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