From eafd8e2fb2abe9b7ed2b259a8fb3779a571471d1 Mon Sep 17 00:00:00 2001 From: Wyon Bi Date: Mon, 13 Aug 2018 08:59:24 +0800 Subject: [PATCH] drm/rockchip: rgb: Add support for RK1808 Change-Id: I60d99dea417b2708ffb2c784a0d26313e7d20fdb Signed-off-by: Wyon Bi --- .../display/rockchip/rockchip-rgb.txt | 3 +- drivers/gpu/drm/rockchip/rockchip_rgb.c | 116 +++++++++++------- 2 files changed, 76 insertions(+), 43 deletions(-) diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-rgb.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-rgb.txt index cb3e490a43f2..372b25596dec 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-rgb.txt +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-rgb.txt @@ -4,9 +4,10 @@ Rockchip RGB interface Required properties: - compatible: matching the soc type: - "rockchip,px30-rgb"; - - "rockchip,rv1108-rgb"; + - "rockchip,rk1808-rgb"; - "rockchip,rk3066-rgb"; - "rockchip,rk3308-rgb"; + - "rockchip,rv1108-rgb"; Optional properties: - pinctrl-names: the pin control state names; should contain "default" diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c index 0d47fa21234a..b5a82897d95e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -29,14 +30,24 @@ #include "rockchip_drm_vop.h" #define HIWORD_UPDATE(v, l, h) (((v) << (l)) | (GENMASK(h, l) << 16)) -#define PX30_GRF_PD_VO_CON1 0x0438 -#define PX30_LCDC_DCLK_INV(v) HIWORD_UPDATE(v, 4, 4) -#define PX30_RGB_SYNC_BYPASS(v) HIWORD_UPDATE(v, 3, 3) -#define PX30_RGB_VOP_SEL(v) HIWORD_UPDATE(v, 2, 2) + +#define PX30_GRF_PD_VO_CON1 0x0438 +#define PX30_RGB_DATA_SYNC_BYPASS(v) HIWORD_UPDATE(v, 3, 3) +#define PX30_RGB_VOP_SEL(v) HIWORD_UPDATE(v, 2, 2) + +#define RK1808_GRF_PD_VO_CON1 0x0444 +#define RK1808_RGB_DATA_SYNC_BYPASS(v) HIWORD_UPDATE(v, 3, 3) #define connector_to_rgb(c) container_of(c, struct rockchip_rgb, connector) #define encoder_to_rgb(c) container_of(c, struct rockchip_rgb, encoder) +struct rockchip_rgb; + +struct rockchip_rgb_funcs { + void (*enable)(struct rockchip_rgb *rgb); + void (*disable)(struct rockchip_rgb *rgb); +}; + struct rockchip_rgb { struct device *dev; struct drm_device *drm_dev; @@ -46,6 +57,7 @@ struct rockchip_rgb { struct drm_encoder encoder; int output_mode; struct regmap *grf; + const struct rockchip_rgb_funcs *funcs; }; static inline int name_to_output_mode(const char *s) @@ -60,7 +72,7 @@ static inline int name_to_output_mode(const char *s) { "s888", ROCKCHIP_OUT_MODE_S888 }, { "s888_dummy", ROCKCHIP_OUT_MODE_S888_DUMMY } }; - int i; + unsigned int i; for (i = 0; i < ARRAY_SIZE(formats); i++) if (!strncmp(s, formats[i].name, strlen(formats[i].name))) @@ -113,14 +125,8 @@ static void rockchip_rgb_encoder_enable(struct drm_encoder *encoder) pinctrl_pm_select_default_state(rgb->dev); - if (rgb->grf) { - int pipe = drm_of_encoder_active_endpoint_id(rgb->dev->of_node, - encoder); - regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, - PX30_RGB_VOP_SEL(pipe)); - regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, - PX30_RGB_SYNC_BYPASS(1)); - } + if (rgb->funcs && rgb->funcs->enable) + rgb->funcs->enable(rgb); drm_panel_prepare(rgb->panel); drm_panel_enable(rgb->panel); @@ -133,6 +139,9 @@ static void rockchip_rgb_encoder_disable(struct drm_encoder *encoder) drm_panel_disable(rgb->panel); drm_panel_unprepare(rgb->panel); + if (rgb->funcs && rgb->funcs->disable) + rgb->funcs->disable(rgb); + pinctrl_pm_select_sleep_state(rgb->dev); } @@ -175,21 +184,6 @@ static const struct drm_encoder_funcs rockchip_rgb_encoder_funcs = { .destroy = drm_encoder_cleanup, }; -static const struct of_device_id rockchip_rgb_dt_ids[] = { - { - .compatible = "rockchip,px30-rgb", - }, { - .compatible = "rockchip,rv1108-rgb", - }, { - .compatible = "rockchip,rk3066-rgb", - }, { - .compatible = "rockchip,rk3308-rgb", - }, - {} -}; - -MODULE_DEVICE_TABLE(of, rockchip_rgb_dt_ids); - static int rockchip_rgb_bind(struct device *dev, struct device *master, void *data) { @@ -337,24 +331,14 @@ static int rockchip_rgb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rockchip_rgb *rgb; - const struct of_device_id *match; int ret; - if (!dev->of_node) { - DRM_DEV_ERROR(dev, "dev->of_node is null\n"); - return -ENODEV; - } - rgb = devm_kzalloc(&pdev->dev, sizeof(*rgb), GFP_KERNEL); if (!rgb) return -ENOMEM; rgb->dev = dev; - match = of_match_node(rockchip_rgb_dt_ids, dev->of_node); - if (!match) { - DRM_DEV_ERROR(dev, "match node failed\n"); - return -ENODEV; - } + rgb->funcs = of_device_get_match_data(dev); if (dev->parent && dev->parent->of_node) { rgb->grf = syscon_node_to_regmap(dev->parent->of_node); @@ -380,12 +364,60 @@ static int rockchip_rgb_remove(struct platform_device *pdev) return 0; } -struct platform_driver rockchip_rgb_driver = { +static void px30_rgb_enable(struct rockchip_rgb *rgb) +{ + int pipe = drm_of_encoder_active_endpoint_id(rgb->dev->of_node, + &rgb->encoder); + + regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, PX30_RGB_VOP_SEL(pipe)); + regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, + PX30_RGB_DATA_SYNC_BYPASS(1)); +} + +static void px30_rgb_disable(struct rockchip_rgb *rgb) +{ + regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, + PX30_RGB_DATA_SYNC_BYPASS(0)); +} + +static const struct rockchip_rgb_funcs px30_rgb_funcs = { + .enable = px30_rgb_enable, + .disable = px30_rgb_disable, +}; + +static void rk1808_rgb_enable(struct rockchip_rgb *rgb) +{ + regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1, + RK1808_RGB_DATA_SYNC_BYPASS(1)); +} + +static void rk1808_rgb_disable(struct rockchip_rgb *rgb) +{ + regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, + RK1808_RGB_DATA_SYNC_BYPASS(0)); +} + +static const struct rockchip_rgb_funcs rk1808_rgb_funcs = { + .enable = rk1808_rgb_enable, + .disable = rk1808_rgb_disable, +}; + +static const struct of_device_id rockchip_rgb_dt_ids[] = { + { .compatible = "rockchip,px30-rgb", .data = &px30_rgb_funcs }, + { .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb_funcs }, + { .compatible = "rockchip,rk3066-rgb", }, + { .compatible = "rockchip,rk3308-rgb", }, + { .compatible = "rockchip,rv1108-rgb", }, + {} +}; +MODULE_DEVICE_TABLE(of, rockchip_rgb_dt_ids); + +static struct platform_driver rockchip_rgb_driver = { .probe = rockchip_rgb_probe, .remove = rockchip_rgb_remove, .driver = { - .name = "rockchip-rgb", - .of_match_table = of_match_ptr(rockchip_rgb_dt_ids), + .name = "rockchip-rgb", + .of_match_table = of_match_ptr(rockchip_rgb_dt_ids), }, };