drm/rockchip: lvds: Add support for rk3366
authorWeiYong Bi <bivvy.bi@rock-chips.com>
Wed, 12 Jul 2017 06:20:34 +0000 (14:20 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 19 Jul 2017 06:33:58 +0000 (14:33 +0800)
Change-Id: Iaf54c4667042b0b24a9083cb7ca931c1b0603804
Signed-off-by: WeiYong Bi <bivvy.bi@rock-chips.com>
Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/rockchip-lvds.txt [deleted file]
drivers/gpu/drm/rockchip/rockchip_lvds.c
drivers/gpu/drm/rockchip/rockchip_lvds.h

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt
new file mode 100644 (file)
index 0000000..1f436f2
--- /dev/null
@@ -0,0 +1,110 @@
+Rockchip RK3288 LVDS interface
+================================
+
+Required properties:
+- compatible: matching the soc type, one of
+       - "rockchip,rk3288-lvds";
+       - "rockchip,rk3366-lvds";
+       - "rockchip,rk3368-lvds";
+
+- reg: physical base address of the controller and length
+       of memory mapped region.
+- reg-names: the name to indicate register. example:
+       - "mipi_lvds_phy": lvds phy register, this's included in the MIPI phy module
+       - "mipi_lvds_ctl": lvds control register, this's included in the MIPI
+               controller module
+- clocks: must include clock specifiers corresponding to entries in the
+       clock-names property.
+- clock-names: must contain "pclk_lvds"
+
+- avdd1v0-supply: regulator phandle for 1.0V analog power
+- avdd1v8-supply: regulator phandle for 1.8V analog power
+- avdd3v3-supply: regulator phandle for 3.3V analog power
+
+- rockchip,grf: phandle to the general register files syscon
+
+- rockchip,data-mapping: should be "vesa" or "jeida",
+       This describes how the color bits are laid out in the
+       serialized LVDS signal.
+- rockchip,data-width : should be <18> or <24>;
+- rockchip,output: should be "rgb", "lvds" or "duallvds",
+       This describes the output face.
+
+Optional properties
+- pinctrl-names: must contain a "default" entry.
+- pinctrl-0: pin control group to be used for this controller.
+- pinctrl-1: pin control group to be used for gpio.
+
+Required nodes:
+
+The lvds has two video ports as described by
+       Documentation/devicetree/bindings/media/video-interfaces.txt.
+Their connections are modeled using the OF graph bindings specified in
+       Documentation/devicetree/bindings/graph.txt.
+
+- video port 0 for the VOP inputs
+- video port 1 for either a panel or subsequent encoder
+
+Example:
+
+For Rockchip RK3288:
+
+       lvds: lvds@ff96c000 {
+               compatible = "rockchip,rk3288-lvds";
+               rockchip,grf = <&grf>;
+               reg = <0xff96c000 0x4000>;
+               clocks = <&cru PCLK_LVDS_PHY>;
+               clock-names = "pclk_lvds";
+               avdd1v0-supply = <&vdd10_lcd>;
+               avdd1v8-supply = <&vcc18_lcd>;
+               avdd3v3-supply = <&vcca_33>;
+               rockchip,data-mapping = "jeida";
+               rockchip,data-width = <24>;
+               rockchip,output = "rgb";
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       lvds_in: port@0 {
+                               reg = <0>;
+
+                               lvds_in_vopb: endpoint@0 {
+                                       reg = <0>;
+                                       remote-endpoint = <&vopb_out_lvds>;
+                               };
+                               lvds_in_vopl: endpoint@1 {
+                                       reg = <1>;
+                                       remote-endpoint = <&vopl_out_lvds>;
+                               };
+                       };
+
+                       lvds_out: port@1 {
+                               reg = <1>;
+
+                               lvds_out_panel: endpoint {
+                                       remote-endpoint = <&panel_in>;
+                               };
+                       };
+               };
+       };
+
+For Rockchip RK3368:
+
+       lvds: lvds@ff968000 {
+               compatible = "rockchip,rk3368-lvds";
+               reg = <0x0 0xff968000 0x0 0x4000>, <0x0 0xff9600a0 0x0 0x20>;
+               reg-names = "mipi_lvds_phy", "mipi_lvds_ctl";
+               clocks = <&cru PCLK_DPHYTX0>, <&cru PCLK_MIPI_DSI0>;
+               clock-names = "pclk_lvds", "pclk_lvds_ctl";
+               power-domains = <&power RK3368_PD_VIO>;
+               rockchip,grf = <&grf>;
+               pinctrl-names = "lcdc", "gpio";
+               pinctrl-0 = <&lcdc_lcdc>;
+               pinctrl-1 = <&lcdc_gpio>;
+
+               ports {
+
+               ...
+
+               };
+       };
diff --git a/Documentation/devicetree/bindings/video/rockchip-lvds.txt b/Documentation/devicetree/bindings/video/rockchip-lvds.txt
deleted file mode 100644 (file)
index 51f4864..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-Rockchip RK3288 LVDS interface
-================================
-
-Required properties:
-- compatible: matching the soc type, one of
-       - "rockchip,rk3288-lvds";
-       - "rockchip,rk33xx-lvds";
-
-- reg: physical base address of the controller and length
-       of memory mapped region.
-- reg-names: the name to indicate register. example:
-       - "mipi_lvds_phy": lvds phy register, this's included in the MIPI phy module
-       - "mipi_lvds_ctl": lvds control register, this's included in the MIPI
-               controller module
-- clocks: must include clock specifiers corresponding to entries in the
-       clock-names property.
-- clock-names: must contain "pclk_lvds"
-
-- avdd1v0-supply: regulator phandle for 1.0V analog power
-- avdd1v8-supply: regulator phandle for 1.8V analog power
-- avdd3v3-supply: regulator phandle for 3.3V analog power
-
-- rockchip,grf: phandle to the general register files syscon
-
-- rockchip,data-mapping: should be "vesa" or "jeida",
-       This describes how the color bits are laid out in the
-       serialized LVDS signal.
-- rockchip,data-width : should be <18> or <24>;
-- rockchip,output: should be "rgb", "lvds" or "duallvds",
-       This describes the output face.
-
-Optional properties
-- pinctrl-names: must contain a "default" entry.
-- pinctrl-0: pin control group to be used for this controller.
-- pinctrl-1: pin control group to be used for gpio.
-
-Required nodes:
-
-The lvds has two video ports as described by
-       Documentation/devicetree/bindings/media/video-interfaces.txt.
-Their connections are modeled using the OF graph bindings specified in
-       Documentation/devicetree/bindings/graph.txt.
-
-- video port 0 for the VOP inputs
-- video port 1 for either a panel or subsequent encoder
-
-Example:
-
-For Rockchip RK3288:
-
-       lvds: lvds@ff96c000 {
-               compatible = "rockchip,rk3288-lvds";
-               rockchip,grf = <&grf>;
-               reg = <0xff96c000 0x4000>;
-               clocks = <&cru PCLK_LVDS_PHY>;
-               clock-names = "pclk_lvds";
-               avdd1v0-supply = <&vdd10_lcd>;
-               avdd1v8-supply = <&vcc18_lcd>;
-               avdd3v3-supply = <&vcca_33>;
-               rockchip,data-mapping = "jeida";
-               rockchip,data-width = <24>;
-               rockchip,output = "rgb";
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       lvds_in: port@0 {
-                               reg = <0>;
-
-                               lvds_in_vopb: endpoint@0 {
-                                       reg = <0>;
-                                       remote-endpoint = <&vopb_out_lvds>;
-                               };
-                               lvds_in_vopl: endpoint@1 {
-                                       reg = <1>;
-                                       remote-endpoint = <&vopl_out_lvds>;
-                               };
-                       };
-
-                       lvds_out: port@1 {
-                               reg = <1>;
-
-                               lvds_out_panel: endpoint {
-                                       remote-endpoint = <&panel_in>;
-                               };
-                       };
-               };
-       };
-
-For Rockchip RK3368:
-
-       lvds: lvds@ff968000 {
-               compatible = "rockchip,rk33xx-lvds";
-               reg = <0x0 0xff968000 0x0 0x4000>, <0x0 0xff9600a0 0x0 0x20>;
-               reg-names = "mipi_lvds_phy", "mipi_lvds_ctl";
-               clocks = <&cru PCLK_DPHYTX0>, <&cru PCLK_MIPI_DSI0>;
-               clock-names = "pclk_lvds", "pclk_lvds_ctl";
-               power-domains = <&power RK3368_PD_VIO>;
-               rockchip,grf = <&grf>;
-               pinctrl-names = "lcdc", "gpio";
-               pinctrl-0 = <&lcdc_lcdc>;
-               pinctrl-1 = <&lcdc_gpio>;
-
-               ports {
-
-               ...
-
-               };
-       };
\ No newline at end of file
index 067910d19dc96ca5ddecb5f0bc750e334c6d0009..f8fd4875722fb177185669521704bc345fb9686e 100644 (file)
@@ -54,6 +54,8 @@ struct rockchip_lvds_soc_data {
        int grf_soc_con6;
        int grf_soc_con7;
        int grf_soc_con15;
+
+       bool has_vop_sel;
 };
 
 struct rockchip_lvds {
@@ -215,7 +217,7 @@ static int rk3288_lvds_poweron(struct rockchip_lvds *lvds)
        return 0;
 }
 
