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> 13*cb17ca6cSSandy 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 62aeb5dd22SSandy Huang #define RK3568_GRF_VO_CON0 0x0360 63aeb5dd22SSandy Huang #define RK3568_LVDS1_SELECT(x) HIWORD_UPDATE(x, 13, 12) 64aeb5dd22SSandy Huang #define RK3568_LVDS1_MSBSEL(x) HIWORD_UPDATE(x, 11, 11) 65aeb5dd22SSandy Huang #define RK3568_LVDS0_SELECT(x) HIWORD_UPDATE(x, 5, 4) 66aeb5dd22SSandy Huang #define RK3568_LVDS0_MSBSEL(x) HIWORD_UPDATE(x, 3, 3) 67aeb5dd22SSandy Huang #define RK3568_GRF_VO_CON2 0x0368 68aeb5dd22SSandy Huang #define RK3568_LVDS0_DCLK_INV_SEL(x) HIWORD_UPDATE(x, 9, 9) 69aeb5dd22SSandy Huang #define RK3568_LVDS0_DCLK_DIV2_SEL(x) HIWORD_UPDATE(x, 8, 8) 70aeb5dd22SSandy Huang #define RK3568_LVDS0_MODE_EN(x) HIWORD_UPDATE(x, 1, 1) 71aeb5dd22SSandy Huang #define RK3568_LVDS0_P2S_EN(x) HIWORD_UPDATE(x, 0, 0) 72aeb5dd22SSandy Huang #define RK3568_GRF_VO_CON3 0x036c 73aeb5dd22SSandy Huang #define RK3568_LVDS1_DCLK_INV_SEL(x) HIWORD_UPDATE(x, 9, 9) 74aeb5dd22SSandy Huang #define RK3568_LVDS1_DCLK_DIV2_SEL(x) HIWORD_UPDATE(x, 8, 8) 75aeb5dd22SSandy Huang #define RK3568_LVDS1_MODE_EN(x) HIWORD_UPDATE(x, 1, 1) 76aeb5dd22SSandy Huang #define RK3568_LVDS1_P2S_EN(x) HIWORD_UPDATE(x, 0, 0) 77aeb5dd22SSandy Huang 78b69d3ed4SWyon Bi enum lvds_format { 79b69d3ed4SWyon Bi LVDS_8BIT_MODE_FORMAT_1, 80b69d3ed4SWyon Bi LVDS_8BIT_MODE_FORMAT_2, 81b69d3ed4SWyon Bi LVDS_8BIT_MODE_FORMAT_3, 82b69d3ed4SWyon Bi LVDS_6BIT_MODE, 83e2721f29SGuochun Huang LVDS_10BIT_MODE_FORMAT_1, 84e2721f29SGuochun Huang LVDS_10BIT_MODE_FORMAT_2, 85186f8572SMark Yao }; 86186f8572SMark Yao 87b69d3ed4SWyon Bi struct rockchip_lvds; 88b69d3ed4SWyon Bi 89b69d3ed4SWyon Bi struct rockchip_lvds_funcs { 90b69d3ed4SWyon Bi void (*enable)(struct rockchip_lvds *lvds, int pipe); 91b69d3ed4SWyon Bi void (*disable)(struct rockchip_lvds *lvds); 92186f8572SMark Yao }; 93186f8572SMark Yao 94b69d3ed4SWyon Bi struct rockchip_lvds { 95*cb17ca6cSSandy Huang int id; 96b69d3ed4SWyon Bi struct udevice *dev; 97b69d3ed4SWyon Bi struct regmap *grf; 98b69d3ed4SWyon Bi struct rockchip_phy *phy; 99b69d3ed4SWyon Bi const struct drm_display_mode *mode; 100b69d3ed4SWyon Bi const struct rockchip_lvds_funcs *funcs; 101b69d3ed4SWyon Bi enum lvds_format format; 102b69d3ed4SWyon Bi bool data_swap; 103b69d3ed4SWyon Bi bool dual_channel; 104186f8572SMark Yao }; 105186f8572SMark Yao 106b69d3ed4SWyon Bi static inline struct rockchip_lvds *state_to_lvds(struct display_state *state) 107186f8572SMark Yao { 108186f8572SMark Yao struct connector_state *conn_state = &state->conn_state; 109186f8572SMark Yao 110b69d3ed4SWyon Bi return dev_get_priv(conn_state->dev); 111186f8572SMark Yao } 112186f8572SMark Yao 11358c17f51SSandy Huang static int rockchip_lvds_connector_pre_init(struct display_state *state) 11458c17f51SSandy Huang { 11558c17f51SSandy Huang struct connector_state *conn_state = &state->conn_state; 11658c17f51SSandy Huang 11758c17f51SSandy Huang conn_state->type = DRM_MODE_CONNECTOR_LVDS; 11858c17f51SSandy Huang 11958c17f51SSandy Huang return 0; 12058c17f51SSandy Huang } 12158c17f51SSandy Huang 122b69d3ed4SWyon Bi static int rockchip_lvds_connector_init(struct display_state *state) 123186f8572SMark Yao { 124b69d3ed4SWyon Bi struct rockchip_lvds *lvds = state_to_lvds(state); 125186f8572SMark Yao struct connector_state *conn_state = &state->conn_state; 1261a8d717cSWyon Bi struct rockchip_panel *panel = state_get_panel(state); 127186f8572SMark Yao 128b69d3ed4SWyon Bi lvds->mode = &conn_state->mode; 129b69d3ed4SWyon Bi lvds->phy = conn_state->phy; 130*cb17ca6cSSandy Huang conn_state->disp_info = rockchip_get_disp_info(conn_state->type, lvds->id); 131186f8572SMark Yao 132b69d3ed4SWyon Bi switch (panel->bus_format) { 1334888f8a4SWyon Bi case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: /* jeida-18 */ 134b69d3ed4SWyon Bi lvds->format = LVDS_6BIT_MODE; 135b69d3ed4SWyon Bi break; 136b69d3ed4SWyon Bi case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* jeida-24 */ 137b69d3ed4SWyon Bi lvds->format = LVDS_8BIT_MODE_FORMAT_2; 138b69d3ed4SWyon Bi break; 139e2721f29SGuochun Huang case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA: /* jeida-30 */ 140e2721f29SGuochun Huang lvds->format = LVDS_10BIT_MODE_FORMAT_1; 1414888f8a4SWyon Bi case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* vesa-18 */ 1424888f8a4SWyon Bi lvds->format = LVDS_8BIT_MODE_FORMAT_3; 1434888f8a4SWyon Bi break; 144e2721f29SGuochun Huang case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG: /* vesa-30 */ 145e2721f29SGuochun Huang lvds->format = LVDS_10BIT_MODE_FORMAT_2; 146e2721f29SGuochun Huang break; 147b69d3ed4SWyon Bi case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* vesa-24 */ 148b69d3ed4SWyon Bi default: 149b69d3ed4SWyon Bi lvds->format = LVDS_8BIT_MODE_FORMAT_1; 150b69d3ed4SWyon Bi break; 151186f8572SMark Yao } 152186f8572SMark Yao 153186f8572SMark Yao conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 154e2721f29SGuochun Huang 155e2721f29SGuochun Huang if ((lvds->format == LVDS_10BIT_MODE_FORMAT_1) || 156e2721f29SGuochun Huang (lvds->format == LVDS_10BIT_MODE_FORMAT_2)) 157e2721f29SGuochun Huang conn_state->output_mode = ROCKCHIP_OUT_MODE_AAAA; 158e2721f29SGuochun Huang 15979feefb1SSandy Huang conn_state->color_space = V4L2_COLORSPACE_DEFAULT; 160aeb5dd22SSandy Huang conn_state->output_if = VOP_OUTPUT_IF_LVDS0; 161186f8572SMark Yao 162186f8572SMark Yao return 0; 163186f8572SMark Yao } 164186f8572SMark Yao 165b69d3ed4SWyon Bi static int rockchip_lvds_connector_enable(struct display_state *state) 166186f8572SMark Yao { 167b69d3ed4SWyon Bi struct rockchip_lvds *lvds = state_to_lvds(state); 168b69d3ed4SWyon Bi struct crtc_state *crtc_state = &state->crtc_state; 169b69d3ed4SWyon Bi int pipe = crtc_state->crtc_id; 170b69d3ed4SWyon Bi int ret; 171186f8572SMark Yao 172b69d3ed4SWyon Bi if (lvds->funcs->enable) 173b69d3ed4SWyon Bi lvds->funcs->enable(lvds, pipe); 174b69d3ed4SWyon Bi 175b69d3ed4SWyon Bi ret = rockchip_phy_set_mode(lvds->phy, PHY_MODE_VIDEO_LVDS); 176b69d3ed4SWyon Bi if (ret) { 177b69d3ed4SWyon Bi dev_err(lvds->dev, "failed to set phy mode: %d\n", ret); 178b69d3ed4SWyon Bi return ret; 179186f8572SMark Yao } 180186f8572SMark Yao 181b69d3ed4SWyon Bi rockchip_phy_power_on(lvds->phy); 182186f8572SMark Yao 183186f8572SMark Yao return 0; 184186f8572SMark Yao } 185186f8572SMark Yao 186b69d3ed4SWyon Bi static int rockchip_lvds_connector_disable(struct display_state *state) 187186f8572SMark Yao { 188b69d3ed4SWyon Bi struct rockchip_lvds *lvds = state_to_lvds(state); 189b69d3ed4SWyon Bi 190b69d3ed4SWyon Bi rockchip_phy_power_off(lvds->phy); 191b69d3ed4SWyon Bi 192b69d3ed4SWyon Bi if (lvds->funcs->disable) 193b69d3ed4SWyon Bi lvds->funcs->disable(lvds); 194b69d3ed4SWyon Bi 195b69d3ed4SWyon Bi return 0; 196b69d3ed4SWyon Bi } 197b69d3ed4SWyon Bi 198b69d3ed4SWyon Bi static const struct rockchip_connector_funcs rockchip_lvds_connector_funcs = { 19958c17f51SSandy Huang .pre_init = rockchip_lvds_connector_pre_init, 200b69d3ed4SWyon Bi .init = rockchip_lvds_connector_init, 201b69d3ed4SWyon Bi .enable = rockchip_lvds_connector_enable, 202b69d3ed4SWyon Bi .disable = rockchip_lvds_connector_disable, 203b69d3ed4SWyon Bi }; 204b69d3ed4SWyon Bi 205b69d3ed4SWyon Bi static int rockchip_lvds_probe(struct udevice *dev) 206b69d3ed4SWyon Bi { 207b69d3ed4SWyon Bi struct rockchip_lvds *lvds = dev_get_priv(dev); 208b69d3ed4SWyon Bi const struct rockchip_connector *connector = 209b69d3ed4SWyon Bi (const struct rockchip_connector *)dev_get_driver_data(dev); 210b69d3ed4SWyon Bi 211b69d3ed4SWyon Bi lvds->dev = dev; 212b69d3ed4SWyon Bi lvds->funcs = connector->data; 213b69d3ed4SWyon Bi lvds->grf = syscon_get_regmap(dev_get_parent(dev)); 214b69d3ed4SWyon Bi lvds->dual_channel = dev_read_bool(dev, "dual-channel"); 215b69d3ed4SWyon Bi lvds->data_swap = dev_read_bool(dev, "rockchip,data-swap"); 216*cb17ca6cSSandy Huang lvds->id = of_alias_get_id(ofnode_to_np(dev->node), "lvds"); 217*cb17ca6cSSandy Huang if (lvds->id < 0) 218*cb17ca6cSSandy Huang lvds->id = 0; 219b69d3ed4SWyon Bi 220b69d3ed4SWyon Bi return 0; 221b69d3ed4SWyon Bi } 222b69d3ed4SWyon Bi 223b69d3ed4SWyon Bi static void px30_lvds_enable(struct rockchip_lvds *lvds, int pipe) 224b69d3ed4SWyon Bi { 225b69d3ed4SWyon Bi regmap_write(lvds->grf, PX30_GRF_PD_VO_CON1, 226b69d3ed4SWyon Bi PX30_LVDS_SELECT(lvds->format) | 227b69d3ed4SWyon Bi PX30_LVDS_MODE_EN(1) | PX30_LVDS_MSBSEL(1) | 228b69d3ed4SWyon Bi PX30_LVDS_P2S_EN(1) | PX30_LVDS_VOP_SEL(pipe)); 229b69d3ed4SWyon Bi } 230b69d3ed4SWyon Bi 231b69d3ed4SWyon Bi static void px30_lvds_disable(struct rockchip_lvds *lvds) 232b69d3ed4SWyon Bi { 233b69d3ed4SWyon Bi regmap_write(lvds->grf, PX30_GRF_PD_VO_CON1, 234b69d3ed4SWyon Bi PX30_LVDS_MODE_EN(0) | PX30_LVDS_P2S_EN(0)); 235b69d3ed4SWyon Bi } 236b69d3ed4SWyon Bi 237b69d3ed4SWyon Bi static const struct rockchip_lvds_funcs px30_lvds_funcs = { 238b69d3ed4SWyon Bi .enable = px30_lvds_enable, 239b69d3ed4SWyon Bi .disable = px30_lvds_disable, 240b69d3ed4SWyon Bi }; 241b69d3ed4SWyon Bi 242b69d3ed4SWyon Bi static const struct rockchip_connector px30_lvds_driver_data = { 243b69d3ed4SWyon Bi .funcs = &rockchip_lvds_connector_funcs, 244b69d3ed4SWyon Bi .data = &px30_lvds_funcs, 245b69d3ed4SWyon Bi }; 246b69d3ed4SWyon Bi 247b69d3ed4SWyon Bi static void rk3126_lvds_enable(struct rockchip_lvds *lvds, int pipe) 248b69d3ed4SWyon Bi { 249b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3126_GRF_LVDS_CON0, 250b69d3ed4SWyon Bi RK3126_LVDS_P2S_EN(1) | RK3126_LVDS_MODE_EN(1) | 251b69d3ed4SWyon Bi RK3126_LVDS_MSBSEL(1) | RK3126_LVDS_SELECT(lvds->format)); 252b69d3ed4SWyon Bi } 253b69d3ed4SWyon Bi 254b69d3ed4SWyon Bi static void rk3126_lvds_disable(struct rockchip_lvds *lvds) 255b69d3ed4SWyon Bi { 256b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3126_GRF_LVDS_CON0, 257b69d3ed4SWyon Bi RK3126_LVDS_P2S_EN(0) | RK3126_LVDS_MODE_EN(0)); 258b69d3ed4SWyon Bi } 259b69d3ed4SWyon Bi 260b69d3ed4SWyon Bi static const struct rockchip_lvds_funcs rk3126_lvds_funcs = { 261b69d3ed4SWyon Bi .enable = rk3126_lvds_enable, 262b69d3ed4SWyon Bi .disable = rk3126_lvds_disable, 263b69d3ed4SWyon Bi }; 264b69d3ed4SWyon Bi 265b69d3ed4SWyon Bi static const struct rockchip_connector rk3126_lvds_driver_data = { 266b69d3ed4SWyon Bi .funcs = &rockchip_lvds_connector_funcs, 267b69d3ed4SWyon Bi .data = &rk3126_lvds_funcs, 268b69d3ed4SWyon Bi }; 269b69d3ed4SWyon Bi 270b69d3ed4SWyon Bi static void rk3288_lvds_enable(struct rockchip_lvds *lvds, int pipe) 271b69d3ed4SWyon Bi { 272b69d3ed4SWyon Bi const struct drm_display_mode *mode = lvds->mode; 273186f8572SMark Yao u32 val; 274186f8572SMark Yao 275b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3288_GRF_SOC_CON6, 276b69d3ed4SWyon Bi RK3288_LVDS_LCDC_SEL(pipe)); 277b69d3ed4SWyon Bi 278b69d3ed4SWyon Bi val = RK3288_LVDS_PWRDWN(0) | RK3288_LVDS_CON_CLKINV(0) | 279b69d3ed4SWyon Bi RK3288_LVDS_CON_CHASEL(lvds->dual_channel) | 280b69d3ed4SWyon Bi RK3288_LVDS_CON_SELECT(lvds->format); 281b69d3ed4SWyon Bi 282b69d3ed4SWyon Bi if (lvds->dual_channel) { 283b69d3ed4SWyon Bi u32 h_bp = mode->htotal - mode->hsync_start; 284b69d3ed4SWyon Bi 285b69d3ed4SWyon Bi val |= RK3288_LVDS_CON_ENABLE_2(1) | 286b69d3ed4SWyon Bi RK3288_LVDS_CON_ENABLE_1(1) | 287b69d3ed4SWyon Bi RK3288_LVDS_CON_STARTSEL(lvds->data_swap); 288b69d3ed4SWyon Bi 289b69d3ed4SWyon Bi if (h_bp % 2) 290b69d3ed4SWyon Bi val |= RK3288_LVDS_CON_STARTPHASE(1); 291186f8572SMark Yao else 292b69d3ed4SWyon Bi val |= RK3288_LVDS_CON_STARTPHASE(0); 293186f8572SMark Yao } else { 294b69d3ed4SWyon Bi val |= RK3288_LVDS_CON_ENABLE_2(0) | 295b69d3ed4SWyon Bi RK3288_LVDS_CON_ENABLE_1(1); 296186f8572SMark Yao } 297186f8572SMark Yao 298b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, val); 299b69d3ed4SWyon Bi 300b69d3ed4SWyon Bi rockchip_phy_set_bus_width(lvds->phy, lvds->dual_channel ? 2 : 1); 301186f8572SMark Yao } 302186f8572SMark Yao 303b69d3ed4SWyon Bi static void rk3288_lvds_disable(struct rockchip_lvds *lvds) 304186f8572SMark Yao { 305b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, RK3288_LVDS_PWRDWN(1)); 306186f8572SMark Yao } 307186f8572SMark Yao 308b69d3ed4SWyon Bi static const struct rockchip_lvds_funcs rk3288_lvds_funcs = { 309b69d3ed4SWyon Bi .enable = rk3288_lvds_enable, 310b69d3ed4SWyon Bi .disable = rk3288_lvds_disable, 311186f8572SMark Yao }; 312186f8572SMark Yao 313b69d3ed4SWyon Bi static const struct rockchip_connector rk3288_lvds_driver_data = { 314b69d3ed4SWyon Bi .funcs = &rockchip_lvds_connector_funcs, 315b69d3ed4SWyon Bi .data = &rk3288_lvds_funcs, 316186f8572SMark Yao }; 317186f8572SMark Yao 318b69d3ed4SWyon Bi static void rk3368_lvds_enable(struct rockchip_lvds *lvds, int pipe) 319b69d3ed4SWyon Bi { 320b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3368_GRF_SOC_CON7, 321b69d3ed4SWyon Bi RK3368_LVDS_SELECT(lvds->format) | 322b69d3ed4SWyon Bi RK3368_LVDS_MODE_EN(1) | RK3368_LVDS_MSBSEL(1) | 323b69d3ed4SWyon Bi RK3368_LVDS_P2S_EN(1)); 324b69d3ed4SWyon Bi } 325b69d3ed4SWyon Bi 326b69d3ed4SWyon Bi static void rk3368_lvds_disable(struct rockchip_lvds *lvds) 327b69d3ed4SWyon Bi { 328b69d3ed4SWyon Bi regmap_write(lvds->grf, RK3368_GRF_SOC_CON7, 329b69d3ed4SWyon Bi RK3368_LVDS_MODE_EN(0) | RK3368_LVDS_P2S_EN(0)); 330b69d3ed4SWyon Bi } 331b69d3ed4SWyon Bi 332b69d3ed4SWyon Bi static const struct rockchip_lvds_funcs rk3368_lvds_funcs = { 333b69d3ed4SWyon Bi .enable = rk3368_lvds_enable, 334b69d3ed4SWyon Bi .disable = rk3368_lvds_disable, 33530d6d433SWyon Bi }; 33630d6d433SWyon Bi 337b69d3ed4SWyon Bi static const struct rockchip_connector rk3368_lvds_driver_data = { 338b69d3ed4SWyon Bi .funcs = &rockchip_lvds_connector_funcs, 339b69d3ed4SWyon Bi .data = &rk3368_lvds_funcs, 34030d6d433SWyon Bi }; 34130d6d433SWyon Bi 342aeb5dd22SSandy Huang static void rk3568_lvds_enable(struct rockchip_lvds *lvds, int pipe) 343aeb5dd22SSandy Huang { 344aeb5dd22SSandy Huang regmap_write(lvds->grf, RK3568_GRF_VO_CON2, 345aeb5dd22SSandy Huang RK3568_LVDS0_MODE_EN(1) | RK3568_LVDS0_P2S_EN(1) | 346aeb5dd22SSandy Huang RK3568_LVDS0_DCLK_INV_SEL(1)); 347aeb5dd22SSandy Huang regmap_write(lvds->grf, RK3568_GRF_VO_CON0, 348aeb5dd22SSandy Huang RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1)); 349aeb5dd22SSandy Huang } 350aeb5dd22SSandy Huang 351aeb5dd22SSandy Huang static void rk3568_lvds_disable(struct rockchip_lvds *lvds) 352aeb5dd22SSandy Huang { 353aeb5dd22SSandy Huang regmap_write(lvds->grf, RK3568_GRF_VO_CON2, RK3568_LVDS0_MODE_EN(0)); 354aeb5dd22SSandy Huang } 355aeb5dd22SSandy Huang 356aeb5dd22SSandy Huang static const struct rockchip_lvds_funcs rk3568_lvds_funcs = { 357aeb5dd22SSandy Huang .enable = rk3568_lvds_enable, 358aeb5dd22SSandy Huang .disable = rk3568_lvds_disable, 359aeb5dd22SSandy Huang }; 360aeb5dd22SSandy Huang 361aeb5dd22SSandy Huang static const struct rockchip_connector rk3568_lvds_driver_data = { 362aeb5dd22SSandy Huang .funcs = &rockchip_lvds_connector_funcs, 363aeb5dd22SSandy Huang .data = &rk3568_lvds_funcs, 364aeb5dd22SSandy Huang }; 365aeb5dd22SSandy Huang 366186f8572SMark Yao static const struct udevice_id rockchip_lvds_ids[] = { 367186f8572SMark Yao { 36830d6d433SWyon Bi .compatible = "rockchip,px30-lvds", 369b69d3ed4SWyon Bi .data = (ulong)&px30_lvds_driver_data, 37030d6d433SWyon Bi }, 37130d6d433SWyon Bi { 37230d6d433SWyon Bi .compatible = "rockchip,rk3126-lvds", 373b69d3ed4SWyon Bi .data = (ulong)&rk3126_lvds_driver_data, 37430d6d433SWyon Bi }, 37530d6d433SWyon Bi { 37630d6d433SWyon Bi .compatible = "rockchip,rk3288-lvds", 377b69d3ed4SWyon Bi .data = (ulong)&rk3288_lvds_driver_data, 37830d6d433SWyon Bi }, 37930d6d433SWyon Bi { 380186f8572SMark Yao .compatible = "rockchip,rk3368-lvds", 381b69d3ed4SWyon Bi .data = (ulong)&rk3368_lvds_driver_data, 38230d6d433SWyon Bi }, 383aeb5dd22SSandy Huang { 384aeb5dd22SSandy Huang .compatible = "rockchip,rk3568-lvds", 385aeb5dd22SSandy Huang .data = (ulong)&rk3568_lvds_driver_data, 386aeb5dd22SSandy Huang }, 38730d6d433SWyon Bi {} 388186f8572SMark Yao }; 389186f8572SMark Yao 390186f8572SMark Yao U_BOOT_DRIVER(rockchip_lvds) = { 391186f8572SMark Yao .name = "rockchip_lvds", 392186f8572SMark Yao .id = UCLASS_DISPLAY, 393186f8572SMark Yao .of_match = rockchip_lvds_ids, 394b69d3ed4SWyon Bi .probe = rockchip_lvds_probe, 395b69d3ed4SWyon Bi .priv_auto_alloc_size = sizeof(struct rockchip_lvds), 396186f8572SMark Yao }; 397