1186f8572SMark Yao /* 2186f8572SMark Yao * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 3186f8572SMark Yao * 4186f8572SMark Yao * SPDX-License-Identifier: GPL-2.0+ 5186f8572SMark Yao */ 6186f8572SMark Yao 7186f8572SMark Yao #include <config.h> 8186f8572SMark Yao #include <common.h> 9186f8572SMark Yao #include <errno.h> 10186f8572SMark Yao #include <dm/device.h> 119aa59efbSKever Yang #include <dm/read.h> 129aa59efbSKever Yang #include <dm/ofnode.h> 13cb17ca6cSSandy Huang #include <dm/of_access.h> 14186f8572SMark Yao #include <syscon.h> 15b69d3ed4SWyon Bi #include <regmap.h> 16b69d3ed4SWyon Bi #include <dm/device.h> 17b69d3ed4SWyon Bi #include <dm/read.h> 18b69d3ed4SWyon Bi #include <linux/media-bus-format.h> 19186f8572SMark Yao 20186f8572SMark Yao #include "rockchip_display.h" 21186f8572SMark Yao #include "rockchip_connector.h" 22b69d3ed4SWyon Bi #include "rockchip_phy.h" 231a8d717cSWyon Bi #include "rockchip_panel.h" 241953e619SWyon Bi 251953e619SWyon Bi #define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK(h, l) << 16)) 26186f8572SMark Yao 27b69d3ed4SWyon Bi #define PX30_GRF_PD_VO_CON1 0x0438 28b69d3ed4SWyon Bi #define PX30_LVDS_SELECT(x) HIWORD_UPDATE(x, 14, 13) 29b69d3ed4SWyon Bi #define PX30_LVDS_MODE_EN(x) HIWORD_UPDATE(x, 12, 12) 30b69d3ed4SWyon Bi #define PX30_LVDS_MSBSEL(x) HIWORD_UPDATE(x, 11, 11) 3131018a86SWyon Bi #define PX30_LVDS_P2S_EN(x) HIWORD_UPDATE(x, 6, 6) 32b69d3ed4SWyon Bi #define PX30_LVDS_VOP_SEL(x) HIWORD_UPDATE(x, 1, 1) 33b69d3ed4SWyon Bi 34b69d3ed4SWyon Bi #define RK3126_GRF_LVDS_CON0 0x0150 35b69d3ed4SWyon Bi #define RK3126_LVDS_P2S_EN(x) HIWORD_UPDATE(x, 9, 9) 36b69d3ed4SWyon Bi #define RK3126_LVDS_MODE_EN(x) HIWORD_UPDATE(x, 6, 6) 37b69d3ed4SWyon Bi #define RK3126_LVDS_MSBSEL(x) HIWORD_UPDATE(x, 3, 3) 38b69d3ed4SWyon Bi #define RK3126_LVDS_SELECT(x) HIWORD_UPDATE(x, 2, 1) 39b69d3ed4SWyon Bi 40b69d3ed4SWyon Bi #define RK3288_GRF_SOC_CON6 0x025c 41b69d3ed4SWyon Bi #define RK3288_LVDS_LCDC_SEL(x) HIWORD_UPDATE(x, 3, 3) 42b69d3ed4SWyon Bi #define RK3288_GRF_SOC_CON7 0x0260 43b69d3ed4SWyon Bi #define RK3288_LVDS_PWRDWN(x) HIWORD_UPDATE(x, 15, 15) 44b69d3ed4SWyon Bi #define RK3288_LVDS_CON_ENABLE_2(x) HIWORD_UPDATE(x, 12, 12) 45b69d3ed4SWyon Bi #define RK3288_LVDS_CON_ENABLE_1(x) HIWORD_UPDATE(x, 11, 11) 46b69d3ed4SWyon Bi #define RK3288_LVDS_CON_DEN_POL(x) HIWORD_UPDATE(x, 10, 10) 47b69d3ed4SWyon Bi #define RK3288_LVDS_CON_HS_POL(x) HIWORD_UPDATE(x, 9, 9) 48b69d3ed4SWyon Bi #define RK3288_LVDS_CON_CLKINV(x) HIWORD_UPDATE(x, 8, 8) 49b69d3ed4SWyon Bi #define RK3288_LVDS_CON_STARTPHASE(x) HIWORD_UPDATE(x, 7, 7) 50b69d3ed4SWyon Bi #define RK3288_LVDS_CON_TTL_EN(x) HIWORD_UPDATE(x, 6, 6) 51b69d3ed4SWyon Bi #define RK3288_LVDS_CON_STARTSEL(x) HIWORD_UPDATE(x, 5, 5) 52b69d3ed4SWyon Bi #define RK3288_LVDS_CON_CHASEL(x) HIWORD_UPDATE(x, 4, 4) 53b69d3ed4SWyon Bi #define RK3288_LVDS_CON_MSBSEL(x) HIWORD_UPDATE(x, 3, 3) 54b69d3ed4SWyon Bi #define RK3288_LVDS_CON_SELECT(x) HIWORD_UPDATE(x, 2, 0) 55b69d3ed4SWyon Bi 56b69d3ed4SWyon Bi #define RK3368_GRF_SOC_CON7 0x041c 57b69d3ed4SWyon Bi #define RK3368_LVDS_SELECT(x) HIWORD_UPDATE(x, 14, 13) 58b69d3ed4SWyon Bi #define RK3368_LVDS_MODE_EN(x) HIWORD_UPDATE(x, 12, 12) 59b69d3ed4SWyon Bi #define RK3368_LVDS_MSBSEL(x) HIWORD_UPDATE(x, 11, 11) 60b69d3ed4SWyon Bi #define RK3368_LVDS_P2S_EN(x) HIWORD_UPDATE(x, 6, 6) 61b69d3ed4SWyon Bi 62*cc341c3bSZhang Yubing #define RK3562_GRF_VO_CON0 0x05d0 63*cc341c3bSZhang Yubing #define RK3562_GRF_VO_CON1 0x05d4 64*cc341c3bSZhang Yubing 65aeb5dd22SSandy Huang #define RK3568_GRF_VO_CON0 0x0360 66aeb5dd22SSandy Huang #define RK3568_LVDS1_SELECT(x) HIWORD_UPDATE(x, 13, 12) 67aeb5dd22SSandy Huang #define RK3568_LVDS1_MSBSEL(x) HIWORD_UPDATE(x, 11, 11) 68aeb5dd22SSandy Huang #define RK3568_LVDS0_SELECT(x) HIWORD_UPDATE(x, 5, 4) 69aeb5dd22SSandy Huang #define RK3568_LVDS0_MSBSEL(x) HIWORD_UPDATE(x, 3, 3) 70aeb5dd22SSandy Huang #define RK3568_GRF_VO_CON2 0x0368 71aeb5dd22SSandy Huang #define RK3568_LVDS0_DCLK_INV_SEL(x) HIWORD_UPDATE(x, 9, 9) 72aeb5dd22SSandy Huang #define RK3568_LVDS0_DCLK_DIV2_SEL(x) HIWORD_UPDATE(x, 8, 8) 73aeb5dd22SSandy Huang #define RK3568_LVDS0_MODE_EN(x) HIWORD_UPDATE(x, 1, 1) 74aeb5dd22SSandy Huang #define RK3568_LVDS0_P2S_EN(x) HIWORD_UPDATE(x, 0, 0) 75aeb5dd22SSandy Huang #define RK3568_GRF_VO_CON3 0x036c 76aeb5dd22SSandy Huang #define RK3568_LVDS1_DCLK_INV_SEL(x) HIWORD_UPDATE(x, 9, 9) 77aeb5dd22SSandy Huang #define RK3568_LVDS1_DCLK_DIV2_SEL(x) HIWORD_UPDATE(x, 8, 8) 78aeb5dd22SSandy Huang #define RK3568_LVDS1_MODE_EN(x) HIWORD_UPDATE(x, 1, 1) 79aeb5dd22SSandy Huang #define RK3568_LVDS1_P2S_EN(x) HIWORD_UPDATE(x, 0, 0) 80aeb5dd22SSandy Huang 81b69d3ed4SWyon Bi enum lvds_format { 82b69d3ed4SWyon Bi LVDS_8BIT_MODE_FORMAT_1, 83b69d3ed4SWyon Bi LVDS_8BIT_MODE_FORMAT_2, 84b69d3ed4SWyon Bi LVDS_8BIT_MODE_FORMAT_3, 85b69d3ed4SWyon Bi LVDS_6BIT_MODE, 86e2721f29SGuochun Huang LVDS_10BIT_MODE_FORMAT_1, 87e2721f29SGuochun Huang LVDS_10BIT_MODE_FORMAT_2, 88186f8572SMark Yao }; 89186f8572SMark Yao 90b69d3ed4SWyon Bi struct rockchip_lvds; 91b69d3ed4SWyon Bi 92b69d3ed4SWyon Bi struct rockchip_lvds_funcs { 93b69d3ed4SWyon Bi void (*enable)(struct rockchip_lvds *lvds, int pipe); 94b69d3ed4SWyon Bi void (*disable)(struct rockchip_lvds *lvds); 95186f8572SMark Yao }; 96186f8572SMark Yao 97b69d3ed4SWyon Bi struct rockchip_lvds { 980594ce39SZhang Yubing struct rockchip_connector connector; 99cb17ca6cSSandy Huang int id; 100b69d3ed4SWyon Bi struct udevice *dev; 101b69d3ed4SWyon Bi struct regmap *grf; 102b69d3ed4SWyon Bi struct rockchip_phy *phy; 103b69d3ed4SWyon Bi const struct drm_display_mode *mode; 104b69d3ed4SWyon Bi const struct rockchip_lvds_funcs *funcs; 105b69d3ed4SWyon Bi enum lvds_format format; 106b69d3ed4SWyon Bi bool data_swap; 107b69d3ed4SWyon Bi bool dual_channel; 108186f8572SMark Yao }; 109186f8572SMark Yao 1100594ce39SZhang Yubing static int rockchip_lvds_connector_init(struct rockchip_connector *conn, 1110594ce39SZhang Yubing struct display_state *state) 112186f8572SMark Yao { 1130594ce39SZhang Yubing struct rockchip_lvds *lvds = dev_get_priv(conn->dev); 114186f8572SMark Yao struct connector_state *conn_state = &state->conn_state; 1150594ce39SZhang Yubing struct rockchip_panel *panel = conn->panel; 116186f8572SMark Yao 117b69d3ed4SWyon Bi lvds->mode = &conn_state->mode; 1180594ce39SZhang Yubing lvds->phy = conn->phy; 119cb17ca6cSSandy Huang conn_state->disp_info = rockchip_get_disp_info(conn_state->type, lvds->id); 120186f8572SMark Yao 121b69d3ed4SWyon Bi switch (panel->bus_format) { 1224888f8a4SWyon Bi case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: /* jeida-18 */ 123b69d3ed4SWyon Bi lvds->format = LVDS_6BIT_MODE; 124b69d3ed4SWyon Bi break; 125b69d3ed4SWyon Bi case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* jeida-24 */ 126b69d3ed4SWyon Bi lvds->format = LVDS_8BIT_MODE_FORMAT_2; 127b69d3ed4SWyon Bi break; 128e2721f29SGuochun Huang case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA: /* jeida-30 */ 129e2721f29SGuochun Huang lvds->format = LVDS_10BIT_MODE_FORMAT_1; 1304888f8a4SWyon Bi case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* vesa-18 */ 1314888f8a4SWyon Bi lvds->format = LVDS_8BIT_MODE_FORMAT_3; 1324888f8a4SWyon Bi break; 133e2721f29SGuochun Huang case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG: /* vesa-30 */ 134e2721f29SGuochun Huang lvds->format = LVDS_10BIT_MODE_FORMAT_2; 135e2721f29SGuochun Huang break; 136b69d3ed4SWyon Bi case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* vesa-24 */ 137b69d3ed4SWyon Bi default: 138b69d3ed4SWyon Bi lvds->format = LVDS_8BIT_MODE_FORMAT_1; 139b69d3ed4SWyon Bi break; 140186f8572SMark Yao } 141186f8572SMark Yao 142186f8572SMark Yao conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 143e2721f29SGuochun Huang 144e2721f29SGuochun Huang if ((lvds->format == LVDS_10BIT_MODE_FORMAT_1) || 145e2721f29SGuochun Huang (lvds->format == LVDS_10BIT_MODE_FORMAT_2)) 146e2721f29SGuochun Huang conn_state->output_mode = ROCKCHIP_OUT_MODE_AAAA; 147e2721f29SGuochun Huang 14879feefb1SSandy Huang conn_state->color_space = V4L2_COLORSPACE_DEFAULT; 149aeb5dd22SSandy Huang conn_state->output_if = VOP_OUTPUT_IF_LVDS0; 150186f8572SMark Yao 151186f8572SMark Yao return 0; 152186f8572SMark Yao } 153186f8572SMark Yao 1540594ce39SZhang Yubing static int rockchip_lvds_connector_enable(struct rockchip_connector *conn, 1550594ce39SZhang Yubing struct display_state *state) 156186f8572SMark Yao { 1570594ce39SZhang Yubing struct rockchip_lvds *lvds = dev_get_priv(conn->dev); 158b69d3ed4SWyon Bi struct crtc_state *crtc_state = &state->crtc_state; 159b69d3ed4SWyon Bi int pipe = crtc_state->crtc_id; 160b69d3ed4SWyon Bi int ret; 161186f8572SMark Yao 162b69d3ed4SWyon Bi if (lvds->funcs->enable) 163b69d3ed4SWyon Bi lvds->funcs->enable(lvds, pipe); 164b69d3ed4SWyon Bi 1659e3ffb10SGuochun Huang ret = rockchip_phy_set_mode(lvds->phy, PHY_MODE_VIDEO_LVDS); 166b69d3ed4SWyon Bi if (ret) { 167b69d3ed4SWyon Bi dev_err(lvds->dev, "failed to set phy mode: %d\n", ret); 168b69d3ed4SWyon Bi return ret; 169186f8572SMark Yao } 170186f8572SMark Yao 171b69d3ed4SWyon Bi rockchip_phy_power_on(lvds->phy); 172186f8572SMark Yao 173186f8572SMark Yao return 0; 174186f8572SMark Yao } 175186f8572SMark Yao 1760594ce39SZhang Yubing static int rockchip_lvds_connector_disable(struct rockchip_connector *conn, 1770594ce39SZhang Yubing struct display_state *state) 178186f8572SMark Yao { 1790594ce39SZhang Yubing struct rockchip_lvds *lvds = dev_get_priv(conn->dev); 180b69d3ed4SWyon Bi 181b69d3ed4SWyon Bi rockchip_phy_power_off(lvds->phy); 182b69d3ed4SWyon Bi 183b69d3ed4SWyon Bi if (lvds->funcs->disable) 184b69d3ed4SWyon Bi lvds->funcs->disable(lvds); 185b69d3ed4SWyon Bi 186b69d3ed4SWyon Bi return 0; 187b69d3ed4SWyon Bi } 188b69d3ed4SWyon Bi 189b69d3ed4SWyon Bi static const struct rockchip_connector_funcs rockchip_lvds_connector_funcs = { 190b69d3ed4SWyon Bi .init = rockchip_lvds_connector_init, 191b69d3ed4SWyon Bi .enable = rockchip_lvds_connector_enable, 192b69d3ed4SWyon Bi .disable = rockchip_lvds_connector_disable, 193b69d3ed4SWyon Bi }; 194b69d3ed4SWyon Bi 195b69d3ed4SWyon Bi static int rockchip_lvds_probe(struct udevice *dev) 196b69d3ed4SWyon Bi { 197b69d3ed4SWyon Bi struct rockchip_lvds *lvds = dev_get_priv(dev); 198b69d3ed4SWyon Bi 199b69d3ed4SWyon Bi lvds->dev = dev; 2000594ce39SZhang Yubing lvds->funcs = (const struct rockchip_lvds_funcs *)dev_get_driver_data(dev); 201b69d3ed4SWyon Bi lvds->grf = syscon_get_regmap(dev_get_parent(dev)); 202b69d3ed4SWyon Bi lvds->dual_channel = dev_read_bool(dev, "dual-channel"); 203b69d3ed4SWyon Bi lvds->data_swap = dev_read_bool(dev, "rockchip,data-swap"); 204cb17ca6cSSandy Huang lvds->id = of_alias_get_id(ofnode_to_np(dev->node), "lvds"); 205cb17ca6cSSandy Huang if (lvds->id < 0) 206cb17ca6cSSandy Huang lvds->id = 0; 207b69d3ed4SWyon Bi 2080594ce39SZhang Yubing rockchip_connector_bind(&lvds->connector, dev, lvds->id, &rockchip_lvds_connector_funcs, 2090594ce39SZhang Yubing NULL, DRM_MODE_CONNECTOR_LVDS); 2100594ce39SZhang Yubing 211b69d3ed4SWyon Bi return 0; 212b69d3ed4SWyon Bi } 213b69d3ed4SWyon Bi 214b69d3ed4SWyon Bi static void px30_lvds_enable(struct rockchip_lvds *lvds, int pipe) 215b69d3ed4SWyon Bi { 216b69d3ed4SWyon Bi regmap_write(lvds->grf, PX30_GRF_PD_VO_CON1, 217b69d3ed4SWyon Bi PX30_LVDS_SELECT(lvds->format) | 218b69d3ed4SWyon Bi PX30_LVDS_MODE_EN(1) | PX30_LVDS_MSBSEL(1) | 219b69d3ed4SWyon Bi PX30_LVDS_P2S_EN(1) | PX30_LVDS_VOP_SEL(pipe)); 220b69d3ed4SWyon Bi } 221b69d3ed4SWyon Bi 222b69d3ed4SWyon Bi static void px30_lvds_disable(struct rockchip_lvds *lvds) 223b69d3ed4SWyon Bi { 224b69d3ed4SWyon Bi regmap_write(lvds->grf, PX30_GRF_PD_VO_CON1, 225b69d3ed4SWyon Bi PX30_LVDS_MODE_EN(0) | PX30_LVDS_P2S_EN(0)); 226b69d3ed4SWyon Bi } 227b69d3ed4SWyon Bi 228b69d3ed4SWyon Bi static const struct rockchip_lvds_funcs px30_lvds_funcs = { 229b69d3ed4SWyon Bi .enable = px30_lvds_enable, 230b69d3ed4SWyon Bi .disable = px30_lvds_disable, 231b69d3ed4SWyon Bi }; 232b69d3ed4SWyon Bi 233b69d3ed4SWyon Bi static void rk3126_lvds_enable(struct rockchip_lvds *lvds, int pipe) 234b69d3ed4SWyon Bi { 235b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3126_GRF_LVDS_CON0, 236b69d3ed4SWyon Bi RK3126_LVDS_P2S_EN(1) | RK3126_LVDS_MODE_EN(1) | 237b69d3ed4SWyon Bi RK3126_LVDS_MSBSEL(1) | RK3126_LVDS_SELECT(lvds->format)); 238b69d3ed4SWyon Bi } 239b69d3ed4SWyon Bi 240b69d3ed4SWyon Bi static void rk3126_lvds_disable(struct rockchip_lvds *lvds) 241b69d3ed4SWyon Bi { 242b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3126_GRF_LVDS_CON0, 243b69d3ed4SWyon Bi RK3126_LVDS_P2S_EN(0) | RK3126_LVDS_MODE_EN(0)); 244b69d3ed4SWyon Bi } 245b69d3ed4SWyon Bi 246b69d3ed4SWyon Bi static const struct rockchip_lvds_funcs rk3126_lvds_funcs = { 247b69d3ed4SWyon Bi .enable = rk3126_lvds_enable, 248b69d3ed4SWyon Bi .disable = rk3126_lvds_disable, 249b69d3ed4SWyon Bi }; 250b69d3ed4SWyon Bi 251b69d3ed4SWyon Bi static void rk3288_lvds_enable(struct rockchip_lvds *lvds, int pipe) 252b69d3ed4SWyon Bi { 253b69d3ed4SWyon Bi const struct drm_display_mode *mode = lvds->mode; 254186f8572SMark Yao u32 val; 255186f8572SMark Yao 256b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3288_GRF_SOC_CON6, 257b69d3ed4SWyon Bi RK3288_LVDS_LCDC_SEL(pipe)); 258b69d3ed4SWyon Bi 259b69d3ed4SWyon Bi val = RK3288_LVDS_PWRDWN(0) | RK3288_LVDS_CON_CLKINV(0) | 260b69d3ed4SWyon Bi RK3288_LVDS_CON_CHASEL(lvds->dual_channel) | 261b69d3ed4SWyon Bi RK3288_LVDS_CON_SELECT(lvds->format); 262b69d3ed4SWyon Bi 263b69d3ed4SWyon Bi if (lvds->dual_channel) { 264b69d3ed4SWyon Bi u32 h_bp = mode->htotal - mode->hsync_start; 265b69d3ed4SWyon Bi 266b69d3ed4SWyon Bi val |= RK3288_LVDS_CON_ENABLE_2(1) | 267b69d3ed4SWyon Bi RK3288_LVDS_CON_ENABLE_1(1) | 268b69d3ed4SWyon Bi RK3288_LVDS_CON_STARTSEL(lvds->data_swap); 269b69d3ed4SWyon Bi 270b69d3ed4SWyon Bi if (h_bp % 2) 271b69d3ed4SWyon Bi val |= RK3288_LVDS_CON_STARTPHASE(1); 272186f8572SMark Yao else 273b69d3ed4SWyon Bi val |= RK3288_LVDS_CON_STARTPHASE(0); 274186f8572SMark Yao } else { 275b69d3ed4SWyon Bi val |= RK3288_LVDS_CON_ENABLE_2(0) | 276b69d3ed4SWyon Bi RK3288_LVDS_CON_ENABLE_1(1); 277186f8572SMark Yao } 278186f8572SMark Yao 279b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, val); 280b69d3ed4SWyon Bi 281b69d3ed4SWyon Bi rockchip_phy_set_bus_width(lvds->phy, lvds->dual_channel ? 2 : 1); 282186f8572SMark Yao } 283186f8572SMark Yao 284b69d3ed4SWyon Bi static void rk3288_lvds_disable(struct rockchip_lvds *lvds) 285186f8572SMark Yao { 286b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, RK3288_LVDS_PWRDWN(1)); 287186f8572SMark Yao } 288186f8572SMark Yao 289b69d3ed4SWyon Bi static const struct rockchip_lvds_funcs rk3288_lvds_funcs = { 290b69d3ed4SWyon Bi .enable = rk3288_lvds_enable, 291b69d3ed4SWyon Bi .disable = rk3288_lvds_disable, 292186f8572SMark Yao }; 293186f8572SMark Yao 294b69d3ed4SWyon Bi static void rk3368_lvds_enable(struct rockchip_lvds *lvds, int pipe) 295b69d3ed4SWyon Bi { 296b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3368_GRF_SOC_CON7, 297b69d3ed4SWyon Bi RK3368_LVDS_SELECT(lvds->format) | 298b69d3ed4SWyon Bi RK3368_LVDS_MODE_EN(1) | RK3368_LVDS_MSBSEL(1) | 299b69d3ed4SWyon Bi RK3368_LVDS_P2S_EN(1)); 300b69d3ed4SWyon Bi } 301b69d3ed4SWyon Bi 302b69d3ed4SWyon Bi static void rk3368_lvds_disable(struct rockchip_lvds *lvds) 303b69d3ed4SWyon Bi { 304b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3368_GRF_SOC_CON7, 305b69d3ed4SWyon Bi RK3368_LVDS_MODE_EN(0) | RK3368_LVDS_P2S_EN(0)); 306b69d3ed4SWyon Bi } 307b69d3ed4SWyon Bi 308b69d3ed4SWyon Bi static const struct rockchip_lvds_funcs rk3368_lvds_funcs = { 309b69d3ed4SWyon Bi .enable = rk3368_lvds_enable, 310b69d3ed4SWyon Bi .disable = rk3368_lvds_disable, 31130d6d433SWyon Bi }; 31230d6d433SWyon Bi 313*cc341c3bSZhang Yubing static void rk3562_lvds_enable(struct rockchip_lvds *lvds, int pipe) 314*cc341c3bSZhang Yubing { 315*cc341c3bSZhang Yubing regmap_write(lvds->grf, RK3562_GRF_VO_CON1, 316*cc341c3bSZhang Yubing RK3568_LVDS0_MODE_EN(1) | RK3568_LVDS0_P2S_EN(1) | 317*cc341c3bSZhang Yubing RK3568_LVDS0_DCLK_INV_SEL(1)); 318*cc341c3bSZhang Yubing regmap_write(lvds->grf, RK3562_GRF_VO_CON0, 319*cc341c3bSZhang Yubing RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1)); 320*cc341c3bSZhang Yubing } 321*cc341c3bSZhang Yubing 322*cc341c3bSZhang Yubing static void rk3562_lvds_disable(struct rockchip_lvds *lvds) 323*cc341c3bSZhang Yubing { 324*cc341c3bSZhang Yubing regmap_write(lvds->grf, RK3562_GRF_VO_CON1, RK3568_LVDS0_MODE_EN(0)); 325*cc341c3bSZhang Yubing } 326*cc341c3bSZhang Yubing 327*cc341c3bSZhang Yubing static const struct rockchip_lvds_funcs rk3562_lvds_funcs = { 328*cc341c3bSZhang Yubing .enable = rk3562_lvds_enable, 329*cc341c3bSZhang Yubing .disable = rk3562_lvds_disable, 330*cc341c3bSZhang Yubing }; 331*cc341c3bSZhang Yubing 332aeb5dd22SSandy Huang static void rk3568_lvds_enable(struct rockchip_lvds *lvds, int pipe) 333aeb5dd22SSandy Huang { 334aeb5dd22SSandy Huang regmap_write(lvds->grf, RK3568_GRF_VO_CON2, 335aeb5dd22SSandy Huang RK3568_LVDS0_MODE_EN(1) | RK3568_LVDS0_P2S_EN(1) | 336aeb5dd22SSandy Huang RK3568_LVDS0_DCLK_INV_SEL(1)); 337aeb5dd22SSandy Huang regmap_write(lvds->grf, RK3568_GRF_VO_CON0, 338aeb5dd22SSandy Huang RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1)); 339aeb5dd22SSandy Huang } 340aeb5dd22SSandy Huang 341aeb5dd22SSandy Huang static void rk3568_lvds_disable(struct rockchip_lvds *lvds) 342aeb5dd22SSandy Huang { 343aeb5dd22SSandy Huang regmap_write(lvds->grf, RK3568_GRF_VO_CON2, RK3568_LVDS0_MODE_EN(0)); 344aeb5dd22SSandy Huang } 345aeb5dd22SSandy Huang 346aeb5dd22SSandy Huang static const struct rockchip_lvds_funcs rk3568_lvds_funcs = { 347aeb5dd22SSandy Huang .enable = rk3568_lvds_enable, 348aeb5dd22SSandy Huang .disable = rk3568_lvds_disable, 349aeb5dd22SSandy Huang }; 350aeb5dd22SSandy Huang 351186f8572SMark Yao static const struct udevice_id rockchip_lvds_ids[] = { 352186f8572SMark Yao { 35330d6d433SWyon Bi .compatible = "rockchip,px30-lvds", 3540594ce39SZhang Yubing .data = (ulong)&px30_lvds_funcs, 35530d6d433SWyon Bi }, 35630d6d433SWyon Bi { 35730d6d433SWyon Bi .compatible = "rockchip,rk3126-lvds", 3580594ce39SZhang Yubing .data = (ulong)&rk3126_lvds_funcs, 35930d6d433SWyon Bi }, 36030d6d433SWyon Bi { 36130d6d433SWyon Bi .compatible = "rockchip,rk3288-lvds", 3620594ce39SZhang Yubing .data = (ulong)&rk3288_lvds_funcs, 36330d6d433SWyon Bi }, 36430d6d433SWyon Bi { 365186f8572SMark Yao .compatible = "rockchip,rk3368-lvds", 3660594ce39SZhang Yubing .data = (ulong)&rk3368_lvds_funcs, 36730d6d433SWyon Bi }, 368aeb5dd22SSandy Huang { 369*cc341c3bSZhang Yubing .compatible = "rockchip,rk3562-lvds", 370*cc341c3bSZhang Yubing .data = (ulong)&rk3562_lvds_funcs, 371*cc341c3bSZhang Yubing }, 372*cc341c3bSZhang Yubing { 373aeb5dd22SSandy Huang .compatible = "rockchip,rk3568-lvds", 3740594ce39SZhang Yubing .data = (ulong)&rk3568_lvds_funcs, 375aeb5dd22SSandy Huang }, 37630d6d433SWyon Bi {} 377186f8572SMark Yao }; 378186f8572SMark Yao 379186f8572SMark Yao U_BOOT_DRIVER(rockchip_lvds) = { 380186f8572SMark Yao .name = "rockchip_lvds", 381186f8572SMark Yao .id = UCLASS_DISPLAY, 382186f8572SMark Yao .of_match = rockchip_lvds_ids, 383b69d3ed4SWyon Bi .probe = rockchip_lvds_probe, 384b69d3ed4SWyon Bi .priv_auto_alloc_size = sizeof(struct rockchip_lvds), 385186f8572SMark Yao }; 386