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

Configure Feed

Select the types of activity you want to include in your feed.

at v3.14-rc2 1243 lines 32 kB view raw
1/* 2 * Samsung DP (Display port) register interface driver. 3 * 4 * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 * Author: Jingoo Han <jg1.han@samsung.com> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 */ 12 13#include <linux/device.h> 14#include <linux/io.h> 15#include <linux/delay.h> 16 17#include "exynos_dp_core.h" 18#include "exynos_dp_reg.h" 19 20#define COMMON_INT_MASK_1 0 21#define COMMON_INT_MASK_2 0 22#define COMMON_INT_MASK_3 0 23#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG) 24#define INT_STA_MASK INT_HPD 25 26void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable) 27{ 28 u32 reg; 29 30 if (enable) { 31 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 32 reg |= HDCP_VIDEO_MUTE; 33 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 34 } else { 35 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 36 reg &= ~HDCP_VIDEO_MUTE; 37 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 38 } 39} 40 41void exynos_dp_stop_video(struct exynos_dp_device *dp) 42{ 43 u32 reg; 44 45 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 46 reg &= ~VIDEO_EN; 47 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 48} 49 50void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable) 51{ 52 u32 reg; 53 54 if (enable) 55 reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | 56 LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; 57 else 58 reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | 59 LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; 60 61 writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP); 62} 63 64void exynos_dp_init_analog_param(struct exynos_dp_device *dp) 65{ 66 u32 reg; 67 68 reg = TX_TERMINAL_CTRL_50_OHM; 69 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1); 70 71 reg = SEL_24M | TX_DVDD_BIT_1_0625V; 72 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2); 73 74 reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO; 75 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3); 76 77 reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | 78 TX_CUR1_2X | TX_CUR_16_MA; 79 writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1); 80 81 reg = CH3_AMP_400_MV | CH2_AMP_400_MV | 82 CH1_AMP_400_MV | CH0_AMP_400_MV; 83 writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL); 84} 85 86void exynos_dp_init_interrupt(struct exynos_dp_device *dp) 87{ 88 /* Set interrupt pin assertion polarity as high */ 89 writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL); 90 91 /* Clear pending regisers */ 92 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 93 writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2); 94 writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3); 95 writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 96 writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA); 97 98 /* 0:mask,1: unmask */ 99 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); 100 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); 101 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); 102 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); 103 writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK); 104} 105 106void exynos_dp_reset(struct exynos_dp_device *dp) 107{ 108 u32 reg; 109 110 exynos_dp_stop_video(dp); 111 exynos_dp_enable_video_mute(dp, 0); 112 113 reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | 114 AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | 115 HDCP_FUNC_EN_N | SW_FUNC_EN_N; 116 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 117 118 reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N | 119 SERDES_FIFO_FUNC_EN_N | 120 LS_CLK_DOMAIN_FUNC_EN_N; 121 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 122 123 usleep_range(20, 30); 124 125 exynos_dp_lane_swap(dp, 0); 126 127 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 128 writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 129 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 130 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 131 132 writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL); 133 writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL); 134 135 writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L); 136 writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H); 137 138 writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL); 139 140 writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST); 141 142 writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD); 143 writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN); 144 145 writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH); 146 writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH); 147 148 writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 149} 150 151void exynos_dp_swreset(struct exynos_dp_device *dp) 152{ 153 writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET); 154} 155 156void exynos_dp_config_interrupt(struct exynos_dp_device *dp) 157{ 158 u32 reg; 159 160 /* 0: mask, 1: unmask */ 161 reg = COMMON_INT_MASK_1; 162 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); 163 164 reg = COMMON_INT_MASK_2; 165 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); 166 167 reg = COMMON_INT_MASK_3; 168 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); 169 170 reg = COMMON_INT_MASK_4; 171 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); 172 173 reg = INT_STA_MASK; 174 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK); 175} 176 177enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp) 178{ 179 u32 reg; 180 181 reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); 182 if (reg & PLL_LOCK) 183 return PLL_LOCKED; 184 else 185 return PLL_UNLOCKED; 186} 187 188void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable) 189{ 190 u32 reg; 191 192 if (enable) { 193 reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); 194 reg |= DP_PLL_PD; 195 writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); 196 } else { 197 reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); 198 reg &= ~DP_PLL_PD; 199 writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); 200 } 201} 202 203void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, 204 enum analog_power_block block, 205 bool enable) 206{ 207 u32 reg; 208 209 switch (block) { 210 case AUX_BLOCK: 211 if (enable) { 212 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 213 reg |= AUX_PD; 214 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 215 } else { 216 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 217 reg &= ~AUX_PD; 218 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 219 } 220 break; 221 case CH0_BLOCK: 222 if (enable) { 223 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 224 reg |= CH0_PD; 225 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 226 } else { 227 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 228 reg &= ~CH0_PD; 229 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 230 } 231 break; 232 case CH1_BLOCK: 233 if (enable) { 234 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 235 reg |= CH1_PD; 236 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 237 } else { 238 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 239 reg &= ~CH1_PD; 240 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 241 } 242 break; 243 case CH2_BLOCK: 244 if (enable) { 245 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 246 reg |= CH2_PD; 247 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 248 } else { 249 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 250 reg &= ~CH2_PD; 251 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 252 } 253 break; 254 case CH3_BLOCK: 255 if (enable) { 256 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 257 reg |= CH3_PD; 258 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 259 } else { 260 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 261 reg &= ~CH3_PD; 262 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 263 } 264 break; 265 case ANALOG_TOTAL: 266 if (enable) { 267 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 268 reg |= DP_PHY_PD; 269 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 270 } else { 271 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 272 reg &= ~DP_PHY_PD; 273 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 274 } 275 break; 276 case POWER_ALL: 277 if (enable) { 278 reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD | 279 CH1_PD | CH0_PD; 280 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 281 } else { 282 writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD); 283 } 284 break; 285 default: 286 break; 287 } 288} 289 290void exynos_dp_init_analog_func(struct exynos_dp_device *dp) 291{ 292 u32 reg; 293 int timeout_loop = 0; 294 295 exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); 296 297 reg = PLL_LOCK_CHG; 298 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 299 300 reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); 301 reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); 302 writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL); 303 304 /* Power up PLL */ 305 if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 306 exynos_dp_set_pll_power_down(dp, 0); 307 308 while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 309 timeout_loop++; 310 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 311 dev_err(dp->dev, "failed to get pll lock status\n"); 312 return; 313 } 314 usleep_range(10, 20); 315 } 316 } 317 318 /* Enable Serdes FIFO function and Link symbol clock domain module */ 319 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 320 reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N 321 | AUX_FUNC_EN_N); 322 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 323} 324 325void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp) 326{ 327 u32 reg; 328 329 reg = HOTPLUG_CHG | HPD_LOST | PLUG; 330 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 331 332 reg = INT_HPD; 333 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 334} 335 336void exynos_dp_init_hpd(struct exynos_dp_device *dp) 337{ 338 u32 reg; 339 340 exynos_dp_clear_hotplug_interrupts(dp); 341 342 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 343 reg &= ~(F_HPD | HPD_CTRL); 344 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 345} 346 347enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp) 348{ 349 u32 reg; 350 351 /* Parse hotplug interrupt status register */ 352 reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 353 354 if (reg & PLUG) 355 return DP_IRQ_TYPE_HP_CABLE_IN; 356 357 if (reg & HPD_LOST) 358 return DP_IRQ_TYPE_HP_CABLE_OUT; 359 360 if (reg & HOTPLUG_CHG) 361 return DP_IRQ_TYPE_HP_CHANGE; 362 363 return DP_IRQ_TYPE_UNKNOWN; 364} 365 366void exynos_dp_reset_aux(struct exynos_dp_device *dp) 367{ 368 u32 reg; 369 370 /* Disable AUX channel module */ 371 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 372 reg |= AUX_FUNC_EN_N; 373 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 374} 375 376void exynos_dp_init_aux(struct exynos_dp_device *dp) 377{ 378 u32 reg; 379 380 /* Clear inerrupts related to AUX channel */ 381 reg = RPLY_RECEIV | AUX_ERR; 382 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 383 384 exynos_dp_reset_aux(dp); 385 386 /* Disable AUX transaction H/W retry */ 387 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)| 388 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; 389 writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ; 390 391 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ 392 reg = DEFER_CTRL_EN | DEFER_COUNT(1); 393 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL); 394 395 /* Enable AUX channel module */ 396 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 397 reg &= ~AUX_FUNC_EN_N; 398 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 399} 400 401int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp) 402{ 403 u32 reg; 404 405 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 406 if (reg & HPD_STATUS) 407 return 0; 408 409 return -EINVAL; 410} 411 412void exynos_dp_enable_sw_function(struct exynos_dp_device *dp) 413{ 414 u32 reg; 415 416 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); 417 reg &= ~SW_FUNC_EN_N; 418 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 419} 420 421int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp) 422{ 423 int reg; 424 int retval = 0; 425 int timeout_loop = 0; 426 427 /* Enable AUX CH operation */ 428 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 429 reg |= AUX_EN; 430 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 431 432 /* Is AUX CH command reply received? */ 433 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 434 while (!(reg & RPLY_RECEIV)) { 435 timeout_loop++; 436 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 437 dev_err(dp->dev, "AUX CH command reply failed!\n"); 438 return -ETIMEDOUT; 439 } 440 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 441 usleep_range(10, 11); 442 } 443 444 /* Clear interrupt source for AUX CH command reply */ 445 writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA); 446 447 /* Clear interrupt source for AUX CH access error */ 448 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 449 if (reg & AUX_ERR) { 450 writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA); 451 return -EREMOTEIO; 452 } 453 454 /* Check AUX CH error access status */ 455 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA); 456 if ((reg & AUX_STATUS_MASK) != 0) { 457 dev_err(dp->dev, "AUX CH error happens: %d\n\n", 458 reg & AUX_STATUS_MASK); 459 return -EREMOTEIO; 460 } 461 462 return retval; 463} 464 465int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, 466 unsigned int reg_addr, 467 unsigned char data) 468{ 469 u32 reg; 470 int i; 471 int retval; 472 473 for (i = 0; i < 3; i++) { 474 /* Clear AUX CH data buffer */ 475 reg = BUF_CLR; 476 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 477 478 /* Select DPCD device address */ 479 reg = AUX_ADDR_7_0(reg_addr); 480 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 481 reg = AUX_ADDR_15_8(reg_addr); 482 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 483 reg = AUX_ADDR_19_16(reg_addr); 484 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 485 486 /* Write data buffer */ 487 reg = (unsigned int)data; 488 writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0); 489 490 /* 491 * Set DisplayPort transaction and write 1 byte 492 * If bit 3 is 1, DisplayPort transaction. 493 * If Bit 3 is 0, I2C transaction. 494 */ 495 reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 496 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 497 498 /* Start AUX transaction */ 499 retval = exynos_dp_start_aux_transaction(dp); 500 if (retval == 0) 501 break; 502 else 503 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 504 __func__); 505 } 506 507 return retval; 508} 509 510int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, 511 unsigned int reg_addr, 512 unsigned char *data) 513{ 514 u32 reg; 515 int i; 516 int retval; 517 518 for (i = 0; i < 3; i++) { 519 /* Clear AUX CH data buffer */ 520 reg = BUF_CLR; 521 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 522 523 /* Select DPCD device address */ 524 reg = AUX_ADDR_7_0(reg_addr); 525 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 526 reg = AUX_ADDR_15_8(reg_addr); 527 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 528 reg = AUX_ADDR_19_16(reg_addr); 529 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 530 531 /* 532 * Set DisplayPort transaction and read 1 byte 533 * If bit 3 is 1, DisplayPort transaction. 534 * If Bit 3 is 0, I2C transaction. 535 */ 536 reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 537 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 538 539 /* Start AUX transaction */ 540 retval = exynos_dp_start_aux_transaction(dp); 541 if (retval == 0) 542 break; 543 else 544 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 545 __func__); 546 } 547 548 /* Read data buffer */ 549 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); 550 *data = (unsigned char)(reg & 0xff); 551 552 return retval; 553} 554 555int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, 556 unsigned int reg_addr, 557 unsigned int count, 558 unsigned char data[]) 559{ 560 u32 reg; 561 unsigned int start_offset; 562 unsigned int cur_data_count; 563 unsigned int cur_data_idx; 564 int i; 565 int retval = 0; 566 567 /* Clear AUX CH data buffer */ 568 reg = BUF_CLR; 569 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 570 571 start_offset = 0; 572 while (start_offset < count) { 573 /* Buffer size of AUX CH is 16 * 4bytes */ 574 if ((count - start_offset) > 16) 575 cur_data_count = 16; 576 else 577 cur_data_count = count - start_offset; 578 579 for (i = 0; i < 3; i++) { 580 /* Select DPCD device address */ 581 reg = AUX_ADDR_7_0(reg_addr + start_offset); 582 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 583 reg = AUX_ADDR_15_8(reg_addr + start_offset); 584 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 585 reg = AUX_ADDR_19_16(reg_addr + start_offset); 586 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 587 588 for (cur_data_idx = 0; cur_data_idx < cur_data_count; 589 cur_data_idx++) { 590 reg = data[start_offset + cur_data_idx]; 591 writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0 592 + 4 * cur_data_idx); 593 } 594 595 /* 596 * Set DisplayPort transaction and write 597 * If bit 3 is 1, DisplayPort transaction. 598 * If Bit 3 is 0, I2C transaction. 599 */ 600 reg = AUX_LENGTH(cur_data_count) | 601 AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 602 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 603 604 /* Start AUX transaction */ 605 retval = exynos_dp_start_aux_transaction(dp); 606 if (retval == 0) 607 break; 608 else 609 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 610 __func__); 611 } 612 613 start_offset += cur_data_count; 614 } 615 616 return retval; 617} 618 619int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, 620 unsigned int reg_addr, 621 unsigned int count, 622 unsigned char data[]) 623{ 624 u32 reg; 625 unsigned int start_offset; 626 unsigned int cur_data_count; 627 unsigned int cur_data_idx; 628 int i; 629 int retval = 0; 630 631 /* Clear AUX CH data buffer */ 632 reg = BUF_CLR; 633 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 634 635 start_offset = 0; 636 while (start_offset < count) { 637 /* Buffer size of AUX CH is 16 * 4bytes */ 638 if ((count - start_offset) > 16) 639 cur_data_count = 16; 640 else 641 cur_data_count = count - start_offset; 642 643 /* AUX CH Request Transaction process */ 644 for (i = 0; i < 3; i++) { 645 /* Select DPCD device address */ 646 reg = AUX_ADDR_7_0(reg_addr + start_offset); 647 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 648 reg = AUX_ADDR_15_8(reg_addr + start_offset); 649 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 650 reg = AUX_ADDR_19_16(reg_addr + start_offset); 651 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 652 653 /* 654 * Set DisplayPort transaction and read 655 * If bit 3 is 1, DisplayPort transaction. 656 * If Bit 3 is 0, I2C transaction. 657 */ 658 reg = AUX_LENGTH(cur_data_count) | 659 AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 660 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 661 662 /* Start AUX transaction */ 663 retval = exynos_dp_start_aux_transaction(dp); 664 if (retval == 0) 665 break; 666 else 667 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 668 __func__); 669 } 670 671 for (cur_data_idx = 0; cur_data_idx < cur_data_count; 672 cur_data_idx++) { 673 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 674 + 4 * cur_data_idx); 675 data[start_offset + cur_data_idx] = 676 (unsigned char)reg; 677 } 678 679 start_offset += cur_data_count; 680 } 681 682 return retval; 683} 684 685int exynos_dp_select_i2c_device(struct exynos_dp_device *dp, 686 unsigned int device_addr, 687 unsigned int reg_addr) 688{ 689 u32 reg; 690 int retval; 691 692 /* Set EDID device address */ 693 reg = device_addr; 694 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 695 writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 696 writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 697 698 /* Set offset from base address of EDID device */ 699 writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0); 700 701 /* 702 * Set I2C transaction and write address 703 * If bit 3 is 1, DisplayPort transaction. 704 * If Bit 3 is 0, I2C transaction. 705 */ 706 reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | 707 AUX_TX_COMM_WRITE; 708 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 709 710 /* Start AUX transaction */ 711 retval = exynos_dp_start_aux_transaction(dp); 712 if (retval != 0) 713 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 714 715 return retval; 716} 717 718int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, 719 unsigned int device_addr, 720 unsigned int reg_addr, 721 unsigned int *data) 722{ 723 u32 reg; 724 int i; 725 int retval; 726 727 for (i = 0; i < 3; i++) { 728 /* Clear AUX CH data buffer */ 729 reg = BUF_CLR; 730 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 731 732 /* Select EDID device */ 733 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); 734 if (retval != 0) 735 continue; 736 737 /* 738 * Set I2C transaction and read data 739 * If bit 3 is 1, DisplayPort transaction. 740 * If Bit 3 is 0, I2C transaction. 741 */ 742 reg = AUX_TX_COMM_I2C_TRANSACTION | 743 AUX_TX_COMM_READ; 744 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 745 746 /* Start AUX transaction */ 747 retval = exynos_dp_start_aux_transaction(dp); 748 if (retval == 0) 749 break; 750 else 751 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 752 __func__); 753 } 754 755 /* Read data */ 756 if (retval == 0) 757 *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); 758 759 return retval; 760} 761 762int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, 763 unsigned int device_addr, 764 unsigned int reg_addr, 765 unsigned int count, 766 unsigned char edid[]) 767{ 768 u32 reg; 769 unsigned int i, j; 770 unsigned int cur_data_idx; 771 unsigned int defer = 0; 772 int retval = 0; 773 774 for (i = 0; i < count; i += 16) { 775 for (j = 0; j < 3; j++) { 776 /* Clear AUX CH data buffer */ 777 reg = BUF_CLR; 778 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 779 780 /* Set normal AUX CH command */ 781 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 782 reg &= ~ADDR_ONLY; 783 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 784 785 /* 786 * If Rx sends defer, Tx sends only reads 787 * request without sending address 788 */ 789 if (!defer) 790 retval = exynos_dp_select_i2c_device(dp, 791 device_addr, reg_addr + i); 792 else 793 defer = 0; 794 795 if (retval == 0) { 796 /* 797 * Set I2C transaction and write data 798 * If bit 3 is 1, DisplayPort transaction. 799 * If Bit 3 is 0, I2C transaction. 800 */ 801 reg = AUX_LENGTH(16) | 802 AUX_TX_COMM_I2C_TRANSACTION | 803 AUX_TX_COMM_READ; 804 writel(reg, dp->reg_base + 805 EXYNOS_DP_AUX_CH_CTL_1); 806 807 /* Start AUX transaction */ 808 retval = exynos_dp_start_aux_transaction(dp); 809 if (retval == 0) 810 break; 811 else 812 dev_dbg(dp->dev, 813 "%s: Aux Transaction fail!\n", 814 __func__); 815 } 816 /* Check if Rx sends defer */ 817 reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM); 818 if (reg == AUX_RX_COMM_AUX_DEFER || 819 reg == AUX_RX_COMM_I2C_DEFER) { 820 dev_err(dp->dev, "Defer: %d\n\n", reg); 821 defer = 1; 822 } 823 } 824 825 for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { 826 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 827 + 4 * cur_data_idx); 828 edid[i + cur_data_idx] = (unsigned char)reg; 829 } 830 } 831 832 return retval; 833} 834 835void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype) 836{ 837 u32 reg; 838 839 reg = bwtype; 840 if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS)) 841 writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET); 842} 843 844void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype) 845{ 846 u32 reg; 847 848 reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET); 849 *bwtype = reg; 850} 851 852void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count) 853{ 854 u32 reg; 855 856 reg = count; 857 writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); 858} 859 860void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count) 861{ 862 u32 reg; 863 864 reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); 865 *count = reg; 866} 867 868void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable) 869{ 870 u32 reg; 871 872 if (enable) { 873 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 874 reg |= ENHANCED; 875 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 876 } else { 877 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 878 reg &= ~ENHANCED; 879 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 880 } 881} 882 883void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, 884 enum pattern_set pattern) 885{ 886 u32 reg; 887 888 switch (pattern) { 889 case PRBS7: 890 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7; 891 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 892 break; 893 case D10_2: 894 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2; 895 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 896 break; 897 case TRAINING_PTN1: 898 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1; 899 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 900 break; 901 case TRAINING_PTN2: 902 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2; 903 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 904 break; 905 case DP_NONE: 906 reg = SCRAMBLING_ENABLE | 907 LINK_QUAL_PATTERN_SET_DISABLE | 908 SW_TRAINING_PATTERN_SET_NORMAL; 909 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 910 break; 911 default: 912 break; 913 } 914} 915 916void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level) 917{ 918 u32 reg; 919 920 reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 921 reg &= ~PRE_EMPHASIS_SET_MASK; 922 reg |= level << PRE_EMPHASIS_SET_SHIFT; 923 writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 924} 925 926void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level) 927{ 928 u32 reg; 929 930 reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 931 reg &= ~PRE_EMPHASIS_SET_MASK; 932 reg |= level << PRE_EMPHASIS_SET_SHIFT; 933 writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 934} 935 936void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level) 937{ 938 u32 reg; 939 940 reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 941 reg &= ~PRE_EMPHASIS_SET_MASK; 942 reg |= level << PRE_EMPHASIS_SET_SHIFT; 943 writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 944} 945 946void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level) 947{ 948 u32 reg; 949 950 reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 951 reg &= ~PRE_EMPHASIS_SET_MASK; 952 reg |= level << PRE_EMPHASIS_SET_SHIFT; 953 writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 954} 955 956void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp, 957 u32 training_lane) 958{ 959 u32 reg; 960 961 reg = training_lane; 962 writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 963} 964 965void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp, 966 u32 training_lane) 967{ 968 u32 reg; 969 970 reg = training_lane; 971 writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 972} 973 974void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp, 975 u32 training_lane) 976{ 977 u32 reg; 978 979 reg = training_lane; 980 writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 981} 982 983void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp, 984 u32 training_lane) 985{ 986 u32 reg; 987 988 reg = training_lane; 989 writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 990} 991 992u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp) 993{ 994 u32 reg; 995 996 reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 997 return reg; 998} 999 1000u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp) 1001{ 1002 u32 reg; 1003 1004 reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 1005 return reg; 1006} 1007 1008u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp) 1009{ 1010 u32 reg; 1011 1012 reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 1013 return reg; 1014} 1015 1016u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp) 1017{ 1018 u32 reg; 1019 1020 reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 1021 return reg; 1022} 1023 1024void exynos_dp_reset_macro(struct exynos_dp_device *dp) 1025{ 1026 u32 reg; 1027 1028 reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST); 1029 reg |= MACRO_RST; 1030 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); 1031 1032 /* 10 us is the minimum reset time. */ 1033 usleep_range(10, 20); 1034 1035 reg &= ~MACRO_RST; 1036 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); 1037} 1038 1039void exynos_dp_init_video(struct exynos_dp_device *dp) 1040{ 1041 u32 reg; 1042 1043 reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG; 1044 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 1045 1046 reg = 0x0; 1047 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1048 1049 reg = CHA_CRI(4) | CHA_CTRL; 1050 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1051 1052 reg = 0x0; 1053 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1054 1055 reg = VID_HRES_TH(2) | VID_VRES_TH(0); 1056 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); 1057} 1058 1059void exynos_dp_set_video_color_format(struct exynos_dp_device *dp) 1060{ 1061 u32 reg; 1062 1063 /* Configure the input color depth, color space, dynamic range */ 1064 reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) | 1065 (dp->video_info->color_depth << IN_BPC_SHIFT) | 1066 (dp->video_info->color_space << IN_COLOR_F_SHIFT); 1067 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); 1068 1069 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ 1070 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1071 reg &= ~IN_YC_COEFFI_MASK; 1072 if (dp->video_info->ycbcr_coeff) 1073 reg |= IN_YC_COEFFI_ITU709; 1074 else 1075 reg |= IN_YC_COEFFI_ITU601; 1076 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1077} 1078 1079int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp) 1080{ 1081 u32 reg; 1082 1083 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1084 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1085 1086 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1087 1088 if (!(reg & DET_STA)) { 1089 dev_dbg(dp->dev, "Input stream clock not detected.\n"); 1090 return -EINVAL; 1091 } 1092 1093 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1094 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1095 1096 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1097 dev_dbg(dp->dev, "wait SYS_CTL_2.\n"); 1098 1099 if (reg & CHA_STA) { 1100 dev_dbg(dp->dev, "Input stream clk is changing\n"); 1101 return -EINVAL; 1102 } 1103 1104 return 0; 1105} 1106 1107void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, 1108 enum clock_recovery_m_value_type type, 1109 u32 m_value, 1110 u32 n_value) 1111{ 1112 u32 reg; 1113 1114 if (type == REGISTER_M) { 1115 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1116 reg |= FIX_M_VID; 1117 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1118 reg = m_value & 0xff; 1119 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0); 1120 reg = (m_value >> 8) & 0xff; 1121 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1); 1122 reg = (m_value >> 16) & 0xff; 1123 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2); 1124 1125 reg = n_value & 0xff; 1126 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0); 1127 reg = (n_value >> 8) & 0xff; 1128 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1); 1129 reg = (n_value >> 16) & 0xff; 1130 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2); 1131 } else { 1132 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1133 reg &= ~FIX_M_VID; 1134 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1135 1136 writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0); 1137 writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1); 1138 writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2); 1139 } 1140} 1141 1142void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type) 1143{ 1144 u32 reg; 1145 1146 if (type == VIDEO_TIMING_FROM_CAPTURE) { 1147 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1148 reg &= ~FORMAT_SEL; 1149 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1150 } else { 1151 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1152 reg |= FORMAT_SEL; 1153 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1154 } 1155} 1156 1157void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable) 1158{ 1159 u32 reg; 1160 1161 if (enable) { 1162 reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1163 reg &= ~VIDEO_MODE_MASK; 1164 reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE; 1165 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1166 } else { 1167 reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1168 reg &= ~VIDEO_MODE_MASK; 1169 reg |= VIDEO_MODE_SLAVE_MODE; 1170 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1171 } 1172} 1173 1174void exynos_dp_start_video(struct exynos_dp_device *dp) 1175{ 1176 u32 reg; 1177 1178 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 1179 reg |= VIDEO_EN; 1180 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 1181} 1182 1183int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp) 1184{ 1185 u32 reg; 1186 1187 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1188 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1189 1190 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1191 if (!(reg & STRM_VALID)) { 1192 dev_dbg(dp->dev, "Input video stream is not detected.\n"); 1193 return -EINVAL; 1194 } 1195 1196 return 0; 1197} 1198 1199void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp) 1200{ 1201 u32 reg; 1202 1203 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); 1204 reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N); 1205 reg |= MASTER_VID_FUNC_EN_N; 1206 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 1207 1208 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1209 reg &= ~INTERACE_SCAN_CFG; 1210 reg |= (dp->video_info->interlaced << 2); 1211 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1212 1213 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1214 reg &= ~VSYNC_POLARITY_CFG; 1215 reg |= (dp->video_info->v_sync_polarity << 1); 1216 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1217 1218 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1219 reg &= ~HSYNC_POLARITY_CFG; 1220 reg |= (dp->video_info->h_sync_polarity << 0); 1221 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1222 1223 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; 1224 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1225} 1226 1227void exynos_dp_enable_scrambling(struct exynos_dp_device *dp) 1228{ 1229 u32 reg; 1230 1231 reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1232 reg &= ~SCRAMBLING_DISABLE; 1233 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1234} 1235 1236void exynos_dp_disable_scrambling(struct exynos_dp_device *dp) 1237{ 1238 u32 reg; 1239 1240 reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1241 reg |= SCRAMBLING_DISABLE; 1242 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1243}