linux/include/drm/drm_dp_mst_helper.h
<<
>>
Prefs
   1/*
   2 * Copyright © 2014 Red Hat.
   3 *
   4 * Permission to use, copy, modify, distribute, and sell this software and its
   5 * documentation for any purpose is hereby granted without fee, provided that
   6 * the above copyright notice appear in all copies and that both that copyright
   7 * notice and this permission notice appear in supporting documentation, and
   8 * that the name of the copyright holders not be used in advertising or
   9 * publicity pertaining to distribution of the software without specific,
  10 * written prior permission.  The copyright holders make no representations
  11 * about the suitability of this software for any purpose.  It is provided "as
  12 * is" without express or implied warranty.
  13 *
  14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  20 * OF THIS SOFTWARE.
  21 */
  22#ifndef _DRM_DP_MST_HELPER_H_
  23#define _DRM_DP_MST_HELPER_H_
  24
  25#include <linux/types.h>
  26#include <drm/drm_dp_helper.h>
  27
  28struct drm_dp_mst_branch;
  29
  30/**
  31 * struct drm_dp_vcpi - Virtual Channel Payload Identifier
  32 * @vcpi: Virtual channel ID.
  33 * @pbn: Payload Bandwidth Number for this channel
  34 * @aligned_pbn: PBN aligned with slot size
  35 * @num_slots: number of slots for this PBN
  36 */
  37struct drm_dp_vcpi {
  38        int vcpi;
  39        int pbn;
  40        int aligned_pbn;
  41        int num_slots;
  42};
  43
  44/**
  45 * struct drm_dp_mst_port - MST port
  46 * @kref: reference count for this port.
  47 * @guid_valid: for DP 1.2 devices if we have validated the GUID.
  48 * @guid: guid for DP 1.2 device on this port.
  49 * @port_num: port number
  50 * @input: if this port is an input port.
  51 * @mcs: message capability status - DP 1.2 spec.
  52 * @ddps: DisplayPort Device Plug Status - DP 1.2
  53 * @pdt: Peer Device Type
  54 * @ldps: Legacy Device Plug Status
  55 * @dpcd_rev: DPCD revision of device on this port
  56 * @num_sdp_streams: Number of simultaneous streams
  57 * @num_sdp_stream_sinks: Number of stream sinks
  58 * @available_pbn: Available bandwidth for this port.
  59 * @next: link to next port on this branch device
  60 * @mstb: branch device attach below this port
  61 * @aux: i2c aux transport to talk to device connected to this port.
  62 * @parent: branch device parent of this port
  63 * @vcpi: Virtual Channel Payload info for this port.
  64 * @connector: DRM connector this port is connected to.
  65 * @mgr: topology manager this port lives under.
  66 *
  67 * This structure represents an MST port endpoint on a device somewhere
  68 * in the MST topology.
  69 */
  70struct drm_dp_mst_port {
  71        struct kref kref;
  72
  73        /* if dpcd 1.2 device is on this port - its GUID info */
  74        bool guid_valid;
  75        u8 guid[16];
  76
  77        u8 port_num;
  78        bool input;
  79        bool mcs;
  80        bool ddps;
  81        u8 pdt;
  82        bool ldps;
  83        u8 dpcd_rev;
  84        u8 num_sdp_streams;
  85        u8 num_sdp_stream_sinks;
  86        uint16_t available_pbn;
  87        struct list_head next;
  88        struct drm_dp_mst_branch *mstb; /* pointer to an mstb if this port has one */
  89        struct drm_dp_aux aux; /* i2c bus for this port? */
  90        struct drm_dp_mst_branch *parent;
  91
  92        struct drm_dp_vcpi vcpi;
  93        struct drm_connector *connector;
  94        struct drm_dp_mst_topology_mgr *mgr;
  95
  96        struct edid *cached_edid; /* for DP logical ports - make tiling work */
  97};
  98
  99/**
 100 * struct drm_dp_mst_branch - MST branch device.
 101 * @kref: reference count for this port.
 102 * @rad: Relative Address to talk to this branch device.
 103 * @lct: Link count total to talk to this branch device.
 104 * @num_ports: number of ports on the branch.
 105 * @msg_slots: one bit per transmitted msg slot.
 106 * @ports: linked list of ports on this branch.
 107 * @port_parent: pointer to the port parent, NULL if toplevel.
 108 * @mgr: topology manager for this branch device.
 109 * @tx_slots: transmission slots for this device.
 110 * @last_seqno: last sequence number used to talk to this.
 111 * @link_address_sent: if a link address message has been sent to this device yet.
 112 *
 113 * This structure represents an MST branch device, there is one
 114 * primary branch device at the root, along with any others connected
 115 * to downstream ports
 116 */
 117struct drm_dp_mst_branch {
 118        struct kref kref;
 119        u8 rad[8];
 120        u8 lct;
 121        int num_ports;
 122
 123        int msg_slots;
 124        struct list_head ports;
 125
 126        /* list of tx ops queue for this port */
 127        struct drm_dp_mst_port *port_parent;
 128        struct drm_dp_mst_topology_mgr *mgr;
 129
 130        /* slots are protected by mstb->mgr->qlock */
 131        struct drm_dp_sideband_msg_tx *tx_slots[2];
 132        int last_seqno;
 133        bool link_address_sent;
 134};
 135
 136
 137/* sideband msg header - not bit struct */
 138struct drm_dp_sideband_msg_hdr {
 139        u8 lct;
 140        u8 lcr;
 141        u8 rad[8];
 142        bool broadcast;
 143        bool path_msg;
 144        u8 msg_len;
 145        bool somt;
 146        bool eomt;
 147        bool seqno;
 148};
 149
 150struct drm_dp_nak_reply {
 151        u8 guid[16];
 152        u8 reason;
 153        u8 nak_data;
 154};
 155
 156struct drm_dp_link_address_ack_reply {
 157        u8 guid[16];
 158        u8 nports;
 159        struct drm_dp_link_addr_reply_port {
 160                bool input_port;
 161                u8 peer_device_type;
 162                u8 port_number;
 163                bool mcs;
 164                bool ddps;
 165                bool legacy_device_plug_status;
 166                u8 dpcd_revision;
 167                u8 peer_guid[16];
 168                u8 num_sdp_streams;
 169                u8 num_sdp_stream_sinks;
 170        } ports[16];
 171};
 172
 173struct drm_dp_remote_dpcd_read_ack_reply {
 174        u8 port_number;
 175        u8 num_bytes;
 176        u8 bytes[255];
 177};
 178
 179struct drm_dp_remote_dpcd_write_ack_reply {
 180        u8 port_number;
 181};
 182
 183struct drm_dp_remote_dpcd_write_nak_reply {
 184        u8 port_number;
 185        u8 reason;
 186        u8 bytes_written_before_failure;
 187};
 188
 189struct drm_dp_remote_i2c_read_ack_reply {
 190        u8 port_number;
 191        u8 num_bytes;
 192        u8 bytes[255];
 193};
 194
 195struct drm_dp_remote_i2c_read_nak_reply {
 196        u8 port_number;
 197        u8 nak_reason;
 198        u8 i2c_nak_transaction;
 199};
 200
 201struct drm_dp_remote_i2c_write_ack_reply {
 202        u8 port_number;
 203};
 204
 205
 206struct drm_dp_sideband_msg_rx {
 207        u8 chunk[48];
 208        u8 msg[256];
 209        u8 curchunk_len;
 210        u8 curchunk_idx; /* chunk we are parsing now */
 211        u8 curchunk_hdrlen;
 212        u8 curlen; /* total length of the msg */
 213        bool have_somt;
 214        bool have_eomt;
 215        struct drm_dp_sideband_msg_hdr initial_hdr;
 216};
 217
 218
 219struct drm_dp_allocate_payload {
 220        u8 port_number;
 221        u8 number_sdp_streams;
 222        u8 vcpi;
 223        u16 pbn;
 224        u8 sdp_stream_sink[8];
 225};
 226
 227struct drm_dp_allocate_payload_ack_reply {
 228        u8 port_number;
 229        u8 vcpi;
 230        u16 allocated_pbn;
 231};
 232
 233struct drm_dp_connection_status_notify {
 234        u8 guid[16];
 235        u8 port_number;
 236        bool legacy_device_plug_status;
 237        bool displayport_device_plug_status;
 238        bool message_capability_status;
 239        bool input_port;
 240        u8 peer_device_type;
 241};
 242
 243struct drm_dp_remote_dpcd_read {
 244        u8 port_number;
 245        u32 dpcd_address;
 246        u8 num_bytes;
 247};
 248
 249struct drm_dp_remote_dpcd_write {
 250        u8 port_number;
 251        u32 dpcd_address;
 252        u8 num_bytes;
 253        u8 *bytes;
 254};
 255
 256struct drm_dp_remote_i2c_read {
 257        u8 num_transactions;
 258        u8 port_number;
 259        struct {
 260                u8 i2c_dev_id;
 261                u8 num_bytes;
 262                u8 *bytes;
 263                u8 no_stop_bit;
 264                u8 i2c_transaction_delay;
 265        } transactions[4];
 266        u8 read_i2c_device_id;
 267        u8 num_bytes_read;
 268};
 269
 270struct drm_dp_remote_i2c_write {
 271        u8 port_number;
 272        u8 write_i2c_device_id;
 273        u8 num_bytes;
 274        u8 *bytes;
 275};
 276
 277/* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
 278struct drm_dp_port_number_req {
 279        u8 port_number;
 280};
 281
 282struct drm_dp_enum_path_resources_ack_reply {
 283        u8 port_number;
 284        u16 full_payload_bw_number;
 285        u16 avail_payload_bw_number;
 286};
 287
 288/* covers POWER_DOWN_PHY, POWER_UP_PHY */
 289struct drm_dp_port_number_rep {
 290        u8 port_number;
 291};
 292
 293struct drm_dp_query_payload {
 294        u8 port_number;
 295        u8 vcpi;
 296};
 297
 298struct drm_dp_resource_status_notify {
 299        u8 port_number;
 300        u8 guid[16];
 301        u16 available_pbn;
 302};
 303
 304struct drm_dp_query_payload_ack_reply {
 305        u8 port_number;
 306        u8 allocated_pbn;
 307};
 308
 309struct drm_dp_sideband_msg_req_body {
 310        u8 req_type;
 311        union ack_req {
 312                struct drm_dp_connection_status_notify conn_stat;
 313                struct drm_dp_port_number_req port_num;
 314                struct drm_dp_resource_status_notify resource_stat;
 315
 316                struct drm_dp_query_payload query_payload;
 317                struct drm_dp_allocate_payload allocate_payload;
 318
 319                struct drm_dp_remote_dpcd_read dpcd_read;
 320                struct drm_dp_remote_dpcd_write dpcd_write;
 321
 322                struct drm_dp_remote_i2c_read i2c_read;
 323                struct drm_dp_remote_i2c_write i2c_write;
 324        } u;
 325};
 326
 327struct drm_dp_sideband_msg_reply_body {
 328        u8 reply_type;
 329        u8 req_type;
 330        union ack_replies {
 331                struct drm_dp_nak_reply nak;
 332                struct drm_dp_link_address_ack_reply link_addr;
 333                struct drm_dp_port_number_rep port_number;
 334
 335                struct drm_dp_enum_path_resources_ack_reply path_resources;
 336                struct drm_dp_allocate_payload_ack_reply allocate_payload;
 337                struct drm_dp_query_payload_ack_reply query_payload;
 338
 339                struct drm_dp_remote_dpcd_read_ack_reply remote_dpcd_read_ack;
 340                struct drm_dp_remote_dpcd_write_ack_reply remote_dpcd_write_ack;
 341                struct drm_dp_remote_dpcd_write_nak_reply remote_dpcd_write_nack;
 342
 343                struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
 344                struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
 345                struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
 346        } u;
 347};
 348
 349/* msg is queued to be put into a slot */
 350#define DRM_DP_SIDEBAND_TX_QUEUED 0
 351/* msg has started transmitting on a slot - still on msgq */
 352#define DRM_DP_SIDEBAND_TX_START_SEND 1
 353/* msg has finished transmitting on a slot - removed from msgq only in slot */
 354#define DRM_DP_SIDEBAND_TX_SENT 2
 355/* msg has received a response - removed from slot */
 356#define DRM_DP_SIDEBAND_TX_RX 3
 357#define DRM_DP_SIDEBAND_TX_TIMEOUT 4
 358
 359struct drm_dp_sideband_msg_tx {
 360        u8 msg[256];
 361        u8 chunk[48];
 362        u8 cur_offset;
 363        u8 cur_len;
 364        struct drm_dp_mst_branch *dst;
 365        struct list_head next;
 366        int seqno;
 367        int state;
 368        bool path_msg;
 369        struct drm_dp_sideband_msg_reply_body reply;
 370};
 371
 372/* sideband msg handler */
 373struct drm_dp_mst_topology_mgr;
 374struct drm_dp_mst_topology_cbs {
 375        /* create a connector for a port */
 376        struct drm_connector *(*add_connector)(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *path);
 377        void (*destroy_connector)(struct drm_dp_mst_topology_mgr *mgr,
 378                                  struct drm_connector *connector);
 379        void (*hotplug)(struct drm_dp_mst_topology_mgr *mgr);
 380
 381};
 382
 383#define DP_MAX_PAYLOAD (sizeof(unsigned long) * 8)
 384
 385#define DP_PAYLOAD_LOCAL 1
 386#define DP_PAYLOAD_REMOTE 2
 387#define DP_PAYLOAD_DELETE_LOCAL 3
 388
 389struct drm_dp_payload {
 390        int payload_state;
 391        int start_slot;
 392        int num_slots;
 393        int vcpi;
 394};
 395
 396/**
 397 * struct drm_dp_mst_topology_mgr - DisplayPort MST manager
 398 * @dev: device pointer for adding i2c devices etc.
 399 * @cbs: callbacks for connector addition and destruction.
 400 * @max_dpcd_transaction_bytes - maximum number of bytes to read/write in one go.
 401 * @aux: aux channel for the DP connector.
 402 * @max_payloads: maximum number of payloads the GPU can generate.
 403 * @conn_base_id: DRM connector ID this mgr is connected to.
 404 * @down_rep_recv: msg receiver state for down replies.
 405 * @up_req_recv: msg receiver state for up requests.
 406 * @lock: protects mst state, primary, guid, dpcd.
 407 * @mst_state: if this manager is enabled for an MST capable port.
 408 * @mst_primary: pointer to the primary branch device.
 409 * @guid_valid: GUID valid for the primary branch device.
 410 * @guid: GUID for primary port.
 411 * @dpcd: cache of DPCD for primary port.
 412 * @pbn_div: PBN to slots divisor.
 413 *
 414 * This struct represents the toplevel displayport MST topology manager.
 415 * There should be one instance of this for every MST capable DP connector
 416 * on the GPU.
 417 */
 418struct drm_dp_mst_topology_mgr {
 419
 420        struct device *dev;
 421        struct drm_dp_mst_topology_cbs *cbs;
 422        int max_dpcd_transaction_bytes;
 423        struct drm_dp_aux *aux; /* auxch for this topology mgr to use */
 424        int max_payloads;
 425        int conn_base_id;
 426
 427        /* only ever accessed from the workqueue - which should be serialised */
 428        struct drm_dp_sideband_msg_rx down_rep_recv;
 429        struct drm_dp_sideband_msg_rx up_req_recv;
 430
 431        /* pointer to info about the initial MST device */
 432        struct mutex lock; /* protects mst_state + primary + guid + dpcd */
 433
 434        bool mst_state;
 435        struct drm_dp_mst_branch *mst_primary;
 436        /* primary MST device GUID */
 437        bool guid_valid;
 438        u8 guid[16];
 439        u8 dpcd[DP_RECEIVER_CAP_SIZE];
 440        u8 sink_count;
 441        int pbn_div;
 442        int total_slots;
 443        int avail_slots;
 444        int total_pbn;
 445
 446        /* messages to be transmitted */
 447        /* qlock protects the upq/downq and in_progress,
 448           the mstb tx_slots and txmsg->state once they are queued */
 449        struct mutex qlock;
 450        struct list_head tx_msg_downq;
 451        struct list_head tx_msg_upq;
 452        bool tx_down_in_progress;
 453        bool tx_up_in_progress;
 454
 455        /* payload info + lock for it */
 456        struct mutex payload_lock;
 457        struct drm_dp_vcpi **proposed_vcpis;
 458        struct drm_dp_payload *payloads;
 459        unsigned long payload_mask;
 460        unsigned long vcpi_mask;
 461
 462        wait_queue_head_t tx_waitq;
 463        struct work_struct work;
 464
 465        struct work_struct tx_work;
 466
 467        struct list_head destroy_connector_list;
 468        struct mutex destroy_connector_lock;
 469        struct work_struct destroy_connector_work;
 470};
 471
 472int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, struct device *dev, struct drm_dp_aux *aux, int max_dpcd_transaction_bytes, int max_payloads, int conn_base_id);
 473
 474void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
 475
 476
 477int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state);
 478
 479
 480int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled);
 481
 482
 483enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 484
 485struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 486
 487
 488int drm_dp_calc_pbn_mode(int clock, int bpp);
 489
 490
 491bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int *slots);
 492
 493int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 494
 495
 496void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 497
 498
 499void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 500                                struct drm_dp_mst_port *port);
 501
 502
 503int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 504                           int pbn);
 505
 506
 507int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr);
 508
 509
 510int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr);
 511
 512int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr);
 513
 514void drm_dp_mst_dump_topology(struct seq_file *m,
 515                              struct drm_dp_mst_topology_mgr *mgr);
 516
 517void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
 518int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
 519#endif
 520