xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_crtc.c (revision 10a896e240d539cb95f8fb67060346e7930d4e12)
1186f8572SMark Yao /*
2186f8572SMark Yao  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3186f8572SMark Yao  *
4186f8572SMark Yao  * SPDX-License-Identifier:	GPL-2.0+
5186f8572SMark Yao  */
6186f8572SMark Yao 
79ae51bb5SWyon Bi #include <clk.h>
8186f8572SMark Yao #include <config.h>
9186f8572SMark Yao #include <common.h>
10186f8572SMark Yao #include <errno.h>
11186f8572SMark Yao #include <malloc.h>
12186f8572SMark Yao #include <asm/unaligned.h>
13186f8572SMark Yao #include <linux/list.h>
14186f8572SMark Yao #include <dm/device.h>
15186f8572SMark Yao #include <dm.h>
169ae51bb5SWyon Bi #include <dm/device-internal.h>
179ae51bb5SWyon Bi #include <dm/lists.h>
18186f8572SMark Yao 
19186f8572SMark Yao #include "rockchip_display.h"
20186f8572SMark Yao #include "rockchip_crtc.h"
21186f8572SMark Yao #include "rockchip_connector.h"
22186f8572SMark Yao 
23690e9ed1SSandy Huang #ifndef CONFIG_SPL_BUILD
249ae51bb5SWyon Bi static const struct udevice_id rockchip_vp_ids[] = {
259ae51bb5SWyon Bi 	{ .compatible = "rockchip-vp" },
269ae51bb5SWyon Bi 	{ }
279ae51bb5SWyon Bi };
289ae51bb5SWyon Bi 
299ae51bb5SWyon Bi U_BOOT_DRIVER(rockchip_vp) = {
309ae51bb5SWyon Bi 	.name		= "rockchip-vp",
319ae51bb5SWyon Bi 	.id		= UCLASS_VIDEO_CRTC,
329ae51bb5SWyon Bi 	.of_match	= rockchip_vp_ids,
339ae51bb5SWyon Bi };
349ae51bb5SWyon Bi 
35186f8572SMark Yao static const struct rockchip_crtc rk3036_vop_data = {
36186f8572SMark Yao 	.funcs = &rockchip_vop_funcs,
37186f8572SMark Yao 	.data = &rk3036_vop,
38186f8572SMark Yao };
39186f8572SMark Yao 
4054f7137bSDamon Ding static const struct rockchip_crtc rv1106_vop_data = {
4154f7137bSDamon Ding 	.funcs = &rockchip_vop_funcs,
4254f7137bSDamon Ding 	.data = &rv1106_vop,
4354f7137bSDamon Ding };
4454f7137bSDamon Ding 
45fe49d276SSandy Huang static const struct rockchip_crtc rv1108_vop_data = {
46fe49d276SSandy Huang 	.funcs = &rockchip_vop_funcs,
47fe49d276SSandy Huang 	.data = &rv1108_vop,
48fe49d276SSandy Huang };
49fe49d276SSandy Huang 
50a144d23dSAndy Yan static const struct rockchip_crtc rv1126_vop_data = {
51a144d23dSAndy Yan 	.funcs = &rockchip_vop_funcs,
52a144d23dSAndy Yan 	.data = &rv1126_vop,
53a144d23dSAndy Yan };
54a144d23dSAndy Yan 
55*10a896e2SChaoyi Chen static const struct rockchip_crtc rv1126b_vop_data = {
56*10a896e2SChaoyi Chen 	.funcs = &rockchip_vop_funcs,
57*10a896e2SChaoyi Chen 	.data = &rv1126b_vop,
58*10a896e2SChaoyi Chen };
59*10a896e2SChaoyi Chen 
607130fbf6SSandy Huang static const struct rockchip_crtc px30_vop_lit_data = {
617130fbf6SSandy Huang 	.funcs = &rockchip_vop_funcs,
627130fbf6SSandy Huang 	.data = &px30_vop_lit,
637130fbf6SSandy Huang };
647130fbf6SSandy Huang 
657130fbf6SSandy Huang static const struct rockchip_crtc px30_vop_big_data = {
667130fbf6SSandy Huang 	.funcs = &rockchip_vop_funcs,
677130fbf6SSandy Huang 	.data = &px30_vop_big,
687130fbf6SSandy Huang };
697130fbf6SSandy Huang 
705c651246SSandy Huang static const struct rockchip_crtc rk3308_vop_data = {
715c651246SSandy Huang 	.funcs = &rockchip_vop_funcs,
725c651246SSandy Huang 	.data = &rk3308_vop,
735c651246SSandy Huang };
745c651246SSandy Huang 
75ad3aa75aSSandy Huang static const struct rockchip_crtc rk1808_vop_data = {
76ad3aa75aSSandy Huang 	.funcs = &rockchip_vop_funcs,
77ad3aa75aSSandy Huang 	.data = &rk1808_vop,
78ad3aa75aSSandy Huang };
79ad3aa75aSSandy Huang 
8006bb018fSSandy Huang static const struct rockchip_crtc rk3288_vop_big_data = {
81186f8572SMark Yao 	.funcs = &rockchip_vop_funcs,
8206bb018fSSandy Huang 	.data = &rk3288_vop_big,
8306bb018fSSandy Huang };
8406bb018fSSandy Huang 
8506bb018fSSandy Huang static const struct rockchip_crtc rk3288_vop_lit_data = {
8606bb018fSSandy Huang 	.funcs = &rockchip_vop_funcs,
8706bb018fSSandy Huang 	.data = &rk3288_vop_lit,
88186f8572SMark Yao };
89186f8572SMark Yao 
90186f8572SMark Yao static const struct rockchip_crtc rk3368_vop_data = {
91186f8572SMark Yao 	.funcs = &rockchip_vop_funcs,
92186f8572SMark Yao 	.data = &rk3368_vop,
93186f8572SMark Yao };
94186f8572SMark Yao 
95186f8572SMark Yao static const struct rockchip_crtc rk3366_vop_data = {
96186f8572SMark Yao 	.funcs = &rockchip_vop_funcs,
97186f8572SMark Yao 	.data = &rk3366_vop,
98186f8572SMark Yao };
99186f8572SMark Yao 
100186f8572SMark Yao static const struct rockchip_crtc rk3399_vop_big_data = {
101186f8572SMark Yao 	.funcs = &rockchip_vop_funcs,
102186f8572SMark Yao 	.data = &rk3399_vop_big,
103186f8572SMark Yao };
104186f8572SMark Yao 
105186f8572SMark Yao static const struct rockchip_crtc rk3399_vop_lit_data = {
106186f8572SMark Yao 	.funcs = &rockchip_vop_funcs,
107186f8572SMark Yao 	.data = &rk3399_vop_lit,
108186f8572SMark Yao };
109186f8572SMark Yao 
110186f8572SMark Yao static const struct rockchip_crtc rk322x_vop_data = {
111186f8572SMark Yao 	.funcs = &rockchip_vop_funcs,
112186f8572SMark Yao 	.data = &rk322x_vop,
113186f8572SMark Yao };
114186f8572SMark Yao 
115186f8572SMark Yao static const struct rockchip_crtc rk3328_vop_data = {
116186f8572SMark Yao 	.funcs = &rockchip_vop_funcs,
117186f8572SMark Yao 	.data = &rk3328_vop,
118186f8572SMark Yao };
119186f8572SMark Yao 
120400ef44dSChaoyi Chen static const struct rockchip_crtc rk3506_vop_data = {
121400ef44dSChaoyi Chen 	.funcs = &rockchip_vop_funcs,
122400ef44dSChaoyi Chen 	.data = &rk3506_vop,
123400ef44dSChaoyi Chen };
124400ef44dSChaoyi Chen 
1255fa6e665SDamon Ding static const struct rockchip_crtc rk3528_vop_data = {
1265fa6e665SDamon Ding 	.funcs = &rockchip_vop2_funcs,
1275fa6e665SDamon Ding 	.data = &rk3528_vop,
1285fa6e665SDamon Ding };
1295fa6e665SDamon Ding 
130452afb13SDamon Ding static const struct rockchip_crtc rk3562_vop_data = {
131452afb13SDamon Ding 	.funcs = &rockchip_vop2_funcs,
132452afb13SDamon Ding 	.data = &rk3562_vop,
133452afb13SDamon Ding };
134452afb13SDamon Ding 
135d0408543SAndy Yan static const struct rockchip_crtc rk3568_vop_data = {
136d0408543SAndy Yan 	.funcs = &rockchip_vop2_funcs,
137d0408543SAndy Yan 	.data = &rk3568_vop,
138d0408543SAndy Yan };
139d0408543SAndy Yan 
140a552a69cSDamon Ding static const struct rockchip_crtc rk3576_vop_data = {
141a552a69cSDamon Ding 	.funcs = &rockchip_vop2_funcs,
142a552a69cSDamon Ding 	.data = &rk3576_vop,
143a552a69cSDamon Ding };
144a552a69cSDamon Ding 
14572f233a9SDamon Ding static const struct rockchip_crtc rk3576_vop_lit_data = {
146a0429dd8SDamon Ding 	.funcs = &rockchip_vop_funcs,
14772f233a9SDamon Ding 	.data = &rk3576_vop_lit,
14872f233a9SDamon Ding };
14972f233a9SDamon Ding 
150ecc31b6eSAndy Yan static const struct rockchip_crtc rk3588_vop_data = {
151ecc31b6eSAndy Yan 	.funcs = &rockchip_vop2_funcs,
152ecc31b6eSAndy Yan 	.data = &rk3588_vop,
153ecc31b6eSAndy Yan };
154ecc31b6eSAndy Yan 
155186f8572SMark Yao static const struct udevice_id rockchip_vop_ids[] = {
156186f8572SMark Yao 	{
157186f8572SMark Yao 		.compatible = "rockchip,rk3036-vop",
158186f8572SMark Yao 		.data = (ulong)&rk3036_vop_data,
159186f8572SMark Yao 	}, {
160fe49d276SSandy Huang 		.compatible = "rockchip,rv1108-vop",
161fe49d276SSandy Huang 		.data = (ulong)&rv1108_vop_data,
162fe49d276SSandy Huang 	}, {
16354f7137bSDamon Ding 		.compatible = "rockchip,rv1106-vop",
16454f7137bSDamon Ding 		.data = (ulong)&rv1106_vop_data,
16554f7137bSDamon Ding 	}, {
166a144d23dSAndy Yan 		.compatible = "rockchip,rv1126-vop",
167a144d23dSAndy Yan 		.data = (ulong)&rv1126_vop_data,
168a144d23dSAndy Yan 	}, {
169*10a896e2SChaoyi Chen 		.compatible = "rockchip,rv1126b-vop",
170*10a896e2SChaoyi Chen 		.data = (ulong)&rv1126b_vop_data,
171*10a896e2SChaoyi Chen 	}, {
17203a9cc7bSMark Yao 		.compatible = "rockchip,rk3126-vop",
17303a9cc7bSMark Yao 		.data = (ulong)&rk3036_vop_data,
17403a9cc7bSMark Yao 	}, {
1757130fbf6SSandy Huang 		.compatible = "rockchip,px30-vop-lit",
1767130fbf6SSandy Huang 		.data = (ulong)&px30_vop_lit_data,
1777130fbf6SSandy Huang 	}, {
1787130fbf6SSandy Huang 		.compatible = "rockchip,px30-vop-big",
1797130fbf6SSandy Huang 		.data = (ulong)&px30_vop_big_data,
1807130fbf6SSandy Huang 	}, {
1815c651246SSandy Huang 		.compatible = "rockchip,rk3308-vop",
1825c651246SSandy Huang 		.data = (ulong)&rk3308_vop_data,
1835c651246SSandy Huang 	}, {
184ad3aa75aSSandy Huang 		.compatible = "rockchip,rk1808-vop-lit",
185ad3aa75aSSandy Huang 		.data = (ulong)&rk1808_vop_data,
186ad3aa75aSSandy Huang 	}, {
18706bb018fSSandy Huang 		.compatible = "rockchip,rk3288-vop-big",
18806bb018fSSandy Huang 		.data = (ulong)&rk3288_vop_big_data,
18906bb018fSSandy Huang 	}, {
19006bb018fSSandy Huang 		.compatible = "rockchip,rk3288-vop-lit",
19106bb018fSSandy Huang 		.data = (ulong)&rk3288_vop_lit_data,
192186f8572SMark Yao 	}, {
193186f8572SMark Yao 		.compatible = "rockchip,rk3368-vop",
194186f8572SMark Yao 		.data = (ulong)&rk3368_vop_data,
195186f8572SMark Yao 	}, {
196186f8572SMark Yao 		.compatible = "rockchip,rk3366-vop",
197186f8572SMark Yao 		.data = (ulong)&rk3366_vop_data,
198186f8572SMark Yao 	}, {
199186f8572SMark Yao 		.compatible = "rockchip,rk3399-vop-big",
200186f8572SMark Yao 		.data = (ulong)&rk3399_vop_big_data,
201186f8572SMark Yao 	}, {
202186f8572SMark Yao 		.compatible = "rockchip,rk3399-vop-lit",
203186f8572SMark Yao 		.data = (ulong)&rk3399_vop_lit_data,
204186f8572SMark Yao 	}, {
205186f8572SMark Yao 		.compatible = "rockchip,rk322x-vop",
206186f8572SMark Yao 		.data = (ulong)&rk322x_vop_data,
207186f8572SMark Yao 	}, {
208186f8572SMark Yao 		.compatible = "rockchip,rk3328-vop",
209186f8572SMark Yao 		.data = (ulong)&rk3328_vop_data,
210d0408543SAndy Yan 	}, {
211400ef44dSChaoyi Chen 		.compatible = "rockchip,rk3506-vop",
212400ef44dSChaoyi Chen 		.data = (ulong)&rk3506_vop_data,
213400ef44dSChaoyi Chen 	}, {
2145fa6e665SDamon Ding 		.compatible = "rockchip,rk3528-vop",
2155fa6e665SDamon Ding 		.data = (ulong)&rk3528_vop_data,
2165fa6e665SDamon Ding 	}, {
217452afb13SDamon Ding 		.compatible = "rockchip,rk3562-vop",
218452afb13SDamon Ding 		.data = (ulong)&rk3562_vop_data,
219452afb13SDamon Ding 	}, {
220d0408543SAndy Yan 		.compatible = "rockchip,rk3568-vop",
221d0408543SAndy Yan 		.data = (ulong)&rk3568_vop_data,
222ecc31b6eSAndy Yan 	}, {
223a552a69cSDamon Ding 		.compatible = "rockchip,rk3576-vop",
224a552a69cSDamon Ding 		.data = (ulong)&rk3576_vop_data,
225a552a69cSDamon Ding 	}, {
22672f233a9SDamon Ding 		.compatible = "rockchip,rk3576-vop-lit",
22772f233a9SDamon Ding 		.data = (ulong)&rk3576_vop_lit_data,
22872f233a9SDamon Ding 	}, {
229ecc31b6eSAndy Yan 		.compatible = "rockchip,rk3588-vop",
230ecc31b6eSAndy Yan 		.data = (ulong)&rk3588_vop_data,
231186f8572SMark Yao 	}, { }
232186f8572SMark Yao };
233186f8572SMark Yao 
rockchip_vop_probe(struct udevice * dev)234186f8572SMark Yao static int rockchip_vop_probe(struct udevice *dev)
235186f8572SMark Yao {
2369ae51bb5SWyon Bi 	struct udevice *child;
2379ae51bb5SWyon Bi 	int ret;
2389ae51bb5SWyon Bi 
239cf409a2eSWyon Bi 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
240cf409a2eSWyon Bi 	ret = clk_set_defaults(dev);
241cf409a2eSWyon Bi 	if (ret) {
242cf409a2eSWyon Bi 		dev_err(dev, "%s clk_set_defaults failed %d\n", __func__, ret);
243cf409a2eSWyon Bi 		return ret;
244cf409a2eSWyon Bi 	}
245cf409a2eSWyon Bi 
2469ae51bb5SWyon Bi 	for (device_find_first_child(dev, &child);
2479ae51bb5SWyon Bi 	     child;
2489ae51bb5SWyon Bi 	     device_find_next_child(&child)) {
2499ae51bb5SWyon Bi 		ret = device_probe(child);
2509ae51bb5SWyon Bi 		if (ret)
2519ae51bb5SWyon Bi 			return ret;
2529ae51bb5SWyon Bi 
2539ae51bb5SWyon Bi 		ret = clk_set_defaults(child);
2549ae51bb5SWyon Bi 		if (ret)
2559ae51bb5SWyon Bi 			return ret;
2569ae51bb5SWyon Bi 	}
2579ae51bb5SWyon Bi 
258186f8572SMark Yao 	return 0;
259186f8572SMark Yao }
260186f8572SMark Yao 
rockchip_vop_bind(struct udevice * dev)261186f8572SMark Yao static int rockchip_vop_bind(struct udevice *dev)
262186f8572SMark Yao {
2639ae51bb5SWyon Bi 	ofnode ports, node;
2649ae51bb5SWyon Bi 	int ret;
2659ae51bb5SWyon Bi 
2669ae51bb5SWyon Bi 	ports = dev_read_subnode(dev, "ports");
2679ae51bb5SWyon Bi 	if (!ofnode_valid(ports))
2689ae51bb5SWyon Bi 		return 0;
2699ae51bb5SWyon Bi 
2709ae51bb5SWyon Bi 	ofnode_for_each_subnode(node, ports) {
2719ae51bb5SWyon Bi 		const char *name = ofnode_get_name(node);
2729ae51bb5SWyon Bi 
2739ae51bb5SWyon Bi 		ret = device_bind_driver_to_node(dev, "rockchip-vp", name,
2749ae51bb5SWyon Bi 						 node, NULL);
2759ae51bb5SWyon Bi 		if (ret) {
2769ae51bb5SWyon Bi 			dev_err(dev, "unable to bind vp device node: %d\n", ret);
2779ae51bb5SWyon Bi 			return ret;
2789ae51bb5SWyon Bi 		}
2799ae51bb5SWyon Bi 	}
2809ae51bb5SWyon Bi 
281186f8572SMark Yao 	return 0;
282186f8572SMark Yao }
283186f8572SMark Yao 
284186f8572SMark Yao U_BOOT_DRIVER(rockchip_vop) = {
285186f8572SMark Yao 	.name	= "rockchip-vop",
286186f8572SMark Yao 	.id	= UCLASS_VIDEO_CRTC,
287186f8572SMark Yao 	.of_match = rockchip_vop_ids,
288186f8572SMark Yao 	.bind	= rockchip_vop_bind,
289186f8572SMark Yao 	.probe	= rockchip_vop_probe,
290186f8572SMark Yao };
291186f8572SMark Yao 
292186f8572SMark Yao UCLASS_DRIVER(rockchip_crtc) = {
293186f8572SMark Yao 	.id		= UCLASS_VIDEO_CRTC,
294186f8572SMark Yao 	.name		= "CRTC",
295186f8572SMark Yao };
296690e9ed1SSandy Huang 
297690e9ed1SSandy Huang #else
298690e9ed1SSandy Huang static struct rockchip_crtc rk3528_vop_data = {
299690e9ed1SSandy Huang 	.funcs = &rockchip_vop2_funcs,
300690e9ed1SSandy Huang 	.data = &rk3528_vop,
301690e9ed1SSandy Huang };
302690e9ed1SSandy Huang 
rockchip_spl_vop_probe(struct crtc_state * crtc_state)303690e9ed1SSandy Huang int rockchip_spl_vop_probe(struct crtc_state *crtc_state)
304690e9ed1SSandy Huang {
305690e9ed1SSandy Huang 
306690e9ed1SSandy Huang 	crtc_state->crtc = &rk3528_vop_data;
307690e9ed1SSandy Huang 
308690e9ed1SSandy Huang 	return 0;
309690e9ed1SSandy Huang }
310690e9ed1SSandy Huang #endif
311690e9ed1SSandy Huang 
312