xref: /rk3399_rockchip-uboot/drivers/video/drm/max96755f.c (revision 11f9ae3a9f57d1ecc3b8cc16cfbf5e4e599e5330)
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 <dm/of_access.h>
13 #include <linux/media-bus-format.h>
14 
15 #include "rockchip_bridge.h"
16 #include "rockchip_display.h"
17 #include "rockchip_panel.h"
18 
19 static void max96755f_mipi_dsi_rx_config(struct max96755f_priv *priv)
20 {
21 	struct drm_display_mode *mode = &priv->mode;
22 	u32 hfp, hsa, hbp, hact;
23 	u32 vact, vsa, vfp, vbp;
24 
25 	dm_i2c_reg_clrset(priv->dev, 0x0331, NUM_LANES,
26 			  FIELD_PREP(NUM_LANES, priv->num_lanes - 1));
27 	if (!priv->dpi_deskew_en)
28 		return;
29 
30 	vact = mode->vdisplay;
31 	vsa = mode->vsync_end - mode->vsync_start;
32 	vfp = mode->vsync_start - mode->vdisplay;
33 	vbp = mode->vtotal - mode->vsync_end;
34 	hact = mode->hdisplay;
35 	hsa = mode->hsync_end - mode->hsync_start;
36 	hfp = mode->hsync_start - mode->hdisplay;
37 	hbp = mode->htotal - mode->hsync_end;
38 	dm_i2c_reg_write(priv->dev, 0x03A4, 0xc1);
39 	dm_i2c_reg_write(priv->dev, 0x0385, FIELD_PREP(DPI_HSYNC_WIDTH_L, hsa));
40 	dm_i2c_reg_write(priv->dev, 0x0386, FIELD_PREP(DPI_VYSNC_WIDTH_L, vsa));
41 	dm_i2c_reg_write(priv->dev, 0x0387,
42 			 FIELD_PREP(DPI_VSYNC_WIDTH_H, (vsa >> 8)) |
43 			 FIELD_PREP(DPI_HSYNC_WIDTH_H, (hsa >> 8)));
44 	dm_i2c_reg_write(priv->dev, 0x03a5, FIELD_PREP(DPI_VFP_L, vfp));
45 	dm_i2c_reg_write(priv->dev, 0x03a6,
46 			 FIELD_PREP(DPI_VBP_L, vbp) |
47 			 FIELD_PREP(DPI_VFP_H, (vfp >> 8)));
48 	dm_i2c_reg_write(priv->dev, 0x03a7, FIELD_PREP(DPI_VBP_H, (vbp >> 4)));
49 	dm_i2c_reg_write(priv->dev, 0x03a8, FIELD_PREP(DPI_VACT_L, vact));
50 	dm_i2c_reg_write(priv->dev, 0x03a9, FIELD_PREP(DPI_VACT_H, (vact >> 8)));
51 	dm_i2c_reg_write(priv->dev, 0x03aa, FIELD_PREP(DPI_HFP_L, hfp));
52 	dm_i2c_reg_write(priv->dev, 0x03ab,
53 			 FIELD_PREP(DPI_HBP_L, hbp) |
54 			 FIELD_PREP(DPI_HFP_H, (hfp >> 7)));
55 	dm_i2c_reg_write(priv->dev, 0x03ac, FIELD_PREP(DPI_HBP_H, (hbp >> 4)));
56 	dm_i2c_reg_write(priv->dev, 0x03ad, FIELD_PREP(DPI_HACT_L, hact));
57 	dm_i2c_reg_write(priv->dev, 0x03ae, FIELD_PREP(DPI_HACT_H, (hact >> 8)));
58 }
59 
60 static void max96755f_bridge_enable(struct rockchip_bridge *bridge)
61 {
62 	struct udevice *dev = bridge->dev;
63 	struct max96755f_priv *priv = dev_get_priv(dev->parent);
64 
65 	max96755f_mipi_dsi_rx_config(priv);
66 	if (priv->split_mode) {
67 		dm_i2c_reg_clrset(dev->parent, 0x0010,
68 				  RESET_ONESHOT | AUTO_LINK | LINK_CFG,
69 				  FIELD_PREP(RESET_ONESHOT, 1) |
70 				  FIELD_PREP(AUTO_LINK, 0) |
71 				  FIELD_PREP(LINK_CFG, SPLITTER_MODE));
72 		mdelay(50);
73 		dm_i2c_reg_clrset(dev->parent, 0x0053,
74 				  TX_SPLIT_MASK_B | TX_SPLIT_MASK_A | TX_STR_SEL,
75 				  FIELD_PREP(TX_SPLIT_MASK_B, 0) |
76 				  FIELD_PREP(TX_SPLIT_MASK_A, 1) |
77 				  FIELD_PREP(TX_STR_SEL, 0));
78 		dm_i2c_reg_clrset(dev->parent, 0x0057,
79 				  TX_SPLIT_MASK_B | TX_SPLIT_MASK_A | TX_STR_SEL,
80 				  FIELD_PREP(TX_SPLIT_MASK_B, 1) |
81 				  FIELD_PREP(TX_SPLIT_MASK_A, 0) |
82 				  FIELD_PREP(TX_STR_SEL, 1));
83 		dm_i2c_reg_clrset(dev->parent, 0x032a,
84 				  DV_SWP_AB | DV_CONV | DV_SPL | DV_EN,
85 				  FIELD_PREP(DV_SWP_AB, priv->dv_swp_ab) |
86 				  FIELD_PREP(DV_CONV, 1) |
87 				  FIELD_PREP(DV_SPL, 1) |
88 				  FIELD_PREP(DV_EN, 1));
89 		dm_i2c_reg_clrset(dev->parent, 0x0311,
90 				  START_PORTAX | START_PORTAY,
91 				  FIELD_PREP(START_PORTAX, 1) |
92 				  FIELD_PREP(START_PORTAY, 1));
93 		dm_i2c_reg_clrset(dev->parent, 0x0002,
94 				  VID_TX_EN_X | VID_TX_EN_Y,
95 				  FIELD_PREP(VID_TX_EN_X, 1) |
96 				  FIELD_PREP(VID_TX_EN_Y, 1));
97 
98 	} else {
99 		dm_i2c_reg_clrset(dev->parent, 0x0002, VID_TX_EN_X,
100 				  FIELD_PREP(VID_TX_EN_X, 1));
101 		dm_i2c_reg_clrset(dev->parent, 0x0311, START_PORTAX,
102 				  FIELD_PREP(START_PORTAX, 1));
103 	}
104 
105 	dm_i2c_reg_clrset(dev->parent, 0x0010, RESET_ONESHOT,
106 			  FIELD_PREP(RESET_ONESHOT, 1));
107 	mdelay(100);
108 }
109 
110 static void max96755f_bridge_disable(struct rockchip_bridge *bridge)
111 {
112 	struct udevice *dev = bridge->dev;
113 	struct max96755f_priv *priv = dev_get_priv(dev->parent);
114 
115 	dm_i2c_reg_clrset(dev->parent, 0x0002, VID_TX_EN_X,
116 			  FIELD_PREP(VID_TX_EN_X, 0));
117 
118 	if (priv->split_mode)
119 		dm_i2c_reg_clrset(dev->parent, 0x0010,
120 				  AUTO_LINK | LINK_CFG,
121 				  FIELD_PREP(AUTO_LINK, 0) |
122 				  FIELD_PREP(LINK_CFG, LINKA));
123 }
124 
125 static void max96755f_bridge_mode_set(struct rockchip_bridge *bridge,
126 				      const struct drm_display_mode *mode)
127 {
128 	struct udevice *dev = bridge->dev;
129 	struct max96755f_priv *priv = dev_get_priv(dev->parent);
130 
131 	memcpy(&priv->mode, mode, sizeof(struct drm_display_mode));
132 }
133 
134 static bool max96755f_bridge_detect(struct rockchip_bridge *bridge)
135 {
136 	struct max96755f_priv *priv = dev_get_priv(bridge->dev->parent);
137 
138 	if (!dm_gpio_get_value(&priv->lock_gpio))
139 		return false;
140 
141 	return true;
142 }
143 
144 static const struct rockchip_bridge_funcs max96755f_bridge_funcs = {
145 	.enable = max96755f_bridge_enable,
146 	.disable = max96755f_bridge_disable,
147 	.mode_set = max96755f_bridge_mode_set,
148 	.detect = max96755f_bridge_detect,
149 };
150 
151 static int max96755f_bridge_probe(struct udevice *dev)
152 {
153 	struct rockchip_bridge *bridge;
154 	struct max96755f_priv *priv = dev_get_priv(dev->parent);
155 	int ret;
156 
157 	bridge = calloc(1, sizeof(*bridge));
158 	if (!bridge)
159 		return -ENOMEM;
160 
161 	dev->driver_data = (ulong)bridge;
162 	bridge->dev = dev;
163 	bridge->funcs = &max96755f_bridge_funcs;
164 
165 	priv->num_lanes = dev_read_u32_default(dev, "dsi,lanes", 4);
166 	priv->dv_swp_ab = dev_read_bool(dev, "vd-swap-ab");
167 	priv->dpi_deskew_en = dev_read_bool(dev, "dpi-deskew-en");
168 
169 	ret = gpio_request_by_name(dev, "lock-gpios", 0, &priv->lock_gpio,
170 				   GPIOD_IS_IN);
171 	if (ret) {
172 		dev_err(dev, "failed to get lock GPIO: %d\n", ret);
173 		return ret;
174 	}
175 
176 	return 0;
177 }
178 
179 static const struct udevice_id max96755f_bridge_of_match[] = {
180 	{ .compatible = "maxim,max96755f-bridge", },
181 	{ }
182 };
183 
184 U_BOOT_DRIVER(max96755f_bridge) = {
185 	.name = "max96755f_bridge",
186 	.id = UCLASS_VIDEO_BRIDGE,
187 	.of_match = max96755f_bridge_of_match,
188 	.probe = max96755f_bridge_probe,
189 };
190