-static int rk3368_lvds_poweron(struct rockchip_lvds *lvds)
+static int rk336x_lvds_poweron(struct rockchip_lvds *lvds)
 {
        u32 delay_times = 20;
 
@@ -255,7 +257,7 @@ static int rk3368_lvds_poweron(struct rockchip_lvds *lvds)
        return 0;
 }
 
-static void rk3368_output_ttl(struct rockchip_lvds *lvds)
+static void rk336x_output_ttl(struct rockchip_lvds *lvds)
 {
        u32 val = 0;
 
@@ -270,10 +272,10 @@ static void rk3368_output_ttl(struct rockchip_lvds *lvds)
                v_MSB_SEL(1) | v_DIG_INTER_RST(1);
        lvds_writel(lvds, MIPIPHY_REGE0, val);
 
-       rk3368_lvds_poweron(lvds);
+       rk336x_lvds_poweron(lvds);
 }
 
-static void rk3368_output_lvds(struct rockchip_lvds *lvds)
+static void rk336x_output_lvds(struct rockchip_lvds *lvds)
 {
        /* digital internal disable */
        lvds_msk_reg(lvds, MIPIPHY_REGE1, m_DIG_INTER_EN, v_DIG_INTER_EN(0));
@@ -289,16 +291,16 @@ static void rk3368_output_lvds(struct rockchip_lvds *lvds)
                     m_MSB_SEL | m_DIG_INTER_RST,
                     v_MSB_SEL(1) | v_DIG_INTER_RST(1));
 
