1*6f486c69SFrançois Tigeot /* 2*6f486c69SFrançois Tigeot * Copyright © 2009 Keith Packard 3*6f486c69SFrançois Tigeot * 4*6f486c69SFrançois Tigeot * Permission to use, copy, modify, distribute, and sell this software and its 5*6f486c69SFrançois Tigeot * documentation for any purpose is hereby granted without fee, provided that 6*6f486c69SFrançois Tigeot * the above copyright notice appear in all copies and that both that copyright 7*6f486c69SFrançois Tigeot * notice and this permission notice appear in supporting documentation, and 8*6f486c69SFrançois Tigeot * that the name of the copyright holders not be used in advertising or 9*6f486c69SFrançois Tigeot * publicity pertaining to distribution of the software without specific, 10*6f486c69SFrançois Tigeot * written prior permission. The copyright holders make no representations 11*6f486c69SFrançois Tigeot * about the suitability of this software for any purpose. It is provided "as 12*6f486c69SFrançois Tigeot * is" without express or implied warranty. 13*6f486c69SFrançois Tigeot * 14*6f486c69SFrançois Tigeot * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15*6f486c69SFrançois Tigeot * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16*6f486c69SFrançois Tigeot * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17*6f486c69SFrançois Tigeot * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18*6f486c69SFrançois Tigeot * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19*6f486c69SFrançois Tigeot * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20*6f486c69SFrançois Tigeot * OF THIS SOFTWARE. 21*6f486c69SFrançois Tigeot * 22*6f486c69SFrançois Tigeot * $FreeBSD: head/sys/dev/drm2/drm_dp_helper.c 254817 2013-08-24 23:38:57Z dumbbell $ 23*6f486c69SFrançois Tigeot */ 24*6f486c69SFrançois Tigeot 25*6f486c69SFrançois Tigeot #include <dev/drm/drmP.h> 26*6f486c69SFrançois Tigeot #include <dev/drm/drm_dp_helper.h> 27*6f486c69SFrançois Tigeot 28*6f486c69SFrançois Tigeot /** 29*6f486c69SFrançois Tigeot * DOC: dp helpers 30*6f486c69SFrançois Tigeot * 31*6f486c69SFrançois Tigeot * These functions contain some common logic and helpers at various abstraction 32*6f486c69SFrançois Tigeot * levels to deal with Display Port sink devices and related things like DP aux 33*6f486c69SFrançois Tigeot * channel transfers, EDID reading over DP aux channels, decoding certain DPCD 34*6f486c69SFrançois Tigeot * blocks, ... 35*6f486c69SFrançois Tigeot */ 36*6f486c69SFrançois Tigeot 37*6f486c69SFrançois Tigeot static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r) 38*6f486c69SFrançois Tigeot { 39*6f486c69SFrançois Tigeot return link_status[r - DP_LANE0_1_STATUS]; 40*6f486c69SFrançois Tigeot } 41*6f486c69SFrançois Tigeot 42*6f486c69SFrançois Tigeot static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], 43*6f486c69SFrançois Tigeot int lane) 44*6f486c69SFrançois Tigeot { 45*6f486c69SFrançois Tigeot int i = DP_LANE0_1_STATUS + (lane >> 1); 46*6f486c69SFrançois Tigeot int s = (lane & 1) * 4; 47*6f486c69SFrançois Tigeot u8 l = dp_link_status(link_status, i); 48*6f486c69SFrançois Tigeot return (l >> s) & 0xf; 49*6f486c69SFrançois Tigeot } 50*6f486c69SFrançois Tigeot 51*6f486c69SFrançois Tigeot bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], 52*6f486c69SFrançois Tigeot int lane_count) 53*6f486c69SFrançois Tigeot { 54*6f486c69SFrançois Tigeot u8 lane_align; 55*6f486c69SFrançois Tigeot u8 lane_status; 56*6f486c69SFrançois Tigeot int lane; 57*6f486c69SFrançois Tigeot 58*6f486c69SFrançois Tigeot lane_align = dp_link_status(link_status, 59*6f486c69SFrançois Tigeot DP_LANE_ALIGN_STATUS_UPDATED); 60*6f486c69SFrançois Tigeot if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) 61*6f486c69SFrançois Tigeot return false; 62*6f486c69SFrançois Tigeot for (lane = 0; lane < lane_count; lane++) { 63*6f486c69SFrançois Tigeot lane_status = dp_get_lane_status(link_status, lane); 64*6f486c69SFrançois Tigeot if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS) 65*6f486c69SFrançois Tigeot return false; 66*6f486c69SFrançois Tigeot } 67*6f486c69SFrançois Tigeot return true; 68*6f486c69SFrançois Tigeot } 69*6f486c69SFrançois Tigeot 70*6f486c69SFrançois Tigeot bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], 71*6f486c69SFrançois Tigeot int lane_count) 72*6f486c69SFrançois Tigeot { 73*6f486c69SFrançois Tigeot int lane; 74*6f486c69SFrançois Tigeot u8 lane_status; 75*6f486c69SFrançois Tigeot 76*6f486c69SFrançois Tigeot for (lane = 0; lane < lane_count; lane++) { 77*6f486c69SFrançois Tigeot lane_status = dp_get_lane_status(link_status, lane); 78*6f486c69SFrançois Tigeot if ((lane_status & DP_LANE_CR_DONE) == 0) 79*6f486c69SFrançois Tigeot return false; 80*6f486c69SFrançois Tigeot } 81*6f486c69SFrançois Tigeot return true; 82*6f486c69SFrançois Tigeot } 83*6f486c69SFrançois Tigeot 84*6f486c69SFrançois Tigeot u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], 85*6f486c69SFrançois Tigeot int lane) 86*6f486c69SFrançois Tigeot { 87*6f486c69SFrançois Tigeot int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); 88*6f486c69SFrançois Tigeot int s = ((lane & 1) ? 89*6f486c69SFrançois Tigeot DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 90*6f486c69SFrançois Tigeot DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); 91*6f486c69SFrançois Tigeot u8 l = dp_link_status(link_status, i); 92*6f486c69SFrançois Tigeot 93*6f486c69SFrançois Tigeot return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; 94*6f486c69SFrançois Tigeot } 95*6f486c69SFrançois Tigeot 96*6f486c69SFrançois Tigeot u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], 97*6f486c69SFrançois Tigeot int lane) 98*6f486c69SFrançois Tigeot { 99*6f486c69SFrançois Tigeot int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); 100*6f486c69SFrançois Tigeot int s = ((lane & 1) ? 101*6f486c69SFrançois Tigeot DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : 102*6f486c69SFrançois Tigeot DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); 103*6f486c69SFrançois Tigeot u8 l = dp_link_status(link_status, i); 104*6f486c69SFrançois Tigeot 105*6f486c69SFrançois Tigeot return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; 106*6f486c69SFrançois Tigeot } 107*6f486c69SFrançois Tigeot 108*6f486c69SFrançois Tigeot void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { 109*6f486c69SFrançois Tigeot if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) 110*6f486c69SFrançois Tigeot DRM_UDELAY(100); 111*6f486c69SFrançois Tigeot else 112*6f486c69SFrançois Tigeot DRM_MDELAY(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4); 113*6f486c69SFrançois Tigeot } 114*6f486c69SFrançois Tigeot 115*6f486c69SFrançois Tigeot void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { 116*6f486c69SFrançois Tigeot if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) 117*6f486c69SFrançois Tigeot DRM_UDELAY(400); 118*6f486c69SFrançois Tigeot else 119*6f486c69SFrançois Tigeot DRM_MDELAY(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4); 120*6f486c69SFrançois Tigeot } 121*6f486c69SFrançois Tigeot 122*6f486c69SFrançois Tigeot u8 drm_dp_link_rate_to_bw_code(int link_rate) 123*6f486c69SFrançois Tigeot { 124*6f486c69SFrançois Tigeot switch (link_rate) { 125*6f486c69SFrançois Tigeot case 162000: 126*6f486c69SFrançois Tigeot default: 127*6f486c69SFrançois Tigeot return DP_LINK_BW_1_62; 128*6f486c69SFrançois Tigeot case 270000: 129*6f486c69SFrançois Tigeot return DP_LINK_BW_2_7; 130*6f486c69SFrançois Tigeot case 540000: 131*6f486c69SFrançois Tigeot return DP_LINK_BW_5_4; 132*6f486c69SFrançois Tigeot } 133*6f486c69SFrançois Tigeot } 134*6f486c69SFrançois Tigeot 135*6f486c69SFrançois Tigeot int drm_dp_bw_code_to_link_rate(u8 link_bw) 136*6f486c69SFrançois Tigeot { 137*6f486c69SFrançois Tigeot switch (link_bw) { 138*6f486c69SFrançois Tigeot case DP_LINK_BW_1_62: 139*6f486c69SFrançois Tigeot default: 140*6f486c69SFrançois Tigeot return 162000; 141*6f486c69SFrançois Tigeot case DP_LINK_BW_2_7: 142*6f486c69SFrançois Tigeot return 270000; 143*6f486c69SFrançois Tigeot case DP_LINK_BW_5_4: 144*6f486c69SFrançois Tigeot return 540000; 145*6f486c69SFrançois Tigeot } 146*6f486c69SFrançois Tigeot } 147