Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/bridge: analogix_dp: Remove duplicated code

Remove code for reading the EDID and DPCD fields and use the helpers
instead.

Besides the obvious code reduction, other helpers are being added to the
core that could be used in this driver and will be good to be able to
use them instead of duplicating them.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Tested-by: Javier Martinez Canillas <javier@osg.samsung.com>
Tested-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Yakir Yang <ykk@rock-chips.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Cc: Javier Martinez Canillas <javier@osg.samsung.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Yakir Yang <ykk@rock-chips.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Archit Taneja <architt@codeaurora.org>

authored by

Tomeu Vizoso and committed by
Sean Paul
d2f12adc 604bac48

+210 -555
+80 -194
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
··· 31 31 #include <drm/bridge/analogix_dp.h> 32 32 33 33 #include "analogix_dp_core.h" 34 + #include "analogix_dp_reg.h" 34 35 35 36 #define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) 36 37 ··· 148 147 { 149 148 unsigned char psr_version; 150 149 151 - analogix_dp_read_byte_from_dpcd(dp, DP_PSR_SUPPORT, &psr_version); 150 + drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version); 152 151 dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version); 153 152 154 153 return (psr_version & DP_PSR_IS_SUPPORTED) ? true : false; ··· 159 158 unsigned char psr_en; 160 159 161 160 /* Disable psr function */ 162 - analogix_dp_read_byte_from_dpcd(dp, DP_PSR_EN_CFG, &psr_en); 161 + drm_dp_dpcd_readb(&dp->aux, DP_PSR_EN_CFG, &psr_en); 163 162 psr_en &= ~DP_PSR_ENABLE; 164 - analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); 163 + drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); 165 164 166 165 /* Main-Link transmitter remains active during PSR active states */ 167 166 psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; 168 - analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); 167 + drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); 169 168 170 169 /* Enable psr function */ 171 170 psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | 172 171 DP_PSR_CRC_VERIFICATION; 173 - analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en); 172 + drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); 174 173 175 174 analogix_dp_enable_psr_crc(dp); 176 - } 177 - 178 - static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data) 179 - { 180 - int i; 181 - unsigned char sum = 0; 182 - 183 - for (i = 0; i < EDID_BLOCK_LENGTH; i++) 184 - sum = sum + edid_data[i]; 185 - 186 - return sum; 187 - } 188 - 189 - static int analogix_dp_read_edid(struct analogix_dp_device *dp) 190 - { 191 - unsigned char *edid = dp->edid; 192 - unsigned int extend_block = 0; 193 - unsigned char sum; 194 - unsigned char test_vector; 195 - int retval; 196 - 197 - /* 198 - * EDID device address is 0x50. 199 - * However, if necessary, you must have set upper address 200 - * into E-EDID in I2C device, 0x30. 201 - */ 202 - 203 - /* Read Extension Flag, Number of 128-byte EDID extension blocks */ 204 - retval = analogix_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, 205 - EDID_EXTENSION_FLAG, 206 - &extend_block); 207 - if (retval) 208 - return retval; 209 - 210 - if (extend_block > 0) { 211 - dev_dbg(dp->dev, "EDID data includes a single extension!\n"); 212 - 213 - /* Read EDID data */ 214 - retval = analogix_dp_read_bytes_from_i2c(dp, 215 - I2C_EDID_DEVICE_ADDR, 216 - EDID_HEADER_PATTERN, 217 - EDID_BLOCK_LENGTH, 218 - &edid[EDID_HEADER_PATTERN]); 219 - if (retval != 0) { 220 - dev_err(dp->dev, "EDID Read failed!\n"); 221 - return -EIO; 222 - } 223 - sum = analogix_dp_calc_edid_check_sum(edid); 224 - if (sum != 0) { 225 - dev_err(dp->dev, "EDID bad checksum!\n"); 226 - return -EIO; 227 - } 228 - 229 - /* Read additional EDID data */ 230 - retval = analogix_dp_read_bytes_from_i2c(dp, 231 - I2C_EDID_DEVICE_ADDR, 232 - EDID_BLOCK_LENGTH, 233 - EDID_BLOCK_LENGTH, 234 - &edid[EDID_BLOCK_LENGTH]); 235 - if (retval != 0) { 236 - dev_err(dp->dev, "EDID Read failed!\n"); 237 - return -EIO; 238 - } 239 - sum = analogix_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]); 240 - if (sum != 0) { 241 - dev_err(dp->dev, "EDID bad checksum!\n"); 242 - return -EIO; 243 - } 244 - 245 - analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST, 246 - &test_vector); 247 - if (test_vector & DP_TEST_LINK_EDID_READ) { 248 - analogix_dp_write_byte_to_dpcd(dp, 249 - DP_TEST_EDID_CHECKSUM, 250 - edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]); 251 - analogix_dp_write_byte_to_dpcd(dp, 252 - DP_TEST_RESPONSE, 253 - DP_TEST_EDID_CHECKSUM_WRITE); 254 - } 255 - } else { 256 - dev_info(dp->dev, "EDID data does not include any extensions.\n"); 257 - 258 - /* Read EDID data */ 259 - retval = analogix_dp_read_bytes_from_i2c(dp, 260 - I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN, 261 - EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]); 262 - if (retval != 0) { 263 - dev_err(dp->dev, "EDID Read failed!\n"); 264 - return -EIO; 265 - } 266 - sum = analogix_dp_calc_edid_check_sum(edid); 267 - if (sum != 0) { 268 - dev_err(dp->dev, "EDID bad checksum!\n"); 269 - return -EIO; 270 - } 271 - 272 - analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST, 273 - &test_vector); 274 - if (test_vector & DP_TEST_LINK_EDID_READ) { 275 - analogix_dp_write_byte_to_dpcd(dp, 276 - DP_TEST_EDID_CHECKSUM, edid[EDID_CHECKSUM]); 277 - analogix_dp_write_byte_to_dpcd(dp, 278 - DP_TEST_RESPONSE, DP_TEST_EDID_CHECKSUM_WRITE); 279 - } 280 - } 281 - 282 - dev_dbg(dp->dev, "EDID Read success!\n"); 283 - return 0; 284 - } 285 - 286 - static int analogix_dp_handle_edid(struct analogix_dp_device *dp) 287 - { 288 - u8 buf[12]; 289 - int i; 290 - int retval; 291 - 292 - /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */ 293 - retval = analogix_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf); 294 - if (retval) 295 - return retval; 296 - 297 - /* Read EDID */ 298 - for (i = 0; i < 3; i++) { 299 - retval = analogix_dp_read_edid(dp); 300 - if (!retval) 301 - break; 302 - } 303 - 304 - return retval; 305 175 } 306 176 307 177 static void ··· 181 309 { 182 310 u8 data; 183 311 184 - analogix_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data); 312 + drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data); 185 313 186 314 if (enable) 187 - analogix_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET, 188 - DP_LANE_COUNT_ENHANCED_FRAME_EN | 189 - DPCD_LANE_COUNT_SET(data)); 315 + drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, 316 + DP_LANE_COUNT_ENHANCED_FRAME_EN | 317 + DPCD_LANE_COUNT_SET(data)); 190 318 else 191 - analogix_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET, 192 - DPCD_LANE_COUNT_SET(data)); 319 + drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, 320 + DPCD_LANE_COUNT_SET(data)); 193 321 } 194 322 195 323 static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp) ··· 197 325 u8 data; 198 326 int retval; 199 327 200 - analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data); 328 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data); 201 329 retval = DPCD_ENHANCED_FRAME_CAP(data); 202 330 203 331 return retval; ··· 216 344 { 217 345 analogix_dp_set_training_pattern(dp, DP_NONE); 218 346 219 - analogix_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET, 220 - DP_TRAINING_PATTERN_DISABLE); 347 + drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 348 + DP_TRAINING_PATTERN_DISABLE); 221 349 } 222 350 223 351 static void ··· 262 390 /* Setup RX configuration */ 263 391 buf[0] = dp->link_train.link_rate; 264 392 buf[1] = dp->link_train.lane_count; 265 - retval = analogix_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf); 266 - if (retval) 393 + retval = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, 2); 394 + if (retval < 0) 267 395 return retval; 268 396 269 397 /* Set TX pre-emphasis to minimum */ ··· 287 415 analogix_dp_set_training_pattern(dp, TRAINING_PTN1); 288 416 289 417 /* Set RX training pattern */ 290 - retval = analogix_dp_write_byte_to_dpcd(dp, 291 - DP_TRAINING_PATTERN_SET, 292 - DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1); 293 - if (retval) 418 + retval = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 419 + DP_LINK_SCRAMBLING_DISABLE | 420 + DP_TRAINING_PATTERN_1); 421 + if (retval < 0) 294 422 return retval; 295 423 296 424 for (lane = 0; lane < lane_count; lane++) 297 425 buf[lane] = DP_TRAIN_PRE_EMPH_LEVEL_0 | 298 426 DP_TRAIN_VOLTAGE_SWING_LEVEL_0; 299 427 300 - retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET, 301 - lane_count, buf); 428 + retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, buf, 429 + lane_count); 430 + if (retval < 0) 431 + return retval; 302 432 303 - return retval; 433 + return 0; 304 434 } 305 435 306 436 static unsigned char analogix_dp_get_lane_status(u8 link_status[2], int lane) ··· 454 580 455 581 lane_count = dp->link_train.lane_count; 456 582 457 - retval = analogix_dp_read_bytes_from_dpcd(dp, 458 - DP_LANE0_1_STATUS, 2, link_status); 459 - if (retval) 583 + retval = drm_dp_dpcd_read(&dp->aux, DP_LANE0_1_STATUS, link_status, 2); 584 + if (retval < 0) 460 585 return retval; 461 586 462 - retval = analogix_dp_read_bytes_from_dpcd(dp, 463 - DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request); 464 - if (retval) 587 + retval = drm_dp_dpcd_read(&dp->aux, DP_ADJUST_REQUEST_LANE0_1, 588 + adjust_request, 2); 589 + if (retval < 0) 465 590 return retval; 466 591 467 592 if (analogix_dp_clock_recovery_ok(link_status, lane_count) == 0) { 468 593 /* set training pattern 2 for EQ */ 469 594 analogix_dp_set_training_pattern(dp, TRAINING_PTN2); 470 595 471 - retval = analogix_dp_write_byte_to_dpcd(dp, 472 - DP_TRAINING_PATTERN_SET, 473 - DP_LINK_SCRAMBLING_DISABLE | 474 - DP_TRAINING_PATTERN_2); 475 - if (retval) 596 + retval = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 597 + DP_LINK_SCRAMBLING_DISABLE | 598 + DP_TRAINING_PATTERN_2); 599 + if (retval < 0) 476 600 return retval; 477 601 478 602 dev_info(dp->dev, "Link Training Clock Recovery success\n"); ··· 508 636 analogix_dp_set_lane_link_training(dp, 509 637 dp->link_train.training_lane[lane], lane); 510 638 511 - retval = analogix_dp_write_bytes_to_dpcd(dp, 512 - DP_TRAINING_LANE0_SET, lane_count, 513 - dp->link_train.training_lane); 514 - if (retval) 639 + retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, 640 + dp->link_train.training_lane, lane_count); 641 + if (retval < 0) 515 642 return retval; 516 643 517 - return retval; 644 + return 0; 518 645 } 519 646 520 647 static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) ··· 526 655 527 656 lane_count = dp->link_train.lane_count; 528 657 529 - retval = analogix_dp_read_bytes_from_dpcd(dp, 530 - DP_LANE0_1_STATUS, 2, link_status); 531 - if (retval) 658 + retval = drm_dp_dpcd_read(&dp->aux, DP_LANE0_1_STATUS, link_status, 2); 659 + if (retval < 0) 532 660 return retval; 533 661 534 662 if (analogix_dp_clock_recovery_ok(link_status, lane_count)) { ··· 535 665 return -EIO; 536 666 } 537 667 538 - retval = analogix_dp_read_bytes_from_dpcd(dp, 539 - DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request); 540 - if (retval) 668 + retval = drm_dp_dpcd_read(&dp->aux, DP_ADJUST_REQUEST_LANE0_1, 669 + adjust_request, 2); 670 + if (retval < 0) 541 671 return retval; 542 672 543 - retval = analogix_dp_read_byte_from_dpcd(dp, 544 - DP_LANE_ALIGN_STATUS_UPDATED, &link_align); 545 - if (retval) 673 + retval = drm_dp_dpcd_readb(&dp->aux, DP_LANE_ALIGN_STATUS_UPDATED, 674 + &link_align); 675 + if (retval < 0) 546 676 return retval; 547 677 548 678 analogix_dp_get_adjust_training_lane(dp, adjust_request); ··· 583 713 analogix_dp_set_lane_link_training(dp, 584 714 dp->link_train.training_lane[lane], lane); 585 715 586 - retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET, 587 - lane_count, dp->link_train.training_lane); 716 + retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, 717 + dp->link_train.training_lane, lane_count); 718 + if (retval < 0) 719 + return retval; 588 720 589 - return retval; 721 + return 0; 590 722 } 591 723 592 724 static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp, ··· 602 730 * For DP rev.1.2, Maximum link rate of Main Link lanes 603 731 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps 604 732 */ 605 - analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data); 733 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_LINK_RATE, &data); 606 734 *bandwidth = data; 607 735 } 608 736 ··· 615 743 * For DP rev.1.1, Maximum number of Main Link lanes 616 744 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes 617 745 */ 618 - analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data); 746 + drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data); 619 747 *lane_count = DPCD_MAX_LANE_COUNT(data); 620 748 } 621 749 ··· 784 912 if (enable) { 785 913 analogix_dp_enable_scrambling(dp); 786 914 787 - analogix_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET, 788 - &data); 789 - analogix_dp_write_byte_to_dpcd(dp, 790 - DP_TRAINING_PATTERN_SET, 791 - (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE)); 915 + drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET, &data); 916 + drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 917 + (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE)); 792 918 } else { 793 919 analogix_dp_disable_scrambling(dp); 794 920 795 - analogix_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET, 796 - &data); 797 - analogix_dp_write_byte_to_dpcd(dp, 798 - DP_TRAINING_PATTERN_SET, 799 - (u8)(data | DP_LINK_SCRAMBLING_DISABLE)); 921 + drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET, &data); 922 + drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 923 + (u8)(data | DP_LINK_SCRAMBLING_DISABLE)); 800 924 } 801 925 } 802 926 ··· 921 1053 int analogix_dp_get_modes(struct drm_connector *connector) 922 1054 { 923 1055 struct analogix_dp_device *dp = to_dp(connector); 924 - struct edid *edid = (struct edid *)dp->edid; 1056 + struct edid *edid; 925 1057 int ret, num_modes = 0; 926 1058 927 1059 ret = analogix_dp_prepare_panel(dp, true, false); ··· 930 1062 return 0; 931 1063 } 932 1064 933 - if (analogix_dp_handle_edid(dp) == 0) { 1065 + edid = drm_get_edid(connector, &dp->aux.ddc); 1066 + if (edid) { 934 1067 drm_mode_connector_update_edid_property(&dp->connector, edid); 935 1068 num_modes += drm_add_edid_modes(&dp->connector, edid); 1069 + kfree(edid); 936 1070 } 937 1071 938 1072 if (dp->plat_data->panel) ··· 1265 1395 return 0; 1266 1396 } 1267 1397 1398 + static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux, 1399 + struct drm_dp_aux_msg *msg) 1400 + { 1401 + struct analogix_dp_device *dp = to_dp(aux); 1402 + 1403 + return analogix_dp_transfer(dp, msg); 1404 + } 1405 + 1268 1406 int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, 1269 1407 struct analogix_dp_plat_data *plat_data) 1270 1408 { ··· 1392 1514 1393 1515 dp->drm_dev = drm_dev; 1394 1516 dp->encoder = dp->plat_data->encoder; 1517 + 1518 + dp->aux.name = "DP-AUX"; 1519 + dp->aux.transfer = analogix_dpaux_transfer; 1520 + dp->aux.dev = &pdev->dev; 1521 + 1522 + ret = drm_dp_aux_register(&dp->aux); 1523 + if (ret) 1524 + goto err_disable_pm_runtime; 1395 1525 1396 1526 ret = analogix_dp_create_bridge(drm_dev, dp); 1397 1527 if (ret) {
+3 -37
drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
··· 20 20 #define MAX_CR_LOOP 5 21 21 #define MAX_EQ_LOOP 5 22 22 23 - /* I2C EDID Chip ID, Slave Address */ 24 - #define I2C_EDID_DEVICE_ADDR 0x50 25 - #define I2C_E_EDID_DEVICE_ADDR 0x30 26 - 27 - #define EDID_BLOCK_LENGTH 0x80 28 - #define EDID_HEADER_PATTERN 0x00 29 - #define EDID_EXTENSION_FLAG 0x7e 30 - #define EDID_CHECKSUM 0x7f 31 - 32 23 /* DP_MAX_LANE_COUNT */ 33 24 #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) 34 25 #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) ··· 157 166 struct drm_device *drm_dev; 158 167 struct drm_connector connector; 159 168 struct drm_bridge *bridge; 169 + struct drm_dp_aux aux; 160 170 struct clk *clock; 161 171 unsigned int irq; 162 172 void __iomem *reg_base; ··· 168 176 int dpms_mode; 169 177 int hpd_gpio; 170 178 bool force_hpd; 171 - unsigned char edid[EDID_BLOCK_LENGTH * 2]; 172 179 bool psr_support; 173 180 174 181 struct mutex panel_lock; ··· 201 210 void analogix_dp_init_aux(struct analogix_dp_device *dp); 202 211 int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp); 203 212 void analogix_dp_enable_sw_function(struct analogix_dp_device *dp); 204 - int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp); 205 - int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp, 206 - unsigned int reg_addr, 207 - unsigned char data); 208 - int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp, 209 - unsigned int reg_addr, 210 - unsigned char *data); 211 - int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp, 212 - unsigned int reg_addr, 213 - unsigned int count, 214 - unsigned char data[]); 215 - int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp, 216 - unsigned int reg_addr, 217 - unsigned int count, 218 - unsigned char data[]); 219 - int analogix_dp_select_i2c_device(struct analogix_dp_device *dp, 220 - unsigned int device_addr, 221 - unsigned int reg_addr); 222 - int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp, 223 - unsigned int device_addr, 224 - unsigned int reg_addr, 225 - unsigned int *data); 226 - int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp, 227 - unsigned int device_addr, 228 - unsigned int reg_addr, 229 - unsigned int count, 230 - unsigned char edid[]); 231 213 void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype); 232 214 void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype); 233 215 void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count); ··· 249 285 void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); 250 286 void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, 251 287 struct edp_vsc_psr *vsc); 288 + ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, 289 + struct drm_dp_aux_msg *msg); 252 290 253 291 #endif /* _ANALOGIX_DP_CORE_H */
+127 -324
drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
··· 585 585 return retval; 586 586 } 587 587 588 - int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp, 589 - unsigned int reg_addr, 590 - unsigned char *data) 591 - { 592 - u32 reg; 593 - int i; 594 - int retval; 595 - 596 - for (i = 0; i < 3; i++) { 597 - /* Clear AUX CH data buffer */ 598 - reg = BUF_CLR; 599 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 600 - 601 - /* Select DPCD device address */ 602 - reg = AUX_ADDR_7_0(reg_addr); 603 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 604 - reg = AUX_ADDR_15_8(reg_addr); 605 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 606 - reg = AUX_ADDR_19_16(reg_addr); 607 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 608 - 609 - /* 610 - * Set DisplayPort transaction and read 1 byte 611 - * If bit 3 is 1, DisplayPort transaction. 612 - * If Bit 3 is 0, I2C transaction. 613 - */ 614 - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 615 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 616 - 617 - /* Start AUX transaction */ 618 - retval = analogix_dp_start_aux_transaction(dp); 619 - if (retval == 0) 620 - break; 621 - 622 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 623 - } 624 - 625 - /* Read data buffer */ 626 - reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0); 627 - *data = (unsigned char)(reg & 0xff); 628 - 629 - return retval; 630 - } 631 - 632 - int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp, 633 - unsigned int reg_addr, 634 - unsigned int count, 635 - unsigned char data[]) 636 - { 637 - u32 reg; 638 - unsigned int start_offset; 639 - unsigned int cur_data_count; 640 - unsigned int cur_data_idx; 641 - int i; 642 - int retval = 0; 643 - 644 - /* Clear AUX CH data buffer */ 645 - reg = BUF_CLR; 646 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 647 - 648 - start_offset = 0; 649 - while (start_offset < count) { 650 - /* Buffer size of AUX CH is 16 * 4bytes */ 651 - if ((count - start_offset) > 16) 652 - cur_data_count = 16; 653 - else 654 - cur_data_count = count - start_offset; 655 - 656 - for (i = 0; i < 3; i++) { 657 - /* Select DPCD device address */ 658 - reg = AUX_ADDR_7_0(reg_addr + start_offset); 659 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 660 - reg = AUX_ADDR_15_8(reg_addr + start_offset); 661 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 662 - reg = AUX_ADDR_19_16(reg_addr + start_offset); 663 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 664 - 665 - for (cur_data_idx = 0; cur_data_idx < cur_data_count; 666 - cur_data_idx++) { 667 - reg = data[start_offset + cur_data_idx]; 668 - writel(reg, dp->reg_base + 669 - ANALOGIX_DP_BUF_DATA_0 + 670 - 4 * cur_data_idx); 671 - } 672 - 673 - /* 674 - * Set DisplayPort transaction and write 675 - * If bit 3 is 1, DisplayPort transaction. 676 - * If Bit 3 is 0, I2C transaction. 677 - */ 678 - reg = AUX_LENGTH(cur_data_count) | 679 - AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 680 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 681 - 682 - /* Start AUX transaction */ 683 - retval = analogix_dp_start_aux_transaction(dp); 684 - if (retval == 0) 685 - break; 686 - 687 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 688 - __func__); 689 - } 690 - 691 - start_offset += cur_data_count; 692 - } 693 - 694 - return retval; 695 - } 696 - 697 - int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp, 698 - unsigned int reg_addr, 699 - unsigned int count, 700 - unsigned char data[]) 701 - { 702 - u32 reg; 703 - unsigned int start_offset; 704 - unsigned int cur_data_count; 705 - unsigned int cur_data_idx; 706 - int i; 707 - int retval = 0; 708 - 709 - /* Clear AUX CH data buffer */ 710 - reg = BUF_CLR; 711 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 712 - 713 - start_offset = 0; 714 - while (start_offset < count) { 715 - /* Buffer size of AUX CH is 16 * 4bytes */ 716 - if ((count - start_offset) > 16) 717 - cur_data_count = 16; 718 - else 719 - cur_data_count = count - start_offset; 720 - 721 - /* AUX CH Request Transaction process */ 722 - for (i = 0; i < 3; i++) { 723 - /* Select DPCD device address */ 724 - reg = AUX_ADDR_7_0(reg_addr + start_offset); 725 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 726 - reg = AUX_ADDR_15_8(reg_addr + start_offset); 727 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 728 - reg = AUX_ADDR_19_16(reg_addr + start_offset); 729 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 730 - 731 - /* 732 - * Set DisplayPort transaction and read 733 - * If bit 3 is 1, DisplayPort transaction. 734 - * If Bit 3 is 0, I2C transaction. 735 - */ 736 - reg = AUX_LENGTH(cur_data_count) | 737 - AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 738 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 739 - 740 - /* Start AUX transaction */ 741 - retval = analogix_dp_start_aux_transaction(dp); 742 - if (retval == 0) 743 - break; 744 - 745 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 746 - __func__); 747 - } 748 - 749 - for (cur_data_idx = 0; cur_data_idx < cur_data_count; 750 - cur_data_idx++) { 751 - reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 752 - + 4 * cur_data_idx); 753 - data[start_offset + cur_data_idx] = 754 - (unsigned char)reg; 755 - } 756 - 757 - start_offset += cur_data_count; 758 - } 759 - 760 - return retval; 761 - } 762 - 763 - int analogix_dp_select_i2c_device(struct analogix_dp_device *dp, 764 - unsigned int device_addr, 765 - unsigned int reg_addr) 766 - { 767 - u32 reg; 768 - int retval; 769 - 770 - /* Set EDID device address */ 771 - reg = device_addr; 772 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 773 - writel(0x0, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 774 - writel(0x0, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 775 - 776 - /* Set offset from base address of EDID device */ 777 - writel(reg_addr, dp->reg_base + ANALOGIX_DP_BUF_DATA_0); 778 - 779 - /* 780 - * Set I2C transaction and write address 781 - * If bit 3 is 1, DisplayPort transaction. 782 - * If Bit 3 is 0, I2C transaction. 783 - */ 784 - reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | 785 - AUX_TX_COMM_WRITE; 786 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 787 - 788 - /* Start AUX transaction */ 789 - retval = analogix_dp_start_aux_transaction(dp); 790 - if (retval != 0) 791 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 792 - 793 - return retval; 794 - } 795 - 796 - int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp, 797 - unsigned int device_addr, 798 - unsigned int reg_addr, 799 - unsigned int *data) 800 - { 801 - u32 reg; 802 - int i; 803 - int retval; 804 - 805 - for (i = 0; i < 3; i++) { 806 - /* Clear AUX CH data buffer */ 807 - reg = BUF_CLR; 808 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 809 - 810 - /* Select EDID device */ 811 - retval = analogix_dp_select_i2c_device(dp, device_addr, 812 - reg_addr); 813 - if (retval != 0) 814 - continue; 815 - 816 - /* 817 - * Set I2C transaction and read data 818 - * If bit 3 is 1, DisplayPort transaction. 819 - * If Bit 3 is 0, I2C transaction. 820 - */ 821 - reg = AUX_TX_COMM_I2C_TRANSACTION | 822 - AUX_TX_COMM_READ; 823 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 824 - 825 - /* Start AUX transaction */ 826 - retval = analogix_dp_start_aux_transaction(dp); 827 - if (retval == 0) 828 - break; 829 - 830 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 831 - } 832 - 833 - /* Read data */ 834 - if (retval == 0) 835 - *data = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0); 836 - 837 - return retval; 838 - } 839 - 840 - int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp, 841 - unsigned int device_addr, 842 - unsigned int reg_addr, 843 - unsigned int count, 844 - unsigned char edid[]) 845 - { 846 - u32 reg; 847 - unsigned int i, j; 848 - unsigned int cur_data_idx; 849 - unsigned int defer = 0; 850 - int retval = 0; 851 - 852 - for (i = 0; i < count; i += 16) { 853 - for (j = 0; j < 3; j++) { 854 - /* Clear AUX CH data buffer */ 855 - reg = BUF_CLR; 856 - writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 857 - 858 - /* Set normal AUX CH command */ 859 - reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2); 860 - reg &= ~ADDR_ONLY; 861 - writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2); 862 - 863 - /* 864 - * If Rx sends defer, Tx sends only reads 865 - * request without sending address 866 - */ 867 - if (!defer) 868 - retval = analogix_dp_select_i2c_device(dp, 869 - device_addr, reg_addr + i); 870 - else 871 - defer = 0; 872 - 873 - if (retval == 0) { 874 - /* 875 - * Set I2C transaction and write data 876 - * If bit 3 is 1, DisplayPort transaction. 877 - * If Bit 3 is 0, I2C transaction. 878 - */ 879 - reg = AUX_LENGTH(16) | 880 - AUX_TX_COMM_I2C_TRANSACTION | 881 - AUX_TX_COMM_READ; 882 - writel(reg, dp->reg_base + 883 - ANALOGIX_DP_AUX_CH_CTL_1); 884 - 885 - /* Start AUX transaction */ 886 - retval = analogix_dp_start_aux_transaction(dp); 887 - if (retval == 0) 888 - break; 889 - 890 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 891 - __func__); 892 - } 893 - /* Check if Rx sends defer */ 894 - reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM); 895 - if (reg == AUX_RX_COMM_AUX_DEFER || 896 - reg == AUX_RX_COMM_I2C_DEFER) { 897 - dev_err(dp->dev, "Defer: %d\n\n", reg); 898 - defer = 1; 899 - } 900 - } 901 - 902 - for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { 903 - reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 904 - + 4 * cur_data_idx); 905 - edid[i + cur_data_idx] = (unsigned char)reg; 906 - } 907 - } 908 - 909 - return retval; 910 - } 911 - 912 588 void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype) 913 589 { 914 590 u32 reg; ··· 1036 1360 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 1037 1361 val |= IF_EN; 1038 1362 writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 1363 + } 1364 + 1365 + ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, 1366 + struct drm_dp_aux_msg *msg) 1367 + { 1368 + u32 reg; 1369 + u8 *buffer = msg->buffer; 1370 + int timeout_loop = 0; 1371 + unsigned int i; 1372 + int num_transferred = 0; 1373 + 1374 + /* Buffer size of AUX CH is 16 bytes */ 1375 + if (WARN_ON(msg->size > 16)) 1376 + return -E2BIG; 1377 + 1378 + /* Clear AUX CH data buffer */ 1379 + reg = BUF_CLR; 1380 + writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 1381 + 1382 + switch (msg->request & ~DP_AUX_I2C_MOT) { 1383 + case DP_AUX_I2C_WRITE: 1384 + reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_I2C_TRANSACTION; 1385 + if (msg->request & DP_AUX_I2C_MOT) 1386 + reg |= AUX_TX_COMM_MOT; 1387 + break; 1388 + 1389 + case DP_AUX_I2C_READ: 1390 + reg = AUX_TX_COMM_READ | AUX_TX_COMM_I2C_TRANSACTION; 1391 + if (msg->request & DP_AUX_I2C_MOT) 1392 + reg |= AUX_TX_COMM_MOT; 1393 + break; 1394 + 1395 + case DP_AUX_NATIVE_WRITE: 1396 + reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_DP_TRANSACTION; 1397 + break; 1398 + 1399 + case DP_AUX_NATIVE_READ: 1400 + reg = AUX_TX_COMM_READ | AUX_TX_COMM_DP_TRANSACTION; 1401 + break; 1402 + 1403 + default: 1404 + return -EINVAL; 1405 + } 1406 + 1407 + reg |= AUX_LENGTH(msg->size); 1408 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 1409 + 1410 + /* Select DPCD device address */ 1411 + reg = AUX_ADDR_7_0(msg->address); 1412 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 1413 + reg = AUX_ADDR_15_8(msg->address); 1414 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 1415 + reg = AUX_ADDR_19_16(msg->address); 1416 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 1417 + 1418 + if (!(msg->request & DP_AUX_I2C_READ)) { 1419 + for (i = 0; i < msg->size; i++) { 1420 + reg = buffer[i]; 1421 + writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + 1422 + 4 * i); 1423 + num_transferred++; 1424 + } 1425 + } 1426 + 1427 + /* Enable AUX CH operation */ 1428 + reg = AUX_EN; 1429 + 1430 + /* Zero-sized messages specify address-only transactions. */ 1431 + if (msg->size < 1) 1432 + reg |= ADDR_ONLY; 1433 + 1434 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2); 1435 + 1436 + /* Is AUX CH command reply received? */ 1437 + /* TODO: Wait for an interrupt instead of looping? */ 1438 + reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA); 1439 + while (!(reg & RPLY_RECEIV)) { 1440 + timeout_loop++; 1441 + if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) { 1442 + dev_err(dp->dev, "AUX CH command reply failed!\n"); 1443 + return -ETIMEDOUT; 1444 + } 1445 + reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA); 1446 + usleep_range(10, 11); 1447 + } 1448 + 1449 + /* Clear interrupt source for AUX CH command reply */ 1450 + writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA); 1451 + 1452 + /* Clear interrupt source for AUX CH access error */ 1453 + reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA); 1454 + if (reg & AUX_ERR) { 1455 + writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA); 1456 + return -EREMOTEIO; 1457 + } 1458 + 1459 + /* Check AUX CH error access status */ 1460 + reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA); 1461 + if ((reg & AUX_STATUS_MASK)) { 1462 + dev_err(dp->dev, "AUX CH error happened: %d\n\n", 1463 + reg & AUX_STATUS_MASK); 1464 + return -EREMOTEIO; 1465 + } 1466 + 1467 + if (msg->request & DP_AUX_I2C_READ) { 1468 + for (i = 0; i < msg->size; i++) { 1469 + reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + 1470 + 4 * i); 1471 + buffer[i] = (unsigned char)reg; 1472 + num_transferred++; 1473 + } 1474 + } 1475 + 1476 + /* Check if Rx sends defer */ 1477 + reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM); 1478 + if (reg == AUX_RX_COMM_AUX_DEFER) 1479 + msg->reply = DP_AUX_NATIVE_REPLY_DEFER; 1480 + else if (reg == AUX_RX_COMM_I2C_DEFER) 1481 + msg->reply = DP_AUX_I2C_REPLY_DEFER; 1482 + else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE || 1483 + (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_READ) 1484 + msg->reply = DP_AUX_I2C_REPLY_ACK; 1485 + else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE || 1486 + (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) 1487 + msg->reply = DP_AUX_NATIVE_REPLY_ACK; 1488 + 1489 + return num_transferred; 1039 1490 }