1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2022 Rockchip Electronics Co., Ltd
4 */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <i2c.h>
10 #include <max96755f.h>
11 #include <video_bridge.h>
12 #include <drm/drm_mipi_dsi.h>
13 #include <dm/of_access.h>
14 #include <linux/media-bus-format.h>
15
16 #include "rockchip_bridge.h"
17 #include "rockchip_display.h"
18 #include "rockchip_panel.h"
19
max96755f_mipi_dsi_rx_config(struct max96755f_priv * priv)20 static void max96755f_mipi_dsi_rx_config(struct max96755f_priv *priv)
21 {
22 struct drm_display_mode *mode = &priv->mode;
23 u32 hfp, hsa, hbp, hact;
24 u32 vact, vsa, vfp, vbp;
25 u8 lane_map;
26
27 dm_i2c_reg_clrset(priv->dev, 0x0331, NUM_LANES,
28 FIELD_PREP(NUM_LANES, priv->num_lanes - 1));
29
30 lane_map = (priv->dsi_lane_map[0] & 0xff) << 4 |
31 (priv->dsi_lane_map[1] & 0xff) << 6 |
32 (priv->dsi_lane_map[2] & 0xff) << 0 |
33 (priv->dsi_lane_map[3] & 0xff) << 2;
34
35 dm_i2c_reg_write(priv->dev, 0x0332, lane_map);
36
37 if (!priv->dpi_deskew_en)
38 return;
39
40 vact = mode->vdisplay;
41 vsa = mode->vsync_end - mode->vsync_start;
42 vfp = mode->vsync_start - mode->vdisplay;
43 vbp = mode->vtotal - mode->vsync_end;
44 hact = mode->hdisplay;
45 hsa = mode->hsync_end - mode->hsync_start;
46 hfp = mode->hsync_start - mode->hdisplay;
47 hbp = mode->htotal - mode->hsync_end;
48 dm_i2c_reg_write(priv->dev, 0x03A4, 0xc1);
49 dm_i2c_reg_write(priv->dev, 0x0385, FIELD_PREP(DPI_HSYNC_WIDTH_L, hsa));
50 dm_i2c_reg_write(priv->dev, 0x0386, FIELD_PREP(DPI_VYSNC_WIDTH_L, vsa));
51 dm_i2c_reg_write(priv->dev, 0x0387,
52 FIELD_PREP(DPI_VSYNC_WIDTH_H, (vsa >> 8)) |
53 FIELD_PREP(DPI_HSYNC_WIDTH_H, (hsa >> 8)));
54 dm_i2c_reg_write(priv->dev, 0x03a5, FIELD_PREP(DPI_VFP_L, vfp));
55 dm_i2c_reg_write(priv->dev, 0x03a6,
56 FIELD_PREP(DPI_VBP_L, vbp) |
57 FIELD_PREP(DPI_VFP_H, (vfp >> 8)));
58 dm_i2c_reg_write(priv->dev, 0x03a7, FIELD_PREP(DPI_VBP_H, (vbp >> 4)));
59 dm_i2c_reg_write(priv->dev, 0x03a8, FIELD_PREP(DPI_VACT_L, vact));
60 dm_i2c_reg_write(priv->dev, 0x03a9, FIELD_PREP(DPI_VACT_H, (vact >> 8)));
61 dm_i2c_reg_write(priv->dev, 0x03aa, FIELD_PREP(DPI_HFP_L, hfp));
62 dm_i2c_reg_write(priv->dev, 0x03ab,
63 FIELD_PREP(DPI_HBP_L, hbp) |
64 FIELD_PREP(DPI_HFP_H, (hfp >> 7)));
65 dm_i2c_reg_write(priv->dev, 0x03ac, FIELD_PREP(DPI_HBP_H, (hbp >> 4)));
66 dm_i2c_reg_write(priv->dev, 0x03ad, FIELD_PREP(DPI_HACT_L, hact));
67 dm_i2c_reg_write(priv->dev, 0x03ae, FIELD_PREP(DPI_HACT_H, (hact >> 8)));
68 }
69
max96755f_bridge_enable(struct rockchip_bridge * bridge)70 static void max96755f_bridge_enable(struct rockchip_bridge *bridge)
71 {
72 struct udevice *dev = bridge->dev;
73 struct max96755f_priv *priv = dev_get_priv(dev->parent);
74
75 max96755f_mipi_dsi_rx_config(priv);
76 if (priv->split_mode) {
77 dm_i2c_reg_clrset(dev->parent, 0x0010,
78 RESET_ONESHOT | AUTO_LINK | LINK_CFG,
79 FIELD_PREP(RESET_ONESHOT, 1) |
80 FIELD_PREP(AUTO_LINK, 0) |
81 FIELD_PREP(LINK_CFG, SPLITTER_MODE));
82 mdelay(50);
83 dm_i2c_reg_clrset(dev->parent, 0x0053,
84 TX_SPLIT_MASK_B | TX_SPLIT_MASK_A | TX_STR_SEL,
85 FIELD_PREP(TX_SPLIT_MASK_B, 0) |
86 FIELD_PREP(TX_SPLIT_MASK_A, 1) |
87 FIELD_PREP(TX_STR_SEL, 0));
88 dm_i2c_reg_clrset(dev->parent, 0x0057,
89 TX_SPLIT_MASK_B | TX_SPLIT_MASK_A | TX_STR_SEL,
90 FIELD_PREP(TX_SPLIT_MASK_B, 1) |
91 FIELD_PREP(TX_SPLIT_MASK_A, 0) |
92 FIELD_PREP(TX_STR_SEL, 1));
93 dm_i2c_reg_clrset(dev->parent, 0x032a,
94 DV_SWP_AB | DV_CONV | DV_SPL | DV_EN,
95 FIELD_PREP(DV_SWP_AB, priv->dv_swp_ab) |
96 FIELD_PREP(DV_CONV, 1) |
97 FIELD_PREP(DV_SPL, 1) |
98 FIELD_PREP(DV_EN, 1));
99 dm_i2c_reg_clrset(dev->parent, 0x0311,
100 START_PORTAX | START_PORTAY,
101 FIELD_PREP(START_PORTAX, 1) |
102 FIELD_PREP(START_PORTAY, 1));
103 dm_i2c_reg_clrset(dev->parent, 0x0002,
104 VID_TX_EN_X | VID_TX_EN_Y,
105 FIELD_PREP(VID_TX_EN_X, 1) |
106 FIELD_PREP(VID_TX_EN_Y, 1));
107
108 } else {
109 dm_i2c_reg_clrset(dev->parent, 0x0002, VID_TX_EN_X,
110 FIELD_PREP(VID_TX_EN_X, 1));
111 dm_i2c_reg_clrset(dev->parent, 0x0311, START_PORTAX,
112 FIELD_PREP(START_PORTAX, 1));
113 }
114
115 dm_i2c_reg_clrset(dev->parent, 0x0010, RESET_ONESHOT,
116 FIELD_PREP(RESET_ONESHOT, 1));
117 mdelay(100);
118 }
119
max96755f_bridge_disable(struct rockchip_bridge * bridge)120 static void max96755f_bridge_disable(struct rockchip_bridge *bridge)
121 {
122 struct udevice *dev = bridge->dev;
123 struct max96755f_priv *priv = dev_get_priv(dev->parent);
124
125 dm_i2c_reg_clrset(dev->parent, 0x0002, VID_TX_EN_X,
126 FIELD_PREP(VID_TX_EN_X, 0));
127
128 if (priv->split_mode)
129 dm_i2c_reg_clrset(dev->parent, 0x0010,
130 AUTO_LINK | LINK_CFG,
131 FIELD_PREP(AUTO_LINK, 0) |
132 FIELD_PREP(LINK_CFG, LINKA));
133 }
134
max96755f_bridge_mode_set(struct rockchip_bridge * bridge,const struct drm_display_mode * mode)135 static void max96755f_bridge_mode_set(struct rockchip_bridge *bridge,
136 const struct drm_display_mode *mode)
137 {
138 struct udevice *dev = bridge->dev;
139 struct max96755f_priv *priv = dev_get_priv(dev->parent);
140
141 memcpy(&priv->mode, mode, sizeof(struct drm_display_mode));
142 }
143
max96755f_bridge_detect(struct rockchip_bridge * bridge)144 static bool max96755f_bridge_detect(struct rockchip_bridge *bridge)
145 {
146 struct max96755f_priv *priv = dev_get_priv(bridge->dev->parent);
147
148 if (!dm_gpio_get_value(&priv->lock_gpio))
149 return false;
150
151 return true;
152 }
153
154 static const struct rockchip_bridge_funcs max96755f_bridge_funcs = {
155 .enable = max96755f_bridge_enable,
156 .disable = max96755f_bridge_disable,
157 .mode_set = max96755f_bridge_mode_set,
158 .detect = max96755f_bridge_detect,
159 };
160
max96755f_bridge_bind(struct udevice * dev)161 static int max96755f_bridge_bind(struct udevice *dev)
162 {
163 struct mipi_dsi_device *device = dev_get_platdata(dev);
164
165 device->dev = dev;
166 device->lanes = dev_read_u32_default(dev, "dsi,lanes", 4);
167 device->format = dev_read_u32_default(dev, "dsi,format",
168 MIPI_DSI_FMT_RGB888);
169 device->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
170 device->channel = dev_read_u32_default(dev, "reg", 0);
171
172 return 0;
173 }
174
max96755f_bridge_probe(struct udevice * dev)175 static int max96755f_bridge_probe(struct udevice *dev)
176 {
177 struct rockchip_bridge *bridge;
178 struct max96755f_priv *priv = dev_get_priv(dev->parent);
179 const struct device_node *np = ofnode_to_np(dev->node);
180 int i, len, ret;
181
182 bridge = calloc(1, sizeof(*bridge));
183 if (!bridge)
184 return -ENOMEM;
185
186 dev->driver_data = (ulong)bridge;
187 bridge->dev = dev;
188 bridge->funcs = &max96755f_bridge_funcs;
189
190 priv->num_lanes = dev_read_u32_default(dev, "dsi,lanes", 4);
191 priv->dv_swp_ab = dev_read_bool(dev, "vd-swap-ab");
192 priv->dpi_deskew_en = dev_read_bool(dev, "dpi-deskew-en");
193
194 for ( i = 0; i < priv->num_lanes; i++)
195 priv->dsi_lane_map[i] = i;
196
197 if (of_find_property(np, "maxim,dsi-lane-map", &len)) {
198 len /= sizeof(u32);
199 if (priv->num_lanes != len) {
200 printf("invalid number of lane map\n");
201 return -EINVAL;
202 }
203 }
204
205 ret = of_read_u32_array(np, "maxim,dsi-lane-map",
206 priv->dsi_lane_map, priv->num_lanes);
207 if (ret) {
208 printf("get dsi lane map failed\n");
209 return -EINVAL;
210 }
211
212 ret = gpio_request_by_name(dev, "lock-gpios", 0, &priv->lock_gpio,
213 GPIOD_IS_IN);
214 if (ret) {
215 dev_err(dev, "failed to get lock GPIO: %d\n", ret);
216 return ret;
217 }
218
219 return 0;
220 }
221
222 static const struct udevice_id max96755f_bridge_of_match[] = {
223 { .compatible = "maxim,max96755f-bridge", },
224 { }
225 };
226
227 U_BOOT_DRIVER(max96755f_bridge) = {
228 .name = "max96755f_bridge",
229 .id = UCLASS_VIDEO_BRIDGE,
230 .of_match = max96755f_bridge_of_match,
231 .probe = max96755f_bridge_probe,
232 .bind = max96755f_bridge_bind,
233 .platdata_auto_alloc_size = sizeof(struct mipi_dsi_device),
234 };
235