-       rk3368_lvds_poweron(lvds);
+       rk336x_lvds_poweron(lvds);
        lvds_msk_reg(lvds, MIPIPHY_REGE1, m_DIG_INTER_EN, v_DIG_INTER_EN(1));
 }
 
-static int rk3368_lvds_output(struct rockchip_lvds *lvds)
+static int rk336x_lvds_output(struct rockchip_lvds *lvds)
 {
        if (lvds->output == DISPLAY_OUTPUT_RGB)
-               rk3368_output_ttl(lvds);
+               rk336x_output_ttl(lvds);
        else
-               rk3368_output_lvds(lvds);
+               rk336x_output_lvds(lvds);
        return 0;
 }
 
@@ -328,8 +330,8 @@ static int rockchip_lvds_poweron(struct rockchip_lvds *lvds)
        }
        if (LVDS_CHIP(lvds) == RK3288_LVDS)
                rk3288_lvds_poweron(lvds);
-       else if (LVDS_CHIP(lvds) == RK3368_LVDS)
-               rk3368_lvds_output(lvds);
+       else if (LVDS_CHIP(lvds) == RK336X_LVDS)
+               rk336x_lvds_output(lvds);
 
        return 0;
 }
@@ -353,8 +355,8 @@ static void rockchip_lvds_poweroff(struct rockchip_lvds *lvds)
                pm_runtime_put(lvds->dev);
                if (lvds->pclk)
                        clk_disable(lvds->pclk);
