video: exynos_dp: Fix incorrect setting for INT_CTL
[firefly-linux-kernel-4.4.55.git] / drivers / video / exynos / exynos_dp_reg.c
index 3f5ca8a0d5ea45076d3929decfb514a1d9e5e52c..93b4b6bb796ca7334b54c30b162915aa81efc40a 100644 (file)
 #include "exynos_dp_core.h"
 #include "exynos_dp_reg.h"
 
-#define COMMON_INT_MASK_1 (0)
-#define COMMON_INT_MASK_2 (0)
-#define COMMON_INT_MASK_3 (0)
-#define COMMON_INT_MASK_4 (0)
-#define INT_STA_MASK (0)
+#define COMMON_INT_MASK_1      0
+#define COMMON_INT_MASK_2      0
+#define COMMON_INT_MASK_3      0
+#define COMMON_INT_MASK_4      (HOTPLUG_CHG | HPD_LOST | PLUG)
+#define INT_STA_MASK           INT_HPD
 
 void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
 {
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
 void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
 {
        /* Set interrupt pin assertion polarity as high */
-       writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
+       writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
 
        /* Clear pending regisers */
        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)
        writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
 }
 
-void exynos_dp_init_hpd(struct exynos_dp_device *dp)
+void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
 {
        u32 reg;
 
@@ -333,12 +333,38 @@ void exynos_dp_init_hpd(struct exynos_dp_device *dp)
 
        reg = INT_HPD;
        writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
+}
+
+void exynos_dp_init_hpd(struct exynos_dp_device *dp)
+{
+       u32 reg;
+
+       exynos_dp_clear_hotplug_interrupts(dp);
 
        reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
        reg &= ~(F_HPD | HPD_CTRL);
        writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
 }
 
+enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
+{
+       u32 reg;
+
+       /* Parse hotplug interrupt status register */
+       reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
+
+       if (reg & PLUG)
+               return DP_IRQ_TYPE_HP_CABLE_IN;
+
+       if (reg & HPD_LOST)
+               return DP_IRQ_TYPE_HP_CABLE_OUT;
+
+       if (reg & HOTPLUG_CHG)
+               return DP_IRQ_TYPE_HP_CHANGE;
+
+       return DP_IRQ_TYPE_UNKNOWN;
+}
+
 void exynos_dp_reset_aux(struct exynos_dp_device *dp)
 {
        u32 reg;
@@ -491,7 +517,7 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
        int i;
        int retval;
 
-       for (i = 0; i < 10; i++) {
+       for (i = 0; i < 3; i++) {
                /* Clear AUX CH data buffer */
                reg = BUF_CLR;
                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,
                else
                        cur_data_count = count - start_offset;
 
-               for (i = 0; i < 10; i++) {
+               for (i = 0; i < 3; i++) {
                        /* Select DPCD device address */
                        reg = AUX_ADDR_7_0(reg_addr + start_offset);
                        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,
                        cur_data_count = count - start_offset;
 
                /* AUX CH Request Transaction process */
-               for (i = 0; i < 10; i++) {
+               for (i = 0; i < 3; i++) {
                        /* Select DPCD device address */
                        reg = AUX_ADDR_7_0(reg_addr + start_offset);
                        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,
        int i;
        int retval;
 
-       for (i = 0; i < 10; i++) {
+       for (i = 0; i < 3; i++) {
                /* Clear AUX CH data buffer */
                reg = BUF_CLR;
                writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
 
                /* Select EDID device */
                retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
-               if (retval != 0) {
-                       dev_err(dp->dev, "Select EDID device fail!\n");
+               if (retval != 0)
                        continue;
-               }
 
                /*
                 * Set I2C transaction and read data
@@ -750,7 +774,7 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
        int retval = 0;
 
        for (i = 0; i < count; i += 16) {
-               for (j = 0; j < 100; j++) {
+               for (j = 0; j < 3; j++) {
                        /* Clear AUX CH data buffer */
                        reg = BUF_CLR;
                        writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);