aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/exynos/exynos_dp_reg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/exynos/exynos_dp_reg.c')
-rw-r--r--drivers/video/exynos/exynos_dp_reg.c77
1 files changed, 48 insertions, 29 deletions
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3f5ca8a0d5ea..29d9d035c73a 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -19,11 +19,11 @@
19#include "exynos_dp_core.h" 19#include "exynos_dp_core.h"
20#include "exynos_dp_reg.h" 20#include "exynos_dp_reg.h"
21 21
22#define COMMON_INT_MASK_1 (0) 22#define COMMON_INT_MASK_1 0
23#define COMMON_INT_MASK_2 (0) 23#define COMMON_INT_MASK_2 0
24#define COMMON_INT_MASK_3 (0) 24#define COMMON_INT_MASK_3 0
25#define COMMON_INT_MASK_4 (0) 25#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
26#define INT_STA_MASK (0) 26#define INT_STA_MASK INT_HPD
27 27
28void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable) 28void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
29{ 29{
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
88void exynos_dp_init_interrupt(struct exynos_dp_device *dp) 88void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
89{ 89{
90 /* Set interrupt pin assertion polarity as high */ 90 /* Set interrupt pin assertion polarity as high */
91 writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL); 91 writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
92 92
93 /* Clear pending regisers */ 93 /* Clear pending regisers */
94 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 94 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
@@ -324,7 +324,7 @@ void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
324 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 324 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
325} 325}
326 326
327void exynos_dp_init_hpd(struct exynos_dp_device *dp) 327void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
328{ 328{
329 u32 reg; 329 u32 reg;
330 330
@@ -333,12 +333,38 @@ void exynos_dp_init_hpd(struct exynos_dp_device *dp)
333 333
334 reg = INT_HPD; 334 reg = INT_HPD;
335 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 335 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
336}
337
338void exynos_dp_init_hpd(struct exynos_dp_device *dp)
339{
340 u32 reg;
341
342 exynos_dp_clear_hotplug_interrupts(dp);
336 343
337 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 344 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
338 reg &= ~(F_HPD | HPD_CTRL); 345 reg &= ~(F_HPD | HPD_CTRL);
339 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 346 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
340} 347}
341 348
349enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
350{
351 u32 reg;
352
353 /* Parse hotplug interrupt status register */
354 reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
355
356 if (reg & PLUG)
357 return DP_IRQ_TYPE_HP_CABLE_IN;
358
359 if (reg & HPD_LOST)
360 return DP_IRQ_TYPE_HP_CABLE_OUT;
361
362 if (reg & HOTPLUG_CHG)
363 return DP_IRQ_TYPE_HP_CHANGE;
364
365 return DP_IRQ_TYPE_UNKNOWN;
366}
367
342void exynos_dp_reset_aux(struct exynos_dp_device *dp) 368void exynos_dp_reset_aux(struct exynos_dp_device *dp)
343{ 369{
344 u32 reg; 370 u32 reg;
@@ -491,7 +517,7 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
491 int i; 517 int i;
492 int retval; 518 int retval;
493 519
494 for (i = 0; i < 10; i++) { 520 for (i = 0; i < 3; i++) {
495 /* Clear AUX CH data buffer */ 521 /* Clear AUX CH data buffer */
496 reg = BUF_CLR; 522 reg = BUF_CLR;
497 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 523 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
@@ -552,7 +578,7 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
552 else 578 else
553 cur_data_count = count - start_offset; 579 cur_data_count = count - start_offset;
554 580
555 for (i = 0; i < 10; i++) { 581 for (i = 0; i < 3; i++) {
556 /* Select DPCD device address */ 582 /* Select DPCD device address */
557 reg = AUX_ADDR_7_0(reg_addr + start_offset); 583 reg = AUX_ADDR_7_0(reg_addr + start_offset);
558 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 584 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
@@ -617,7 +643,7 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
617 cur_data_count = count - start_offset; 643 cur_data_count = count - start_offset;
618 644
619 /* AUX CH Request Transaction process */ 645 /* AUX CH Request Transaction process */
620 for (i = 0; i < 10; i++) { 646 for (i = 0; i < 3; i++) {
621 /* Select DPCD device address */ 647 /* Select DPCD device address */
622 reg = AUX_ADDR_7_0(reg_addr + start_offset); 648 reg = AUX_ADDR_7_0(reg_addr + start_offset);
623 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 649 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
@@ -700,17 +726,15 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
700 int i; 726 int i;
701 int retval; 727 int retval;
702 728
703 for (i = 0; i < 10; i++) { 729 for (i = 0; i < 3; i++) {
704 /* Clear AUX CH data buffer */ 730 /* Clear AUX CH data buffer */
705 reg = BUF_CLR; 731 reg = BUF_CLR;
706 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 732 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
707 733
708 /* Select EDID device */ 734 /* Select EDID device */
709 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); 735 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
710 if (retval != 0) { 736 if (retval != 0)
711 dev_err(dp->dev, "Select EDID device fail!\n");
712 continue; 737 continue;
713 }
714 738
715 /* 739 /*
716 * Set I2C transaction and read data 740 * Set I2C transaction and read data
@@ -750,7 +774,7 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
750 int retval = 0; 774 int retval = 0;
751 775
752 for (i = 0; i < count; i += 16) { 776 for (i = 0; i < count; i += 16) {
753 for (j = 0; j < 100; j++) { 777 for (j = 0; j < 3; j++) {
754 /* Clear AUX CH data buffer */ 778 /* Clear AUX CH data buffer */
755 reg = BUF_CLR; 779 reg = BUF_CLR;
756 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 780 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
@@ -1034,24 +1058,20 @@ void exynos_dp_init_video(struct exynos_dp_device *dp)
1034 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); 1058 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
1035} 1059}
1036 1060
1037void exynos_dp_set_video_color_format(struct exynos_dp_device *dp, 1061void exynos_dp_set_video_color_format(struct exynos_dp_device *dp)
1038 u32 color_depth,
1039 u32 color_space,
1040 u32 dynamic_range,
1041 u32 ycbcr_coeff)
1042{ 1062{
1043 u32 reg; 1063 u32 reg;
1044 1064
1045 /* Configure the input color depth, color space, dynamic range */ 1065 /* Configure the input color depth, color space, dynamic range */
1046 reg = (dynamic_range << IN_D_RANGE_SHIFT) | 1066 reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
1047 (color_depth << IN_BPC_SHIFT) | 1067 (dp->video_info->color_depth << IN_BPC_SHIFT) |
1048 (color_space << IN_COLOR_F_SHIFT); 1068 (dp->video_info->color_space << IN_COLOR_F_SHIFT);
1049 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); 1069 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
1050 1070
1051 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ 1071 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
1052 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1072 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
1053 reg &= ~IN_YC_COEFFI_MASK; 1073 reg &= ~IN_YC_COEFFI_MASK;
1054 if (ycbcr_coeff) 1074 if (dp->video_info->ycbcr_coeff)
1055 reg |= IN_YC_COEFFI_ITU709; 1075 reg |= IN_YC_COEFFI_ITU709;
1056 else 1076 else
1057 reg |= IN_YC_COEFFI_ITU601; 1077 reg |= IN_YC_COEFFI_ITU601;
@@ -1178,8 +1198,7 @@ int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
1178 return 0; 1198 return 0;
1179} 1199}
1180 1200
1181void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp, 1201void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
1182 struct video_info *video_info)
1183{ 1202{
1184 u32 reg; 1203 u32 reg;
1185 1204
@@ -1190,17 +1209,17 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
1190 1209
1191 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1210 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1192 reg &= ~INTERACE_SCAN_CFG; 1211 reg &= ~INTERACE_SCAN_CFG;
1193 reg |= (video_info->interlaced << 2); 1212 reg |= (dp->video_info->interlaced << 2);
1194 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1213 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1195 1214
1196 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1215 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1197 reg &= ~VSYNC_POLARITY_CFG; 1216 reg &= ~VSYNC_POLARITY_CFG;
1198 reg |= (video_info->v_sync_polarity << 1); 1217 reg |= (dp->video_info->v_sync_polarity << 1);
1199 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1218 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1200 1219
1201 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1220 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1202 reg &= ~HSYNC_POLARITY_CFG; 1221 reg &= ~HSYNC_POLARITY_CFG;
1203 reg |= (video_info->h_sync_polarity << 0); 1222 reg |= (dp->video_info->h_sync_polarity << 0);
1204 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1223 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1205 1224
1206 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; 1225 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;