1 /* 2 * Copyright © 2009 Keith Packard 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 23 #include <linux/kernel.h> 24 #include <linux/module.h> 25 #include <linux/delay.h> 26 #include <linux/init.h> 27 #include <linux/errno.h> 28 #include <linux/sched.h> 29 #include <linux/i2c.h> 30 #include <linux/export.h> 31 #include <drm/drm_dp_helper.h> 32 #include <drm/drmP.h> 33 34 /** 35 * DOC: dp helpers 36 * 37 * These functions contain some common logic and helpers at various abstraction 38 * levels to deal with Display Port sink devices and related things like DP aux 39 * channel transfers, EDID reading over DP aux channels, decoding certain DPCD 40 * blocks, ... 41 */ 42 43 /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ 44 static int 45 i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, 46 uint8_t write_byte, uint8_t *read_byte) 47 { 48 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; 49 int ret; 50 51 ret = (*algo_data->aux_ch)(adapter, mode, 52 write_byte, read_byte); 53 return ret; 54 } 55 56 /* 57 * I2C over AUX CH 58 */ 59 60 /* 61 * Send the address. If the I2C link is running, this 'restarts' 62 * the connection with the new address, this is used for doing 63 * a write followed by a read (as needed for DDC) 64 */ 65 static int 66 i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) 67 { 68 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; 69 int mode = MODE_I2C_START; 70 int ret; 71 72 if (reading) 73 mode |= MODE_I2C_READ; 74 else 75 mode |= MODE_I2C_WRITE; 76 algo_data->address = address; 77 algo_data->running = true; 78 ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); 79 return ret; 80 } 81 82 /* 83 * Stop the I2C transaction. This closes out the link, sending 84 * a bare address packet with the MOT bit turned off 85 */ 86 static void 87 i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading) 88 { 89 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; 90 int mode = MODE_I2C_STOP; 91 92 if (reading) 93 mode |= MODE_I2C_READ; 94 else 95 mode |= MODE_I2C_WRITE; 96 if (algo_data->running) { 97 (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); 98 algo_data->running = false; 99 } 100 } 101 102 /* 103 * Write a single byte to the current I2C address, the 104 * the I2C link must be running or this returns -EIO 105 */ 106 static int 107 i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte) 108 { 109 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; 110 int ret; 111 112 if (!algo_data->running) 113 return -EIO; 114 115 ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL); 116 return ret; 117 } 118 119 /* 120 * Read a single byte from the current I2C address, the 121 * I2C link must be running or this returns -EIO 122 */ 123 static int 124 i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret) 125 { 126 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; 127 int ret; 128 129 if (!algo_data->running) 130 return -EIO; 131 132 ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret); 133 return ret; 134 } 135 136 static int 137 i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, 138 struct i2c_msg *msgs, 139 int num) 140 { 141 int ret = 0; 142 bool reading = false; 143 int m; 144 int b; 145 146 for (m = 0; m < num; m++) { 147 u16 len = msgs[m].len; 148 u8 *buf = msgs[m].buf; 149 reading = (msgs[m].flags & I2C_M_RD) != 0; 150 ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading); 151 if (ret < 0) 152 break; 153 if (reading) { 154 for (b = 0; b < len; b++) { 155 ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]); 156 if (ret < 0) 157 break; 158 } 159 } else { 160 for (b = 0; b < len; b++) { 161 ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]); 162 if (ret < 0) 163 break; 164 } 165 } 166 if (ret < 0) 167 break; 168 } 169 if (ret >= 0) 170 ret = num; 171 i2c_algo_dp_aux_stop(adapter, reading); 172 DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret); 173 return ret; 174 } 175 176 static u32 177 i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter) 178 { 179 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 180 I2C_FUNC_SMBUS_READ_BLOCK_DATA | 181 I2C_FUNC_SMBUS_BLOCK_PROC_CALL | 182 I2C_FUNC_10BIT_ADDR; 183 } 184 185 static const struct i2c_algorithm i2c_dp_aux_algo = { 186 .master_xfer = i2c_algo_dp_aux_xfer, 187 .functionality = i2c_algo_dp_aux_functionality, 188 }; 189 190 static void 191 i2c_dp_aux_reset_bus(struct i2c_adapter *adapter) 192 { 193 (void) i2c_algo_dp_aux_address(adapter, 0, false); 194 (void) i2c_algo_dp_aux_stop(adapter, false); 195 } 196 197 static int 198 i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) 199 { 200 adapter->algo = &i2c_dp_aux_algo; 201 adapter->retries = 3; 202 i2c_dp_aux_reset_bus(adapter); 203 return 0; 204 } 205 206 /** 207 * i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper 208 * @adapter: i2c adapter to register 209 * 210 * This registers an i2c adapater that uses dp aux channel as it's underlaying 211 * transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure 212 * and store it in the algo_data member of the @adapter argument. This will be 213 * used by the i2c over dp aux algorithm to drive the hardware. 214 * 215 * RETURNS: 216 * 0 on success, -ERRNO on failure. 217 */ 218 int 219 i2c_dp_aux_add_bus(struct i2c_adapter *adapter) 220 { 221 int error; 222 223 error = i2c_dp_aux_prepare_bus(adapter); 224 if (error) 225 return error; 226 error = i2c_add_adapter(adapter); 227 return error; 228 } 229 EXPORT_SYMBOL(i2c_dp_aux_add_bus); 230 231 /* Helpers for DP link training */ 232 static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r) 233 { 234 return link_status[r - DP_LANE0_1_STATUS]; 235 } 236 237 static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], 238 int lane) 239 { 240 int i = DP_LANE0_1_STATUS + (lane >> 1); 241 int s = (lane & 1) * 4; 242 u8 l = dp_link_status(link_status, i); 243 return (l >> s) & 0xf; 244 } 245 246 bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], 247 int lane_count) 248 { 249 u8 lane_align; 250 u8 lane_status; 251 int lane; 252 253 lane_align = dp_link_status(link_status, 254 DP_LANE_ALIGN_STATUS_UPDATED); 255 if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) 256 return false; 257 for (lane = 0; lane < lane_count; lane++) { 258 lane_status = dp_get_lane_status(link_status, lane); 259 if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS) 260 return false; 261 } 262 return true; 263 } 264 EXPORT_SYMBOL(drm_dp_channel_eq_ok); 265 266 bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], 267 int lane_count) 268 { 269 int lane; 270 u8 lane_status; 271 272 for (lane = 0; lane < lane_count; lane++) { 273 lane_status = dp_get_lane_status(link_status, lane); 274 if ((lane_status & DP_LANE_CR_DONE) == 0) 275 return false; 276 } 277 return true; 278 } 279 EXPORT_SYMBOL(drm_dp_clock_recovery_ok); 280 281 u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], 282 int lane) 283 { 284 int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); 285 int s = ((lane & 1) ? 286 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 287 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); 288 u8 l = dp_link_status(link_status, i); 289 290 return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; 291 } 292 EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage); 293 294 u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], 295 int lane) 296 { 297 int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); 298 int s = ((lane & 1) ? 299 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : 300 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); 301 u8 l = dp_link_status(link_status, i); 302 303 return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; 304 } 305 EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis); 306 307 void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { 308 if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) 309 udelay(100); 310 else 311 mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4); 312 } 313 EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay); 314 315 void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { 316 if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) 317 udelay(400); 318 else 319 mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4); 320 } 321 EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay); 322 323 u8 drm_dp_link_rate_to_bw_code(int link_rate) 324 { 325 switch (link_rate) { 326 case 162000: 327 default: 328 return DP_LINK_BW_1_62; 329 case 270000: 330 return DP_LINK_BW_2_7; 331 case 540000: 332 return DP_LINK_BW_5_4; 333 } 334 } 335 EXPORT_SYMBOL(drm_dp_link_rate_to_bw_code); 336 337 int drm_dp_bw_code_to_link_rate(u8 link_bw) 338 { 339 switch (link_bw) { 340 case DP_LINK_BW_1_62: 341 default: 342 return 162000; 343 case DP_LINK_BW_2_7: 344 return 270000; 345 case DP_LINK_BW_5_4: 346 return 540000; 347 } 348 } 349 EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate); 350