video: add nexell video driver (soc: displaytop)
[platform/kernel/u-boot.git] / drivers / video / nexell / soc / s5pxx18_soc_disptop.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2016  Nexell Co., Ltd.
4  *
5  * Author: junghyun, kim <jhkim@nexell.co.kr>
6  */
7
8 #include <linux/types.h>
9 #include <linux/io.h>
10
11 #include "s5pxx18_soc_disptop.h"
12
13 static struct {
14         struct nx_disp_top_register_set *pregister;
15 } __g_module_variables = { NULL, };
16
17 int nx_disp_top_initialize(void)
18 {
19         static int binit;
20         u32 i;
21
22         if (binit == 0) {
23                 for (i = 0; i < NUMBER_OF_DISPTOP_MODULE; i++)
24                         __g_module_variables.pregister = NULL;
25                 binit = 1;
26         }
27         return 1;
28 }
29
30 u32 nx_disp_top_get_number_of_module(void)
31 {
32         return NUMBER_OF_DISPTOP_MODULE;
33 }
34
35 u32 nx_disp_top_get_physical_address(void)
36 {
37         static const u32 physical_addr[] = PHY_BASEADDR_DISPTOP_LIST;
38
39         return (u32)(physical_addr[0] + PHY_BASEADDR_DISPLAYTOP_MODULE_OFFSET);
40 }
41
42 u32 nx_disp_top_get_size_of_register_set(void)
43 {
44         return sizeof(struct nx_disp_top_register_set);
45 }
46
47 void nx_disp_top_set_base_address(void *base_address)
48 {
49         __g_module_variables.pregister =
50             (struct nx_disp_top_register_set *)base_address;
51 }
52
53 void *nx_disp_top_get_base_address(void)
54 {
55         return (void *)__g_module_variables.pregister;
56 }
57
58 void nx_disp_top_set_resconvmux(int benb, u32 sel)
59 {
60         register struct nx_disp_top_register_set *pregister;
61         u32 regvalue;
62
63         pregister = __g_module_variables.pregister;
64         regvalue = (benb << 31) | (sel << 0);
65         writel((u32)regvalue, &pregister->resconv_mux_ctrl);
66 }
67
68 void nx_disp_top_set_hdmimux(int benb, u32 sel)
69 {
70         register struct nx_disp_top_register_set *pregister;
71         u32 regvalue;
72
73         pregister = __g_module_variables.pregister;
74         regvalue = (benb << 31) | (sel << 0);
75         writel((u32)regvalue, &pregister->interconv_mux_ctrl);
76 }
77
78 void nx_disp_top_set_mipimux(int benb, u32 sel)
79 {
80         register struct nx_disp_top_register_set *pregister;
81         u32 regvalue;
82
83         pregister = __g_module_variables.pregister;
84         regvalue = (benb << 31) | (sel << 0);
85         writel((u32)regvalue, &pregister->mipi_mux_ctrl);
86 }
87
88 void nx_disp_top_set_lvdsmux(int benb, u32 sel)
89 {
90         register struct nx_disp_top_register_set *pregister;
91         u32 regvalue;
92
93         pregister = __g_module_variables.pregister;
94         regvalue = (benb << 31) | (sel << 0);
95         writel((u32)regvalue, &pregister->lvds_mux_ctrl);
96 }
97
98 void nx_disp_top_set_primary_mux(u32 sel)
99 {
100         register struct nx_disp_top_register_set *pregister;
101
102         pregister = __g_module_variables.pregister;
103         writel((u32)sel, &pregister->tftmpu_mux);
104 }
105
106 void nx_disp_top_hdmi_set_vsync_start(u32 sel)
107 {
108         register struct nx_disp_top_register_set *pregister;
109
110         pregister = __g_module_variables.pregister;
111         writel((u32)sel, &pregister->hdmisyncctrl0);
112 }
113
114 void nx_disp_top_hdmi_set_vsync_hsstart_end(u32 start, u32 end)
115 {
116         register struct nx_disp_top_register_set *pregister;
117
118         pregister = __g_module_variables.pregister;
119         writel((u32)(end << 16) | (start << 0), &pregister->hdmisyncctrl3);
120 }
121
122 void nx_disp_top_hdmi_set_hactive_start(u32 sel)
123 {
124         register struct nx_disp_top_register_set *pregister;
125
126         pregister = __g_module_variables.pregister;
127         writel((u32)sel, &pregister->hdmisyncctrl1);
128 }
129
130 void nx_disp_top_hdmi_set_hactive_end(u32 sel)
131 {
132         register struct nx_disp_top_register_set *pregister;
133
134         pregister = __g_module_variables.pregister;
135         writel((u32)sel, &pregister->hdmisyncctrl2);
136 }
137
138 void nx_disp_top_set_hdmifield(u32 enable, u32 init_val, u32 vsynctoggle,
139                                u32 hsynctoggle, u32 vsyncclr, u32 hsyncclr,
140                                u32 field_use, u32 muxsel)
141 {
142         register struct nx_disp_top_register_set *pregister;
143         u32 regvalue;
144
145         pregister = __g_module_variables.pregister;
146         regvalue = ((enable & 0x01) << 0) | ((init_val & 0x01) << 1) |
147                    ((vsynctoggle & 0x3fff) << 2) |
148                    ((hsynctoggle & 0x3fff) << 17);
149         writel(regvalue, &pregister->hdmifieldctrl);
150         regvalue = ((field_use & 0x01) << 31) | ((muxsel & 0x01) << 30) |
151                    ((hsyncclr) << 15) | ((vsyncclr) << 0);
152         writel(regvalue, &pregister->greg0);
153 }
154
155 void nx_disp_top_set_padclock(u32 mux_index, u32 padclk_cfg)
156 {
157         register struct nx_disp_top_register_set *pregister;
158         u32 regvalue;
159
160         pregister = __g_module_variables.pregister;
161         regvalue = readl(&pregister->greg1);
162         if (padmux_secondary_mlc == mux_index) {
163                 regvalue = regvalue & (~(0x7 << 3));
164                 regvalue = regvalue | (padclk_cfg << 3);
165         } else if (padmux_resolution_conv == mux_index) {
166                 regvalue = regvalue & (~(0x7 << 6));
167                 regvalue = regvalue | (padclk_cfg << 6);
168         } else {
169                 regvalue = regvalue & (~(0x7 << 0));
170                 regvalue = regvalue | (padclk_cfg << 0);
171         }
172         writel(regvalue, &pregister->greg1);
173 }
174
175 void nx_disp_top_set_lcdif_enb(int enb)
176 {
177         register struct nx_disp_top_register_set *pregister;
178         u32 regvalue;
179
180         pregister = __g_module_variables.pregister;
181         regvalue = readl(&pregister->greg1);
182         regvalue = regvalue & (~(0x1 << 9));
183         regvalue = regvalue | ((enb & 0x1) << 9);
184         writel(regvalue, &pregister->greg1);
185 }