From d9c900b0270a18101403cf5e95c1639fccd43a9f Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:01 +0800 Subject: drm/rockchip: analogix_dp: split the lcdc select setting into device data eDP controller need to declare which vop provide the video source, and it's defined in GRF registers. But different chips have different GRF register address, so we need to create a device data to declare the GRF messages for each chips. Signed-off-by: Yakir Yang Acked-by: Mark Yao Reviewed-by: Tomasz Figa Reviewed-by: Sean Paul diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index c120172..0a30931 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -33,13 +34,26 @@ #include "rockchip_drm_drv.h" #include "rockchip_drm_vop.h" +#define RK3288_GRF_SOC_CON6 0x25c +#define RK3288_EDP_LCDC_SEL BIT(5) + +#define HIWORD_UPDATE(val, mask) (val | (mask) << 16) + #define to_dp(nm) container_of(nm, struct rockchip_dp_device, nm) -/* dp grf register offset */ -#define GRF_SOC_CON6 0x025c -#define GRF_EDP_LCD_SEL_MASK BIT(5) -#define GRF_EDP_SEL_VOP_LIT BIT(5) -#define GRF_EDP_SEL_VOP_BIG 0 +/** + * struct rockchip_dp_chip_data - splite the grf setting of kind of chips + * @lcdsel_grf_reg: grf register offset of lcdc select + * @lcdsel_big: reg value of selecting vop big for eDP + * @lcdsel_lit: reg value of selecting vop little for eDP + * @chip_type: specific chip type + */ +struct rockchip_dp_chip_data { + u32 lcdsel_grf_reg; + u32 lcdsel_big; + u32 lcdsel_lit; + u32 chip_type; +}; struct rockchip_dp_device { struct drm_device *drm_dev; @@ -51,6 +65,8 @@ struct rockchip_dp_device { struct regmap *grf; struct reset_control *rst; + const struct rockchip_dp_chip_data *data; + struct analogix_dp_plat_data plat_data; }; @@ -119,13 +135,13 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder) return; if (ret) - val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK << 16); + val = dp->data->lcdsel_lit; else - val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK << 16); + val = dp->data->lcdsel_big; dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG"); - ret = regmap_write(dp->grf, GRF_SOC_CON6, val); + ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val); if (ret != 0) { dev_err(dp->dev, "Could not write to GRF: %d\n", ret); return; @@ -246,6 +262,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, void *data) { struct rockchip_dp_device *dp = dev_get_drvdata(dev); + const struct rockchip_dp_chip_data *dp_data; struct drm_device *drm_dev = data; int ret; @@ -256,10 +273,15 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, */ dev_set_drvdata(dev, NULL); + dp_data = of_device_get_match_data(dev); + if (!dp_data) + return -ENODEV; + ret = rockchip_dp_init(dp); if (ret < 0) return ret; + dp->data = dp_data; dp->drm_dev = drm_dev; ret = rockchip_dp_drm_create_encoder(dp); @@ -270,7 +292,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, dp->plat_data.encoder = &dp->encoder; - dp->plat_data.dev_type = RK3288_DP; + dp->plat_data.dev_type = dp->data->chip_type; dp->plat_data.power_on = rockchip_dp_poweron; dp->plat_data.power_off = rockchip_dp_powerdown; @@ -356,8 +378,15 @@ static const struct dev_pm_ops rockchip_dp_pm_ops = { #endif }; +static const struct rockchip_dp_chip_data rk3288_dp = { + .lcdsel_grf_reg = RK3288_GRF_SOC_CON6, + .lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL), + .lcdsel_lit = HIWORD_UPDATE(RK3288_EDP_LCDC_SEL, RK3288_EDP_LCDC_SEL), + .chip_type = RK3288_DP, +}; + static const struct of_device_id rockchip_dp_dt_ids[] = { - {.compatible = "rockchip,rk3288-dp",}, + {.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp }, {} }; MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids); -- cgit v0.10.2 From cb5571fcf809860c455f6b62bb5252f277b52e83 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:05 +0800 Subject: drm/bridge: analogix_dp: correct the register bit define error in ANALOGIX_DP_PLL_REG_1 There're an register define error in ANALOGIX_DP_PLL_REG_1 which introduced by commit bcec20fd5ad6 ("drm: bridge: analogix/dp: add some rk3288 special registers setting"). The PHY PLL input clock source is selected by ANALOGIX_DP_PLL_REG_1 BIT 0, not BIT 1. Signed-off-by: Yakir Yang Reviewed-by: Sean Paul Reviewed-by: Tomasz Figa Tested-by: Javier Martinez Canillas diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h index 337912b..88d56ad 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h @@ -163,8 +163,8 @@ #define HSYNC_POLARITY_CFG (0x1 << 0) /* ANALOGIX_DP_PLL_REG_1 */ -#define REF_CLK_24M (0x1 << 1) -#define REF_CLK_27M (0x0 << 1) +#define REF_CLK_24M (0x1 << 0) +#define REF_CLK_27M (0x0 << 0) /* ANALOGIX_DP_LANE_MAP */ #define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6) -- cgit v0.10.2 From 7bdc072086939093238a970f054e8e63d531253d Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:18 +0800 Subject: drm/bridge: analogix_dp: some rockchip chips need to flip REF_CLK bit setting As vendor document indicate, when REF_CLK bit set 0, then DP phy's REF_CLK should switch to 24M source clock. But due to IC PHY layout mistaken, some chips need to flip this bit(like RK3288), and unfortunately they didn't indicate in the DP version register. That's why we have to make this little hack. Signed-off-by: Yakir Yang Reviewed-by: Tomasz Figa Tested-by: Javier Martinez Canillas Reviewed-by: Sean Paul diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 49205ef..48030f0 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -74,8 +74,12 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp) reg = SEL_24M | TX_DVDD_BIT_1_0625V; writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2); - if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) { - writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1); + if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) { + reg = REF_CLK_24M; + if (dp->plat_data->dev_type == RK3288_DP) + reg ^= REF_CLK_MASK; + + writel(reg, dp->reg_base + ANALOGIX_DP_PLL_REG_1); writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2); writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3); writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4); @@ -244,7 +248,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp, u32 reg; u32 phy_pd_addr = ANALOGIX_DP_PHY_PD; - if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) + if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) phy_pd_addr = ANALOGIX_DP_PD; switch (block) { @@ -448,7 +452,7 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp) analogix_dp_reset_aux(dp); /* Disable AUX transaction H/W retry */ - if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) + if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) | AUX_HW_RETRY_COUNT_SEL(3) | AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h index 88d56ad..cdcc6c5 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h @@ -165,6 +165,7 @@ /* ANALOGIX_DP_PLL_REG_1 */ #define REF_CLK_24M (0x1 << 0) #define REF_CLK_27M (0x0 << 0) +#define REF_CLK_MASK (0x1 << 0) /* ANALOGIX_DP_LANE_MAP */ #define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6) diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 25afb31..790ab5d 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -18,6 +18,11 @@ enum analogix_dp_devtype { RK3288_DP, }; +static inline bool is_rockchip(enum analogix_dp_devtype type) +{ + return type == RK3288_DP; +} + struct analogix_dp_plat_data { enum analogix_dp_devtype dev_type; struct drm_panel *panel; -- cgit v0.10.2 From 82872e42bb1501dd9e60ca430f4bae45a469aa64 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:26 +0800 Subject: drm/rockchip: analogix_dp: add rk3399 eDP support RK3399 and RK3288 shared the same eDP IP controller, only some light difference with VOP configure and GRF configure. Signed-off-by: Yakir Yang Acked-by: Mark Yao Reviewed-by: Tomasz Figa Reviewed-by: Sean Paul diff --git a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt index 4f2ba8c..4a0f4f7 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt +++ b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt @@ -5,6 +5,7 @@ Required properties for dp-controller: platform specific such as: * "samsung,exynos5-dp" * "rockchip,rk3288-dp" + * "rockchip,rk3399-edp" -reg: physical base address of the controller and length of memory mapped region. diff --git a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt index e832ff9..726c945 100644 --- a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt @@ -2,7 +2,8 @@ Rockchip RK3288 specific extensions to the Analogix Display Port ================================ Required properties: -- compatible: "rockchip,rk3288-edp"; +- compatible: "rockchip,rk3288-edp", + "rockchip,rk3399-edp"; - reg: physical base address of the controller and length diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 7699597..ed798e3 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1208,6 +1208,7 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp) switch (dp->plat_data->dev_type) { case RK3288_DP: + case RK3399_EDP: /* * Like Rk3288 DisplayPort TRM indicate that "Main link * containing 4 physical lanes of 2.7/1.62 Gbps/lane". diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 0a30931..8557a08 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -36,6 +36,8 @@ #define RK3288_GRF_SOC_CON6 0x25c #define RK3288_EDP_LCDC_SEL BIT(5) +#define RK3399_GRF_SOC_CON20 0x6250 +#define RK3399_EDP_LCDC_SEL BIT(5) #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) @@ -159,6 +161,8 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, struct drm_connector_state *conn_state) { struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + struct rockchip_dp_device *dp = to_dp(encoder); + int ret; /* * FIXME(Yakir): driver should configure the CRTC output video @@ -173,8 +177,19 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, * But if I configure CTRC to RGBaaa, and eDP driver still keep * RGB666 input video mode, then screen would works prefect. */ + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; s->output_type = DRM_MODE_CONNECTOR_eDP; + if (dp->data->chip_type == RK3399_EDP) { + /* + * For RK3399, VOP Lit must code the out mode to RGB888, + * VOP Big must code the out mode to RGB10. + */ + ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, + encoder); + if (ret > 0) + s->output_mode = ROCKCHIP_OUT_MODE_P888; + } return 0; } @@ -378,6 +393,13 @@ static const struct dev_pm_ops rockchip_dp_pm_ops = { #endif }; +static const struct rockchip_dp_chip_data rk3399_edp = { + .lcdsel_grf_reg = RK3399_GRF_SOC_CON20, + .lcdsel_big = HIWORD_UPDATE(0, RK3399_EDP_LCDC_SEL), + .lcdsel_lit = HIWORD_UPDATE(RK3399_EDP_LCDC_SEL, RK3399_EDP_LCDC_SEL), + .chip_type = RK3399_EDP, +}; + static const struct rockchip_dp_chip_data rk3288_dp = { .lcdsel_grf_reg = RK3288_GRF_SOC_CON6, .lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL), @@ -387,6 +409,7 @@ static const struct rockchip_dp_chip_data rk3288_dp = { static const struct of_device_id rockchip_dp_dt_ids[] = { {.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp }, + {.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp }, {} }; MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids); diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 790ab5d..fc4aea3 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -16,11 +16,12 @@ enum analogix_dp_devtype { EXYNOS_DP, RK3288_DP, + RK3399_EDP, }; static inline bool is_rockchip(enum analogix_dp_devtype type) { - return type == RK3288_DP; + return type == RK3288_DP || type == RK3399_EDP; } struct analogix_dp_plat_data { -- cgit v0.10.2 From eb87c91c73f825ea377bdd229cf1cf6ef54e1372 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:30 +0800 Subject: drm/rockchip: analogix_dp: make panel detect to an optional action Some boards don't need to declare a panel device node, like the display interface is DP monitors, so it's necessary to make the panel detect to an optional action. Signed-off-by: Yakir Yang Acked-by: Mark Yao Reviewed-by: Tomasz Figa Reviewed-by: Sean Paul diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 8557a08..0755573 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -329,38 +329,33 @@ static int rockchip_dp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *panel_node, *port, *endpoint; + struct drm_panel *panel = NULL; struct rockchip_dp_device *dp; - struct drm_panel *panel; port = of_graph_get_port_by_id(dev->of_node, 1); - if (!port) { - dev_err(dev, "can't find output port\n"); - return -EINVAL; - } - - endpoint = of_get_child_by_name(port, "endpoint"); - of_node_put(port); - if (!endpoint) { - dev_err(dev, "no output endpoint found\n"); - return -EINVAL; - } - - panel_node = of_graph_get_remote_port_parent(endpoint); - of_node_put(endpoint); - if (!panel_node) { - dev_err(dev, "no output node found\n"); - return -EINVAL; - } - - panel = of_drm_find_panel(panel_node); - if (!panel) { - DRM_ERROR("failed to find panel\n"); + if (port) { + endpoint = of_get_child_by_name(port, "endpoint"); + of_node_put(port); + if (!endpoint) { + dev_err(dev, "no output endpoint found\n"); + return -EINVAL; + } + + panel_node = of_graph_get_remote_port_parent(endpoint); + of_node_put(endpoint); + if (!panel_node) { + dev_err(dev, "no output node found\n"); + return -EINVAL; + } + + panel = of_drm_find_panel(panel_node); of_node_put(panel_node); - return -EPROBE_DEFER; + if (!panel) { + DRM_ERROR("failed to find panel\n"); + return -EPROBE_DEFER; + } } - of_node_put(panel_node); - dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); if (!dp) return -ENOMEM; -- cgit v0.10.2 From fcc150c5152d0c7aa3d37b77226e79ce5fc34cf8 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:35 +0800 Subject: drm/bridge: analogix_dp: passing the connector as an argument in .get_modes() It's better to pass the connector to platform driver in .get_modes() callback, just like what the .get_modes() helper function designed. Signed-off-by: Yakir Yang Reviewed-by: Sean Paul Reviewed-by: Tomasz Figa diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index ed798e3..32715da 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -938,7 +938,7 @@ int analogix_dp_get_modes(struct drm_connector *connector) num_modes += drm_panel_get_modes(dp->plat_data->panel); if (dp->plat_data->get_modes) - num_modes += dp->plat_data->get_modes(dp->plat_data); + num_modes += dp->plat_data->get_modes(dp->plat_data, connector); return num_modes; } diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index 4c1fb3f..4f08505 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c @@ -67,10 +67,10 @@ static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data) return exynos_dp_crtc_clock_enable(plat_data, false); } -static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data) +static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data, + struct drm_connector *connector) { struct exynos_dp_device *dp = to_dp(plat_data); - struct drm_connector *connector = dp->connector; struct drm_display_mode *mode; int num_modes = 0; diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index fc4aea3..261b86d 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -34,7 +34,8 @@ struct analogix_dp_plat_data { int (*power_off)(struct analogix_dp_plat_data *); int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *, struct drm_connector *); - int (*get_modes)(struct analogix_dp_plat_data *); + int (*get_modes)(struct analogix_dp_plat_data *, + struct drm_connector *); }; int analogix_dp_resume(struct device *dev); -- cgit v0.10.2 From db8a9aed10489d37e44ce4e1412e41f1c99ea28f Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:39 +0800 Subject: drm/rockchip: analogix_dp: correct the connector display color format and bpc Rockchip VOP couldn't output YUV video format for eDP controller, so when driver detect connector support YUV video format, we need to hack it down to RGB888. Signed-off-by: Yakir Yang Acked-by: Mark Yao Reviewed-by: Tomasz Figa Reviewed-by: Sean Paul diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 0755573..0a0fb3a 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -110,6 +110,23 @@ static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) return 0; } +static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data, + struct drm_connector *connector) +{ + struct drm_display_info *di = &connector->display_info; + /* VOP couldn't output YUV video format for eDP rightly */ + u32 mask = DRM_COLOR_FORMAT_YCRCB444 | DRM_COLOR_FORMAT_YCRCB422; + + if ((di->color_formats & mask)) { + DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n"); + di->color_formats &= ~mask; + di->color_formats |= DRM_COLOR_FORMAT_RGB444; + di->bpc = 8; + } + + return 0; +} + static bool rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, @@ -310,6 +327,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, dp->plat_data.dev_type = dp->data->chip_type; dp->plat_data.power_on = rockchip_dp_poweron; dp->plat_data.power_off = rockchip_dp_powerdown; + dp->plat_data.get_modes = rockchip_dp_get_modes; return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); } -- cgit v0.10.2 From d698f0eb9d0ebfff26a5a739a21164700d5dd58e Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:44 +0800 Subject: drm/rockchip: analogix_dp: update the comments about why need to hardcode VOP output mode The hardware IC designed that VOP must output the RGB10 video format to eDP contoller, and if eDP panel only support RGB8, then eDP contoller should cut down the video data, not via VOP contoller, that's why we need to hardcode the VOP output mode to RGA10 here. Signed-off-by: Yakir Yang Acked-by: Mark Yao Reviewed-by: Tomasz Figa Reviewed-by: Sean Paul diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 0a0fb3a..850edc4 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -182,17 +182,11 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, int ret; /* - * FIXME(Yakir): driver should configure the CRTC output video - * mode with the display information which indicated the monitor - * support colorimetry. - * - * But don't know why the CRTC driver seems could only output the - * RGBaaa rightly. For example, if connect the "innolux,n116bge" - * eDP screen, EDID would indicated that screen only accepted the - * 6bpc mode. But if I configure CRTC to RGB666 output, then eDP - * screen would show a blue picture (RGB888 show a green picture). - * But if I configure CTRC to RGBaaa, and eDP driver still keep - * RGB666 input video mode, then screen would works prefect. + * The hardware IC designed that VOP must output the RGB10 video + * format to eDP controller, and if eDP panel only support RGB8, + * then eDP controller should cut down the video data, not via VOP + * controller, that's why we need to hardcode the VOP output mode + * to RGA10 here. */ s->output_mode = ROCKCHIP_OUT_MODE_AAAA; -- cgit v0.10.2 From 7608a9fb37b02c5cce3199f87eafb0a6c07d6f93 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:15:47 +0800 Subject: drm/bridge: analogix_dp: fix no drm hpd event when panel plug in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The enum value of DP_IRQ_TYPE_HP_CABLE_IN is zero, but driver only send drm hp event when the irq_type and the enum value is true. if (irq_type & DP_IRQ_TYPE_HP_CABLE_IN || ...) drm_helper_hpd_irq_event(dp->drm_dev); So there would no drm hpd event when cable plug in, to fix that just need to assign all hotplug enum with no-zero values. Reported-by: Dan Carpenter Signed-off-by: Yakir Yang Reviewed-by: Sean Paul Reviewed-by: Stéphane Marchesin Reviewed-by: Tomasz Figa Tested-by: Javier Martinez Canillas diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index f09275d..b456380 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -127,10 +127,10 @@ enum analog_power_block { }; enum dp_irq_type { - DP_IRQ_TYPE_HP_CABLE_IN, - DP_IRQ_TYPE_HP_CABLE_OUT, - DP_IRQ_TYPE_HP_CHANGE, - DP_IRQ_TYPE_UNKNOWN, + DP_IRQ_TYPE_HP_CABLE_IN = BIT(0), + DP_IRQ_TYPE_HP_CABLE_OUT = BIT(1), + DP_IRQ_TYPE_HP_CHANGE = BIT(2), + DP_IRQ_TYPE_UNKNOWN = BIT(3), }; struct video_info { -- cgit v0.10.2 From dc1c93bef4690f7262bc10cf75a74564b477224d Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:16:05 +0800 Subject: drm/rockchip: analogix_dp: introduce the pclk for grf For RK3399's GRF module, if we want to operate the graphic related grf registers, we need to enable the pclk_vio_grf which supply power for VIO GRF IOs, so it's better to introduce an optional grf clock in driver. Signed-off-by: Yakir Yang Reviewed-by: Douglas Anderson Reviewed-by: Tomasz Figa diff --git a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt index 726c945..0b39256 100644 --- a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt @@ -28,6 +28,12 @@ Required properties: Port 0: contained 2 endpoints, connecting to the output of vop. Port 1: contained 1 endpoint, connecting to the input of panel. +Optional property for different chips: +- clocks: from common clock binding: handle to grf_vio clock. + +- clock-names: from common clock binding: + Required elements: "grf" + For the below properties, please refer to Analogix DP binding document: * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt - phys (required) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 850edc4..e81e19a 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -64,6 +64,7 @@ struct rockchip_dp_device { struct drm_display_mode mode; struct clk *pclk; + struct clk *grfclk; struct regmap *grf; struct reset_control *rst; @@ -160,11 +161,17 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder) dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG"); - ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val); - if (ret != 0) { - dev_err(dp->dev, "Could not write to GRF: %d\n", ret); + ret = clk_prepare_enable(dp->grfclk); + if (ret < 0) { + dev_err(dp->dev, "failed to enable grfclk %d\n", ret); return; } + + ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val); + if (ret != 0) + dev_err(dp->dev, "Could not write to GRF: %d\n", ret); + + clk_disable_unprepare(dp->grfclk); } static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder) @@ -234,6 +241,16 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp) return PTR_ERR(dp->grf); } + dp->grfclk = devm_clk_get(dev, "grf"); + if (PTR_ERR(dp->grfclk) == -ENOENT) { + dp->grfclk = NULL; + } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) { + return -EPROBE_DEFER; + } else if (IS_ERR(dp->grfclk)) { + dev_err(dev, "failed to get grf clock\n"); + return PTR_ERR(dp->grfclk); + } + dp->pclk = devm_clk_get(dev, "pclk"); if (IS_ERR(dp->pclk)) { dev_err(dev, "failed to get pclk property\n"); -- cgit v0.10.2 From 77b8d755b1ebca5caceb8f9f1371ca0124cdb0cf Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 29 Jun 2016 17:16:13 +0800 Subject: dt-bindings: analogix_dp: rockchip: correct the wrong compatible name The document about rockchip platform make a mistaken in available compatible name of "rk3288-edp", we should correct it to "rk3288-dp" which correspond to the compatible name in driver. This mistaken was introduced in commit be91c36247089 ("dt-bindings: add document for rockchip variant of analogix_dp"). Reported-by: Tomasz Figa Signed-off-by: Yakir Yang Reviewed-by: Douglas Anderson Reviewed-by: Tomasz Figa diff --git a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt index 0b39256..01cced1 100644 --- a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt @@ -2,7 +2,7 @@ Rockchip RK3288 specific extensions to the Analogix Display Port ================================ Required properties: -- compatible: "rockchip,rk3288-edp", +- compatible: "rockchip,rk3288-dp", "rockchip,rk3399-edp"; - reg: physical base address of the controller and length -- cgit v0.10.2