-       } else if (LVDS_CHIP(lvds) == RK3368_LVDS) {
-               val = v_RK3368_LVDSMODE_EN(0) | v_RK3368_MIPIPHY_TTL_EN(0);
+       } else if (LVDS_CHIP(lvds) == RK336X_LVDS) {
+               val = v_RK336X_LVDSMODE_EN(0) | v_RK336X_MIPIPHY_TTL_EN(0);
                ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val);
                if (ret != 0) {
                        dev_err(lvds->dev, "Could not write to GRF: %d\n", ret);
@@ -513,7 +515,7 @@ static void rockchip_lvds_encoder_mode_set(struct drm_encoder *encoder,
                        dev_err(lvds->dev, "Could not write to GRF: %d\n", ret);
                        return;
                }
-       } else if (LVDS_CHIP(lvds) == RK3368_LVDS) {
+       } else if (LVDS_CHIP(lvds) == RK336X_LVDS) {
                if (lvds->output == DISPLAY_OUTPUT_RGB) {
                        /* iomux to lcdc */
                        if (lvds->pins && !IS_ERR(lvds->pins->default_state))
@@ -522,10 +524,10 @@ static void rockchip_lvds_encoder_mode_set(struct drm_encoder *encoder,
 
                        lvds_dsi_writel(lvds, 0x0, 0x4);/*set clock lane enable*/
                        /* enable lvds mode */
-                       val = v_RK3368_LVDSMODE_EN(0) |
-                               v_RK3368_MIPIPHY_TTL_EN(1) |
-                               v_RK3368_MIPIPHY_LANE0_EN(1) |
-                               v_RK3368_MIPIDPI_FORCEX_EN(1);
+                       val = v_RK336X_LVDSMODE_EN(0) |
+                               v_RK336X_MIPIPHY_TTL_EN(1) |
+                               v_RK336X_MIPIPHY_LANE0_EN(1) |
+                               v_RK336X_MIPIDPI_FORCEX_EN(1);
                        ret = regmap_write(lvds->grf,
                                           lvds->soc_data->grf_soc_con7, val);
                        if (ret != 0) {
@@ -533,7 +535,7 @@ static void rockchip_lvds_encoder_mode_set(struct drm_encoder *encoder,
                                        "Could not write to GRF: %d\n", ret);
                                return;
                        }
-                       val = v_RK3368_FORCE_JETAG(0);
+                       val = v_RK336X_FORCE_JETAG(0);
                        ret = regmap_write(lvds->grf,
                                           lvds->soc_data->grf_soc_con15, val);
                        if (ret != 0) {
@@ -543,13 +545,14 @@ static void rockchip_lvds_encoder_mode_set(struct drm_encoder *encoder,
                        }
                } else if (lvds->output == DISPLAY_OUTPUT_LVDS) {
                        /* enable lvds mode */
-                       val = v_RK3368_LVDSMODE_EN(1) | v_RK3368_MIPIPHY_TTL_EN(0);
+                       val = v_RK336X_LVDSMODE_EN(1) |
+                             v_RK336X_MIPIPHY_TTL_EN(0);
                        /* config lvds_format */
-                       val |= v_RK3368_LVDS_OUTPUT_FORMAT(lvds->format);
+                       val |= v_RK336X_LVDS_OUTPUT_FORMAT(lvds->format);
                        /* LSB receive mode */
-                       val |= v_RK3368_LVDS_MSBSEL(LVDS_MSB_D7);
-                       val |= v_RK3368_MIPIPHY_LANE0_EN(1) |
-                              v_RK3368_MIPIDPI_FORCEX_EN(1);
+                       val |= v_RK336X_LVDS_MSBSEL(LVDS_MSB_D7);
+                       val |= v_RK336X_MIPIPHY_LANE0_EN(1) |
+                              v_RK336X_MIPIDPI_FORCEX_EN(1);
                        ret = regmap_write(lvds->grf,
                                           lvds->soc_data->grf_soc_con7, val);
                        if (ret != 0) {
@@ -567,6 +570,9 @@ static int rockchip_lvds_set_vop_source(struct rockchip_lvds *lvds,
        u32 val;
        int ret;
 
+       if (!lvds->soc_data->has_vop_sel)
+               return 0;
+
        ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder);
        if (ret < 0)
                return ret;
@@ -581,7 +587,14 @@ static int rockchip_lvds_set_vop_source(struct rockchip_lvds *lvds,
                ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con6, val);
                if (ret < 0)
                        return ret;
+       } else {
+               if (ret)
+                       val = RK3366_LVDS_VOP_SEL_LIT;
+               else
+                       val = RK3366_LVDS_VOP_SEL_BIG;
+               regmap_write(lvds->grf, RK3366_GRF_SOC_CON0, val);
        }
+
        return 0;
 }
 
@@ -637,14 +650,21 @@ static struct rockchip_lvds_soc_data rk3288_lvds_data = {
        .chip_type = RK3288_LVDS,
        .grf_soc_con6 = 0x025c,
        .grf_soc_con7 = 0x0260,
+       .has_vop_sel = true,
+};
+
+static struct rockchip_lvds_soc_data rk3366_lvds_data = {
+       .chip_type = RK336X_LVDS,
+       .grf_soc_con7  = RK3366_GRF_SOC_CON5,
+       .grf_soc_con15 = RK3366_GRF_SOC_CON6,
+       .has_vop_sel = true,
 };
 
-static struct rockchip_lvds_soc_data rk33xx_lvds_data = {
-       .chip_type = RK3368_LVDS,
-       .grf_soc_con5  = 0x0414,
-       .grf_soc_con6  = 0x0418,
-       .grf_soc_con7  = 0x041c,
-       .grf_soc_con15 = 0x043c,
+static struct rockchip_lvds_soc_data rk3368_lvds_data = {
+       .chip_type = RK336X_LVDS,
+       .grf_soc_con7  = RK3368_GRF_SOC_CON7,
+       .grf_soc_con15 = RK3368_GRF_SOC_CON15,
+       .has_vop_sel = false,
 };
 
 static const struct of_device_id rockchip_lvds_dt_ids[] = {
@@ -653,8 +673,12 @@ static const struct of_device_id rockchip_lvds_dt_ids[] = {
                .data = &rk3288_lvds_data
        },
        {
-               .compatible = "rockchip,rk33xx-lvds",
-               .data = &rk33xx_lvds_data
+               .compatible = "rockchip,rk3366-lvds",
+               .data = &rk3366_lvds_data
+       },
+       {
+               .compatible = "rockchip,rk3368-lvds",
+               .data = &rk3368_lvds_data
        },
        {}
 };
@@ -830,7 +854,7 @@ static int rockchip_lvds_probe(struct platform_device *pdev)
                lvds->regs = devm_ioremap_resource(&pdev->dev, res);
                if (IS_ERR(lvds->regs))
                        return PTR_ERR(lvds->regs);
-       } else if (LVDS_CHIP(lvds) == RK3368_LVDS) {
+       } else if (LVDS_CHIP(lvds) == RK336X_LVDS) {
                /* lvds regs on MIPIPHY_REG */
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                                   "mipi_lvds_phy");
index 803566b37955bfe55a2cb4a36065af57ec066d11..28ac030effec5751df54dd3ff82daf50a1b5a49b 100644 (file)
 
 #define RK3288_LVDS_SOC_CON6_SEL_VOP_LIT       BIT(3)
 
+#define RK3366_GRF_SOC_CON0    0x0400
+#define RK3366_LVDS_VOP_SEL_LIT        (BITS_MASK(1, 1, 0) | BITS_EN(1, 0))
+#define RK3366_LVDS_VOP_SEL_BIG        (BITS_MASK(0, 1, 0) | BITS_EN(1, 0))
+#define RK3366_GRF_SOC_CON5    0x0414
+#define RK3366_GRF_SOC_CON6    0x0418
+
+#define RK3368_GRF_SOC_CON7    0x041c
+#define RK3368_GRF_SOC_CON15   0x043c
+
 #define LVDS_FMT_MASK                          (0x07 << 16)
 #define LVDS_MSB                               BIT(3)
 #define LVDS_DUAL                              BIT(4)
 #define v_LANE1_EN(x)          BITS_MASK(x, 1, 6)
 #define v_LANE0_EN(x)          BITS_MASK(x, 1, 7)
 
-#define v_RK3368_LVDS_OUTPUT_FORMAT(x) (BITS_MASK(x, 3, 13) | BITS_EN(3, 13))
-#define v_RK3368_LVDS_MSBSEL(x)                (BITS_MASK(x, 1, 11) | BITS_EN(1, 11))
-#define v_RK3368_LVDSMODE_EN(x)                (BITS_MASK(x, 1, 12) | BITS_EN(1, 12))
-#define v_RK3368_MIPIPHY_TTL_EN(x)     (BITS_MASK(x, 1, 15) | BITS_EN(1, 15))
-#define v_RK3368_MIPIPHY_LANE0_EN(x)   (BITS_MASK(x, 1, 5) | BITS_EN(1, 5))
-#define v_RK3368_MIPIDPI_FORCEX_EN(x)  (BITS_MASK(x, 1, 6) | BITS_EN(1, 6))
-#define v_RK3368_FORCE_JETAG(x)                (BITS_MASK(x, 1, 13) | BITS_EN(1, 13))
+#define v_RK336X_LVDS_OUTPUT_FORMAT(x) (BITS_MASK(x, 3, 13) | BITS_EN(3, 13))
+#define v_RK336X_LVDS_MSBSEL(x)                (BITS_MASK(x, 1, 11) | BITS_EN(1, 11))
+#define v_RK336X_LVDSMODE_EN(x)                (BITS_MASK(x, 1, 12) | BITS_EN(1, 12))
+#define v_RK336X_MIPIPHY_TTL_EN(x)     (BITS_MASK(x, 1, 15) | BITS_EN(1, 15))
+#define v_RK336X_MIPIPHY_LANE0_EN(x)   (BITS_MASK(x, 1, 5) | BITS_EN(1, 5))
+#define v_RK336X_MIPIDPI_FORCEX_EN(x)  (BITS_MASK(x, 1, 6) | BITS_EN(1, 6))
+#define v_RK336X_FORCE_JETAG(x)                (BITS_MASK(x, 1, 13) | BITS_EN(1, 13))
 
 enum {
        LVDS_MSB_D0 = 0,
@@ -184,7 +193,7 @@ enum {
 
 enum rockchip_lvds_sub_devtype {
        RK3288_LVDS,
-       RK3368_LVDS,
+       RK336X_LVDS,
 };
 
 #endif /* _ROCKCHIP_LVDS_ */