1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #include "rgb.h"
20 #include <common.h>
21
22 #define IO_ADDRESS(x) (x)
23
24 #define SSP_BASE 0x120c1000
25 #define SSP_SIZE 0x1000
26 #define DEFAULT_MD_LEN 128
27
28 /* SSP register definition. */
29 #define SSP_CR0 IO_ADDRESS(SSP_BASE + 0x00)
30 #define SSP_CR1 IO_ADDRESS(SSP_BASE + 0x04)
31 #define SSP_DR IO_ADDRESS(SSP_BASE + 0x08)
32 #define SSP_SR IO_ADDRESS(SSP_BASE + 0x0C)
33 #define SSP_CPSR IO_ADDRESS(SSP_BASE + 0x10)
34 #define SSP_IMSC IO_ADDRESS(SSP_BASE + 0x14)
35 #define SSP_RIS IO_ADDRESS(SSP_BASE + 0x18)
36 #define SSP_MIS IO_ADDRESS(SSP_BASE + 0x1C)
37 #define SSP_ICR IO_ADDRESS(SSP_BASE + 0x20)
38 #define SSP_DMACR IO_ADDRESS(SSP_BASE + 0x24)
39
40 #define SPI_SR_BSY (0x1 << 4) /* spi busy flag */
41 #define SPI_SR_TFE (0x1 << 0) /* Whether to send fifo is empty */
42 #define SPI_DATA_WIDTH 9
43 #define SPI_SPO 1
44 #define SPI_SPH 1
45 #define SPI_SCR 8
46 #define SPI_CPSDVSR 8
47 #define SPI_FRAMEMODE 0
48
49 #define MAX_WAIT 10000
50
51 #define ssp_readw(addr, ret) ((ret) = (*(volatile unsigned int *)(addr)))
52 #define ssp_writew(addr, value) ((*(volatile unsigned int *)(addr)) = (value))
53
54 #if CONFIG_RGB_INTFACE
hi_spi_check_timeout(void)55 static int hi_spi_check_timeout(void)
56 {
57 unsigned int value = 0;
58 unsigned int tmp = 0;
59 while (1) {
60 ssp_readw(SSP_SR, value);
61 if ((value & SPI_SR_TFE) && (!(value & SPI_SR_BSY))) {
62 break;
63 }
64
65 if (tmp++ > MAX_WAIT) {
66 printf("spi transfer wait timeout!\n");
67 return -1;
68 }
69 udelay(1);
70 }
71 return 0;
72 }
73 #endif
74
hi_ssp_write_only(int is_write_only)75 static void hi_ssp_write_only(int is_write_only)
76 {
77 unsigned int ret = 0;
78
79 ssp_readw(SSP_CR1, ret);
80
81 ret = ret & (~(0x1 << 5)); /* bit5 */
82
83 ssp_writew(SSP_CR1, ret);
84 }
85
hi_ssp_enable(void)86 static void hi_ssp_enable(void)
87 {
88 unsigned int ret = 0;
89 ssp_readw(SSP_CR1, ret);
90 ret = (ret & 0xFFFD) | 0x2;
91
92 ret = ret | (0x1 << 4); /* 4 big/little end, 1: little, 0: big */
93
94 ret = ret | (0x1 << 15); /* 15 wait en */
95
96 ssp_writew(SSP_CR1, ret);
97
98 hi_ssp_write_only(0);
99 }
100
hi_ssp_disable(void)101 static void hi_ssp_disable(void)
102 {
103 unsigned int ret = 0;
104 ssp_readw(SSP_CR1, ret);
105 ret = ret & (~(0x1 << 1));
106 ssp_writew(SSP_CR1, ret);
107 }
108
hi_ssp_set_frameform(unsigned char framemode,unsigned char spo,unsigned char sph,unsigned char datawidth)109 static int hi_ssp_set_frameform(unsigned char framemode, unsigned char spo, unsigned char sph,
110 unsigned char datawidth)
111 {
112 unsigned int ret = 0;
113 ssp_readw(SSP_CR0, ret);
114 if (framemode > 3) { /* 3 frame mode */
115 printf("set frame parameter err.\n");
116 return -1;
117 }
118 ret = (ret & 0xFFCF) | (framemode << 4); /* 4 set frame mode */
119 if ((ret & 0x30) == 0) {
120 if (spo > 1) {
121 printf("set spo parameter err.\n");
122 return -1;
123 }
124 if (sph > 1) {
125 printf("set sph parameter err.\n");
126 return -1;
127 }
128 ret = (ret & 0xFF3F) | (sph << 7) | (spo << 6); /* 7 6 to set */
129 }
130 if ((datawidth > 16) || (datawidth < 4)) { /* data width should be 4 - 16 */
131 printf("set datawidth parameter err.\n");
132 return -1;
133 }
134 ret = (ret & 0xFFF0) | (datawidth - 1);
135 ssp_writew(SSP_CR0, ret);
136 return 0;
137 }
138
hi_ssp_set_serialclock(unsigned char scr,unsigned char cpsdvsr)139 static int hi_ssp_set_serialclock(unsigned char scr, unsigned char cpsdvsr)
140 {
141 unsigned int ret = 0;
142 ssp_readw(SSP_CR0, ret);
143 ret = (ret & 0xFF) | (scr << 8); /* 8 to set clk */
144 ssp_writew(SSP_CR0, ret);
145 if ((cpsdvsr & 0x1)) {
146 printf("set cpsdvsr parameter err.\n");
147 return -1;
148 }
149 ssp_writew(SSP_CPSR, cpsdvsr);
150 return 0;
151 }
152
hi_ssp_alt_mode_set(int enable)153 static int hi_ssp_alt_mode_set(int enable)
154 {
155 unsigned int ret = 0;
156
157 ssp_readw(SSP_CR1, ret);
158 if (enable) {
159 ret = ret & (~0x40);
160 } else {
161 ret = (ret & 0xFF) | 0x40;
162 }
163 ssp_writew(SSP_CR1, ret);
164
165 return 0;
166 }
167
168 #if CONFIG_RGB_INTFACE
spi_enable(void)169 static void spi_enable(void)
170 {
171 ssp_writew(SSP_CR1, 0x42);
172 }
173 #endif
174
spi_disable(void)175 static void spi_disable(void)
176 {
177 ssp_writew(SSP_CR1, 0x40);
178 }
179
180 #if CONFIG_RGB_INTFACE
spi_write_a8byte(unsigned char dat)181 static void spi_write_a8byte(unsigned char dat)
182 {
183 unsigned short spi_data;
184
185 spi_data = (unsigned short)dat;
186
187 spi_enable();
188 ssp_writew(SSP_DR, spi_data);
189 printf("spi_data:0x%x\n", spi_data);
190 udelay(10000); /* delay 10000 us */
191 spi_disable();
192 }
193
spi_write_a9byte(unsigned char cmd_dat,unsigned char dat)194 static void spi_write_a9byte(unsigned char cmd_dat, unsigned char dat)
195 {
196 unsigned short spi_data;
197 int ret;
198 if (cmd_dat) {
199 spi_data = 1 << 8; /* 8 data */
200 } else {
201 spi_data = 0 << 8; /* 8 data */
202 }
203
204 spi_data = spi_data | dat;
205 spi_enable();
206 ssp_writew(SSP_DR, spi_data);
207 ret = hi_spi_check_timeout();
208 if (ret != 0) {
209 printf("spi_send timeout\n");
210 }
211 spi_disable();
212 }
213
spi_write_a16byte(unsigned short spi_data)214 static void spi_write_a16byte(unsigned short spi_data)
215 {
216 spi_enable();
217 ssp_writew(SSP_DR, spi_data);
218 printf("spi_data:0x%x\n", spi_data);
219 udelay(10000); /* delay 10000 us */
220 spi_disable();
221 }
222
ssp_write_dat(unsigned char dat)223 static void ssp_write_dat(unsigned char dat)
224 {
225 spi_write_a9byte(1, dat);
226 }
227
ssp_write_cmd(unsigned char dat)228 static void ssp_write_cmd(unsigned char dat)
229 {
230 spi_write_a9byte(0, dat);
231 }
232 #endif
233
ssp_set(void)234 static void ssp_set(void)
235 {
236 spi_disable();
237 hi_ssp_set_frameform(SPI_FRAMEMODE, SPI_SPO, SPI_SPH, SPI_DATA_WIDTH);
238 hi_ssp_set_serialclock(SPI_SCR, SPI_CPSDVSR);
239 hi_ssp_alt_mode_set(1);
240 hi_ssp_enable();
241 }
242
rgb_reset(void)243 static void rgb_reset(void)
244 {
245 }
246
rgb_init_vertical(void)247 static void rgb_init_vertical(void)
248 {
249 return;
250 }
251
rgb_init_display(void)252 static void rgb_init_display(void)
253 {
254 /* spi_9bit_setting */
255 ssp_set();
256
257 rgb_reset();
258
259 rgb_init_vertical();
260
261 return;
262 }
263
rgb_setbacklight(void)264 static void rgb_setbacklight(void)
265 {
266 }
spi_config(void)267 void spi_config(void)
268 {
269 }
270
spi_pinmux(void)271 void spi_pinmux(void)
272 {
273 }
274
vo_rgb_pinmux(void)275 void vo_rgb_pinmux(void)
276 {
277 }
278
rgb_display(void)279 void rgb_display(void)
280 {
281 spi_config();
282
283 spi_pinmux();
284
285 vo_rgb_pinmux();
286
287 rgb_init_display();
288
289 rgb_setbacklight();
290
291 return;
292 }
293
rgb_stop(void)294 void rgb_stop(void)
295 {
296 hi_ssp_disable();
297
298 return;
299 }
300
301