xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/serdes-panel.c (revision c6d8e6aac063eabd956f25ad0e4c1531dd59f385)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * serdes-panel.c  --  display panel for different serdes chips
4  *
5  * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
6  *
7  * Author: luowei <lw@rock-chips.com>
8  */
9 
10 #include <serdes-display-core.h>
11 
12 static void serdes_panel_init(struct serdes *serdes)
13 {
14 	if (serdes->vpower_supply)
15 		regulator_set_enable(serdes->vpower_supply, true);
16 
17 	if (dm_gpio_is_valid(&serdes->enable_gpio))
18 		dm_gpio_set_value(&serdes->enable_gpio, 1);
19 
20 	mdelay(5);
21 
22 	if (serdes->chip_data->panel_ops->init)
23 		serdes->chip_data->panel_ops->init(serdes);
24 
25 	serdes_i2c_set_sequence(serdes);
26 
27 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
28 		       serdes->chip_data->name);
29 }
30 
31 static void serdes_panel_prepare(struct rockchip_panel *panel)
32 {
33 	struct udevice *dev = panel->dev;
34 	struct serdes *serdes = dev_get_priv(dev);
35 
36 	if (serdes->chip_data->panel_ops->prepare)
37 		serdes->chip_data->panel_ops->prepare(serdes);
38 
39 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
40 		       serdes->chip_data->name);
41 }
42 
43 static void serdes_panel_unprepare(struct rockchip_panel *panel)
44 {
45 	struct udevice *dev = panel->dev;
46 	struct serdes *serdes = dev_get_priv(dev);
47 
48 	if (serdes->chip_data->panel_ops->unprepare)
49 		serdes->chip_data->panel_ops->unprepare(serdes);
50 
51 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
52 		       serdes->chip_data->name);
53 }
54 
55 static void serdes_panel_enable(struct rockchip_panel *panel)
56 {
57 	struct udevice *dev = panel->dev;
58 	struct serdes *serdes = dev_get_priv(dev);
59 
60 	if (serdes->chip_data->panel_ops->enable)
61 		serdes->chip_data->panel_ops->enable(serdes);
62 
63 	serdes_panel_init(serdes);
64 
65 	if (serdes->serdes_panel->backlight)
66 		backlight_enable(serdes->serdes_panel->backlight);
67 
68 	if (serdes->chip_data->panel_ops->backlight_enable)
69 		serdes->chip_data->panel_ops->backlight_enable(serdes);
70 
71 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
72 		       serdes->chip_data->name);
73 }
74 
75 static void serdes_panel_disable(struct rockchip_panel *panel)
76 {
77 	struct udevice *dev = panel->dev;
78 	struct serdes *serdes = dev_get_priv(dev);
79 
80 	if (serdes->chip_data->panel_ops->backlight_disable)
81 		serdes->chip_data->panel_ops->backlight_disable(serdes);
82 
83 	if (serdes->serdes_panel->backlight)
84 		backlight_disable(serdes->serdes_panel->backlight);
85 
86 	if (serdes->chip_data->panel_ops->disable)
87 		serdes->chip_data->panel_ops->disable(serdes);
88 
89 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
90 		       serdes->chip_data->name);
91 }
92 
93 static struct rockchip_panel_funcs serdes_panel_ops = {
94 	.prepare = serdes_panel_prepare,
95 	.unprepare = serdes_panel_unprepare,
96 	.enable = serdes_panel_enable,
97 	.disable = serdes_panel_disable,
98 };
99 
100 static int serdes_panel_probe(struct udevice *dev)
101 {
102 	struct serdes *serdes = dev_get_priv(dev);
103 	struct serdes_panel *serdes_panel = NULL;
104 	struct rockchip_panel *panel;
105 	int ret;
106 
107 	ret = i2c_set_chip_offset_len(dev, 2);
108 	if (ret)
109 		return ret;
110 
111 	serdes->dev = dev;
112 	serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev);
113 	serdes->type = serdes->chip_data->serdes_type;
114 
115 	SERDES_DBG_MFD("%s: %s %s start\n", __func__, serdes->dev->name,
116 		       serdes->chip_data->name);
117 
118 	if (!serdes->chip_data->panel_ops) {
119 		printf("%s %s no panel ops\n",
120 		       __func__, serdes->chip_data->name);
121 		return -1;
122 	}
123 
124 	if (serdes->chip_data->serdes_type != TYPE_DES)
125 		printf("warning: this chip is not des type\n");
126 
127 	serdes_panel = calloc(1, sizeof(*serdes_panel));
128 	if (!serdes_panel)
129 		return -ENOMEM;
130 
131 	serdes->serdes_panel = serdes_panel;
132 
133 	ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
134 					   "backlight",
135 					   &serdes->serdes_panel->backlight);
136 	if (ret && ret != -ENOENT)
137 		printf("%s: Cannot get backlight: %d\n", __func__, ret);
138 
139 	panel = calloc(1, sizeof(*panel));
140 	if (!panel)
141 		return -ENOMEM;
142 
143 	ret = serdes_get_init_seq(serdes);
144 	if (ret)
145 		goto free_panel;
146 
147 	dev->driver_data = (ulong)panel;
148 	panel->dev = dev;
149 	panel->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
150 	panel->funcs = &serdes_panel_ops;
151 
152 	serdes->serdes_panel->panel = panel;
153 
154 	ret = serdes_pinctrl_register(dev, serdes);
155 	if (ret)
156 		return ret;
157 
158 	printf("%s %s successful, version %s\n",
159 	       __func__,
160 	       serdes->dev->name,
161 	       SERDES_UBOOT_DISPLAY_VERSION);
162 
163 	return 0;
164 
165 free_panel:
166 	free(panel);
167 
168 	return ret;
169 }
170 
171 static const struct udevice_id serdes_of_match[] = {
172 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96752)
173 	{ .compatible = "maxim,max96752", .data = (ulong)&serdes_max96752_data },
174 #endif
175 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96772)
176 	{ .compatible = "maxim,max96772", .data = (ulong)&serdes_max96772_data },
177 #endif
178 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX121)
179 	{ .compatible = "rockchip,rkx121", .data = (ulong)&serdes_rkx121_data },
180 #endif
181 	{ }
182 };
183 
184 U_BOOT_DRIVER(serdes_panel) = {
185 	.name = "serdes-panel",
186 	.id = UCLASS_PANEL,
187 	.of_match = serdes_of_match,
188 	.probe = serdes_panel_probe,
189 	.priv_auto_alloc_size = sizeof(struct serdes),
190 };
191