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
nx_disp_top_initialize(void)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
nx_disp_top_get_number_of_module(void)30 u32 nx_disp_top_get_number_of_module(void)
31 {
32 return NUMBER_OF_DISPTOP_MODULE;
33 }
34
nx_disp_top_get_physical_address(void)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
nx_disp_top_get_size_of_register_set(void)42 u32 nx_disp_top_get_size_of_register_set(void)
43 {
44 return sizeof(struct nx_disp_top_register_set);
45 }
46
nx_disp_top_set_base_address(void * base_address)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
nx_disp_top_get_base_address(void)53 void *nx_disp_top_get_base_address(void)
54 {
55 return (void *)__g_module_variables.pregister;
56 }
57
nx_disp_top_set_resconvmux(int benb,u32 sel)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
nx_disp_top_set_hdmimux(int benb,u32 sel)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
nx_disp_top_set_mipimux(int benb,u32 sel)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
nx_disp_top_set_lvdsmux(int benb,u32 sel)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
nx_disp_top_set_primary_mux(u32 sel)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
nx_disp_top_hdmi_set_vsync_start(u32 sel)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
nx_disp_top_hdmi_set_vsync_hsstart_end(u32 start,u32 end)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
nx_disp_top_hdmi_set_hactive_start(u32 sel)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
nx_disp_top_hdmi_set_hactive_end(u32 sel)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
nx_disp_top_set_hdmifield(u32 enable,u32 init_val,u32 vsynctoggle,u32 hsynctoggle,u32 vsyncclr,u32 hsyncclr,u32 field_use,u32 muxsel)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
nx_disp_top_set_padclock(u32 mux_index,u32 padclk_cfg)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
nx_disp_top_set_lcdif_enb(int enb)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 }
186