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