]>
Commit | Line | Data |
---|---|---|
a355ece8 | 1 | // SPDX-License-Identifier: GPL-2.0 |
d46d4047 PT |
2 | /* |
3 | * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH | |
4 | * Copyright (c) 2015 Google, Inc | |
5 | * Copyright 2014 Rockchip Inc. | |
d46d4047 PT |
6 | */ |
7 | ||
d678a59d | 8 | #include <common.h> |
d46d4047 PT |
9 | #include <display.h> |
10 | #include <dm.h> | |
11 | #include <regmap.h> | |
12 | #include <syscon.h> | |
13 | #include <video.h> | |
401d1c4f | 14 | #include <asm/global_data.h> |
15f09a1a KY |
15 | #include <asm/arch-rockchip/clock.h> |
16 | #include <asm/arch-rockchip/grf_rk3288.h> | |
17 | #include <asm/arch-rockchip/hardware.h> | |
c05ed00a | 18 | #include <linux/delay.h> |
d46d4047 PT |
19 | #include "rk_vop.h" |
20 | ||
21 | DECLARE_GLOBAL_DATA_PTR; | |
22 | ||
23 | static void rk3288_set_pin_polarity(struct udevice *dev, | |
24 | enum vop_modes mode, u32 polarity) | |
25 | { | |
26 | struct rk_vop_priv *priv = dev_get_priv(dev); | |
27 | struct rk3288_vop *regs = priv->regs; | |
28 | ||
29 | /* The RK3328 VOP (v3.1) has its polarity configuration in ctrl0 */ | |
30 | clrsetbits_le32(®s->dsp_ctrl0, | |
31 | M_DSP_DCLK_POL | M_DSP_DEN_POL | | |
32 | M_DSP_VSYNC_POL | M_DSP_HSYNC_POL, | |
33 | V_DSP_PIN_POL(polarity)); | |
34 | } | |
35 | ||
36 | static void rk3288_set_io_vsel(struct udevice *dev) | |
37 | { | |
38 | struct rk3288_grf *grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); | |
39 | ||
40 | /* lcdc(vop) iodomain select 1.8V */ | |
41 | rk_setreg(&grf->io_vsel, 1 << 0); | |
42 | } | |
43 | ||
44 | /* | |
45 | * Try some common regulators. We should really get these from the | |
46 | * device tree somehow. | |
47 | */ | |
48 | static const char * const rk3288_regulator_names[] = { | |
49 | "vcc18_lcd", | |
50 | "VCC18_LCD", | |
51 | "vdd10_lcd_pwren_h", | |
52 | "vdd10_lcd", | |
53 | "VDD10_LCD", | |
54 | "vcc33_lcd" | |
55 | }; | |
56 | ||
57 | static int rk3288_vop_probe(struct udevice *dev) | |
58 | { | |
59 | /* Before relocation we don't need to do anything */ | |
60 | if (!(gd->flags & GD_FLG_RELOC)) | |
61 | return 0; | |
62 | ||
63 | /* Set the LCDC(vop) iodomain to 1.8V */ | |
64 | rk3288_set_io_vsel(dev); | |
65 | ||
66 | /* Probe regulators required for the RK3288 VOP */ | |
67 | rk_vop_probe_regulators(dev, rk3288_regulator_names, | |
68 | ARRAY_SIZE(rk3288_regulator_names)); | |
69 | ||
70 | return rk_vop_probe(dev); | |
71 | } | |
72 | ||
f418676e SG |
73 | static int rk_vop_remove(struct udevice *dev) |
74 | { | |
75 | struct rk_vop_priv *priv = dev_get_priv(dev); | |
76 | struct rk3288_vop *regs = priv->regs; | |
77 | ||
78 | setbits_le32(®s->sys_ctrl, V_STANDBY_EN(1)); | |
79 | ||
80 | /* wait frame complete (60Hz) to enter standby */ | |
81 | mdelay(17); | |
82 | ||
83 | return 0; | |
84 | } | |
85 | ||
d46d4047 PT |
86 | struct rkvop_driverdata rk3288_driverdata = { |
87 | .features = VOP_FEATURE_OUTPUT_10BIT, | |
88 | .set_pin_polarity = rk3288_set_pin_polarity, | |
89 | }; | |
90 | ||
91 | static const struct udevice_id rk3288_vop_ids[] = { | |
92 | { .compatible = "rockchip,rk3288-vop", | |
93 | .data = (ulong)&rk3288_driverdata }, | |
94 | { } | |
95 | }; | |
96 | ||
97 | static const struct video_ops rk3288_vop_ops = { | |
98 | }; | |
99 | ||
e3e2470f WL |
100 | U_BOOT_DRIVER(rockchip_rk3288_vop) = { |
101 | .name = "rockchip_rk3288_vop", | |
d46d4047 PT |
102 | .id = UCLASS_VIDEO, |
103 | .of_match = rk3288_vop_ids, | |
104 | .ops = &rk3288_vop_ops, | |
105 | .bind = rk_vop_bind, | |
106 | .probe = rk3288_vop_probe, | |
f418676e | 107 | .remove = rk_vop_remove, |
41575d8e | 108 | .priv_auto = sizeof(struct rk_vop_priv), |
d46d4047 | 109 | }; |