xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/serdes-panel-split.c (revision fb0c3269ba4cd093780cb50afda01fe0d30baa4b)
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 "core.h"
11 
serdes_panel_split_init(struct serdes * serdes)12 static void serdes_panel_split_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 	if (serdes->chip_data->serdes_type == TYPE_DES)
26 		serdes_i2c_set_sequence(serdes);
27 
28 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
29 		       serdes->chip_data->name);
30 }
31 
serdes_panel_split_prepare(struct rockchip_panel * panel)32 static void serdes_panel_split_prepare(struct rockchip_panel *panel)
33 {
34 	struct udevice *dev = panel->dev;
35 	struct serdes *serdes = dev_get_priv(dev->parent);
36 
37 	if (serdes->chip_data->panel_ops->prepare)
38 		serdes->chip_data->panel_ops->prepare(serdes);
39 
40 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
41 		       serdes->chip_data->name);
42 }
43 
serdes_panel_split_unprepare(struct rockchip_panel * panel)44 static void serdes_panel_split_unprepare(struct rockchip_panel *panel)
45 {
46 	struct udevice *dev = panel->dev;
47 	struct serdes *serdes = dev_get_priv(dev->parent);
48 
49 	if (serdes->chip_data->panel_ops->unprepare)
50 		serdes->chip_data->panel_ops->unprepare(serdes);
51 
52 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
53 		       serdes->chip_data->name);
54 }
55 
serdes_panel_split_enable(struct rockchip_panel * panel)56 static void serdes_panel_split_enable(struct rockchip_panel *panel)
57 {
58 	struct udevice *dev = panel->dev;
59 	struct serdes *serdes = dev_get_priv(dev->parent);
60 
61 	if (serdes->chip_data->panel_ops->enable)
62 		serdes->chip_data->panel_ops->enable(serdes);
63 
64 	serdes_panel_split_init(serdes);
65 
66 	if (serdes->serdes_panel_split->backlight)
67 		backlight_enable(serdes->serdes_panel_split->backlight);
68 
69 	if (serdes->chip_data->panel_ops->backlight_enable)
70 		serdes->chip_data->panel_ops->backlight_enable(serdes);
71 
72 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
73 		       serdes->chip_data->name);
74 }
75 
serdes_panel_split_disable(struct rockchip_panel * panel)76 static void serdes_panel_split_disable(struct rockchip_panel *panel)
77 {
78 	struct udevice *dev = panel->dev;
79 	struct serdes *serdes = dev_get_priv(dev->parent);
80 
81 	if (serdes->chip_data->panel_ops->backlight_disable)
82 		serdes->chip_data->panel_ops->backlight_disable(serdes);
83 
84 	if (serdes->serdes_panel_split->backlight)
85 		backlight_disable(serdes->serdes_panel_split->backlight);
86 
87 	if (serdes->chip_data->panel_ops->disable)
88 		serdes->chip_data->panel_ops->disable(serdes);
89 
90 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
91 		       serdes->chip_data->name);
92 }
93 
94 static struct rockchip_panel_funcs serdes_panel_split_ops = {
95 	.prepare = serdes_panel_split_prepare,
96 	.unprepare = serdes_panel_split_unprepare,
97 	.enable = serdes_panel_split_enable,
98 	.disable = serdes_panel_split_disable,
99 };
100 
serdes_panel_split_probe(struct udevice * dev)101 static int serdes_panel_split_probe(struct udevice *dev)
102 {
103 	struct serdes *serdes = dev_get_priv(dev->parent);
104 	struct serdes_panel_split *serdes_panel_split = NULL;
105 	struct rockchip_panel *panel;
106 	int ret;
107 
108 	SERDES_DBG_MFD("%s: %s %s start\n", __func__, serdes->dev->name,
109 		       serdes->chip_data->name);
110 
111 	if (!serdes->chip_data->panel_ops) {
112 		printf("%s %s no panel ops\n",
113 		       __func__, serdes->chip_data->name);
114 		return -1;
115 	}
116 
117 	if (serdes->chip_data->serdes_type != TYPE_DES)
118 		printf("%s warning: this chip is not des type\n", __func__);
119 
120 	serdes_panel_split = calloc(1, sizeof(*serdes_panel_split));
121 	if (!serdes_panel_split)
122 		return -ENOMEM;
123 
124 	serdes->serdes_panel_split = serdes_panel_split;
125 
126 	ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
127 					   "backlight",
128 					   &serdes->serdes_panel_split->backlight);
129 	if (ret && ret != -ENOENT)
130 		printf("%s: Cannot get backlight: %d\n", __func__, ret);
131 
132 	panel = calloc(1, sizeof(*panel));
133 	if (!panel)
134 		return -ENOMEM;
135 
136 	ret = serdes_get_init_seq(serdes);
137 	if (ret)
138 		goto free_panel;
139 
140 	dev->driver_data = (ulong)panel;
141 	panel->dev = dev;
142 	panel->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
143 	panel->funcs = &serdes_panel_split_ops;
144 
145 	serdes->serdes_panel_split->panel = panel;
146 
147 	printf("%s %s successful, version %s\n",
148 	       __func__,
149 	       serdes->dev->name,
150 	       SERDES_UBOOT_DISPLAY_VERSION);
151 
152 	return 0;
153 
154 free_panel:
155 	free(panel);
156 
157 	return ret;
158 }
159 
160 static const struct udevice_id serdes_of_match[] = {
161 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96752)
162 	{ .compatible = "maxim,max96752-panel-split",},
163 #endif
164 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96772)
165 	{ .compatible = "maxim,max96772-panel-split",},
166 #endif
167 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX121)
168 	{ .compatible = "rockchip,rkx121-panel-split",},
169 #endif
170 	{ }
171 };
172 
173 U_BOOT_DRIVER(serdes_panel_split) = {
174 	.name = "serdes-panel-split",
175 	.id = UCLASS_PANEL,
176 	.of_match = serdes_of_match,
177 	.probe = serdes_panel_split_probe,
178 	.priv_auto_alloc_size = sizeof(struct serdes_panel_split),
179 };
180