1 /*
2 * Allwinner SoCs display driver.
3 *
4 * Copyright (C) 2016 Allwinner.
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11 #include "de_eink.h"
12
13 #define EE_CTL (0x000)
14 #define EE_IRQ (0x004)
15 #define EE_IDX_GEN (0x008)
16 #define EE_IMG_SIZE (0x00c)
17 #define EE_LAST_IMG_ADDR (0x010)
18 #define EE_LAST_IMG_PITCH (0x014)
19 #define EE_CURR_IMG_ADDR (0x018)
20 #define EE_CURR_IMG_PITCH (0x01c)
21 #define EE_LAST_IDX_ADDR (0x020)
22 #define EE_IDX_WIN0 (0x024)
23 #define EE_IDX_WIN1 (0x028)
24 #define EE_NEW_IDX_ADDR (0x02c)
25
26 #define EE_PIPE_EN (0x040)
27 #define EE_PIPE_WIN0 (0x044)
28 #define EE_PIPE_WIN1 (0x048)
29 #define EE_WAV_FILE_ADDR (0x04c)
30
31 #define EE_DEC_CTL (0x150)
32 #define EE_DEC_IDX_ADDR (0x154)
33 #define EE_DEC_WAV_ADDR (0x158)
34 #define EE_DEC_WAV_PITCH (0x15c)
35
36 #define EDMA_GLB_CTL (0x400)
37 #define EDMA_CTL (0x404)
38 #define EDMA_WAV_ADDR (0x408)
39 #define EDMA_WAV_PITCH (0x40c)
40 #define EDMA_WAV_SIZE (0x410)
41 #define EDMA_IMG_COOR (0x414)
42 #define EDMA_IMG_SIZE (0x418)
43 #define EDMA_PIXEL_VALUE (0x41c)
44
45 #define EDMA_WB_ADDR (0x440)
46 #define EDMA_WB_STS (0x444)
47
48 static unsigned long ee_base;
49
50 /* #define ee_writel writel */
51 /* #define ee_readl readl */
52 #define EINK_RUINT32(offset) (*((volatile u32 *)((offset))))
53 #define EINK_WUINT32(value, offset) (*((volatile u32 *)((offset))) = (value))
54
55
56 extern s32 disp_delay_us(u32 us);
57 extern s32 disp_delay_ms(u32 ms);
58
eink_set_base(unsigned long reg_base)59 int eink_set_base(unsigned long reg_base)
60 {
61 ee_base = reg_base;
62
63 return 0;
64 }
65 /*
66 *int eink_set_mode(unsigned char in_mode, unsigned char out_mode)
67 *{
68 * unsigned int tmp;
69 *
70 * tmp = ((out_mode&0x1)<<4)|(in_mode&0x3);
71 * EINK_WUINT32(tmp,ee_base + EE_CTL);
72 *
73 * return 0;
74 *
75 *}
76 */
eink_config(unsigned char in_mode,unsigned int out_mode)77 s32 eink_config(unsigned char in_mode, unsigned int out_mode)
78 {
79 unsigned int tmp;
80
81 tmp = ((out_mode&0x1)<<4)|(in_mode&0x3);
82 EINK_WUINT32(tmp, ee_base + EE_CTL);
83
84 return 0;
85 }
86
eink_irq_enable(void)87 int eink_irq_enable(void)
88 {
89 EINK_WUINT32(1<<4, ee_base + EE_IRQ);
90
91 /* unsigned int tmp;
92 * tmp = EINK_RUINT32(ee_base + EE_IRQ);
93 * pr_info("eink_irq_en 0x%x\n", tmp);
94 */
95 return 0;
96 }
97
eink_irq_disable(void)98 int eink_irq_disable(void)
99 {
100 EINK_WUINT32(0, ee_base + EE_IRQ);
101
102 return 0;
103 }
104
eink_irq_query(void)105 int eink_irq_query(void)
106 {
107 unsigned int idx_irq, dec_irq;
108 unsigned reg_val = 0;
109
110 reg_val = EINK_RUINT32(ee_base + EE_IRQ);
111 dec_irq = reg_val&0x1;
112 idx_irq = reg_val&0x2;
113
114 if (dec_irq == 0x1) {
115 EINK_WUINT32(reg_val&0x1d, ee_base + EE_IRQ);
116 return 0;
117 }
118 if (idx_irq == 0x2) {
119 EINK_WUINT32(reg_val&0x1e, ee_base + EE_IRQ);
120 return 1;
121 }
122 return -1;
123 }
124
eink_irq_query_index(void)125 int eink_irq_query_index(void)
126 {
127 unsigned int idx_irq;
128 unsigned reg_val = 0;
129
130 reg_val = EINK_RUINT32(ee_base + EE_IRQ);
131 idx_irq = reg_val&0x2;
132
133 if (idx_irq == 0x2) {
134 EINK_WUINT32(reg_val&0x1e, ee_base + EE_IRQ);
135 return 1;
136 }
137 return -1;
138
139 }
140
141 /*
142 int eink_start_idx (u32 disp, u32 old_index_data_paddr,
143 u32 new_index_data_paddr, struct ee_img* last_image,
144 struct ee_img* current_image, unsigned char flash_mode,
145 unsigned char win_en, struct area_info* area)
146 {
147 return 0;
148
149 }
150 */
151
eink_start_idx(struct ee_img * last_img,struct ee_img * curr_img,unsigned char flash_mode,unsigned char win_en,unsigned long last_idx_addr,unsigned long curr_idx_addr,struct area_info * info)152 int eink_start_idx(struct ee_img *last_img, struct ee_img *curr_img,
153 unsigned char flash_mode, unsigned char win_en,
154 unsigned long last_idx_addr, unsigned long curr_idx_addr,
155 struct area_info *info)
156 {
157 unsigned int tmp, w, h;
158 unsigned int x, y;
159
160 x = 0;
161 y = 0;
162 w = last_img->w?(last_img->w-1)&0xfff:0;
163 h = last_img->h?(last_img->h-1)&0xfff:0;
164 tmp = ((h<<16)|w);
165 EINK_WUINT32(tmp, ee_base + EE_IMG_SIZE);
166 /* tmp = last_img->y*last_img->pitch + last_img->x + last_img->addr; */
167 tmp = y*last_img->pitch + x + last_img->addr;
168 EINK_WUINT32(tmp, ee_base + EE_LAST_IMG_ADDR);
169 EINK_WUINT32(last_img->pitch, ee_base + EE_LAST_IMG_PITCH);
170
171 /* tmp = curr_img->y*curr_img->pitch + curr_img->x + curr_img->addr; */
172
173 tmp = y*curr_img->pitch + x + curr_img->addr;
174 EINK_WUINT32(tmp, ee_base + EE_CURR_IMG_ADDR);
175 EINK_WUINT32(curr_img->pitch, ee_base + EE_CURR_IMG_PITCH);
176
177 if (!win_en) {
178 tmp = ((info->y_top&0xfff)<<16)|(info->x_top&0xfff);
179 EINK_WUINT32(tmp, ee_base + EE_IDX_WIN0);
180 tmp = ((info->y_bottom&0xfff)<<16)|(info->x_bottom&0xfff);
181 EINK_WUINT32(tmp, ee_base + EE_IDX_WIN1);
182 }
183
184 EINK_WUINT32(last_idx_addr, ee_base + EE_LAST_IDX_ADDR);
185 EINK_WUINT32(curr_idx_addr, ee_base + EE_NEW_IDX_ADDR);
186
187 tmp = (flash_mode&0x3)<<8;
188 tmp |= (win_en&0x1)<<4;
189 tmp |= 0x1;
190 EINK_WUINT32(tmp, ee_base + EE_IDX_GEN);
191
192 return 0;
193 }
194
eink_index_finish(void)195 int eink_index_finish(void)
196 {
197 unsigned int reg_val;
198
199 reg_val = EINK_RUINT32(ee_base + EE_IRQ)&0x2;
200 if (reg_val == 0x2)
201 return 1;
202 else
203 return 0;
204 }
205
eink_get_updata_area(struct area_info * info)206 int eink_get_updata_area(struct area_info *info)
207 {
208 unsigned int reg_val;
209
210 reg_val = EINK_RUINT32(ee_base + EE_IDX_WIN0);
211 info->x_top = reg_val & 0xfff;
212 info->y_top = (reg_val >> 16) & 0xfff;
213
214 reg_val = EINK_RUINT32(ee_base + EE_IDX_WIN1);
215 info->x_bottom = reg_val & 0xfff;
216 info->y_bottom = (reg_val >> 16) & 0xfff;
217
218 return 0;
219 }
220
eink_pipe_enable(unsigned int pipe_no)221 int eink_pipe_enable(unsigned int pipe_no)
222 {
223 unsigned int pipe_base;
224 unsigned int reg_val;
225
226 pipe_base = ee_base + EE_PIPE_EN + (pipe_no << 4);
227 EINK_WUINT32(0x1, pipe_base);
228
229 reg_val = EINK_RUINT32(pipe_base);
230 return 0;
231 }
232
eink_pipe_disable(unsigned int pipe_no)233 int eink_pipe_disable(unsigned int pipe_no)
234 {
235 unsigned int pipe_base;
236
237 pipe_base = ee_base + EE_PIPE_EN + (pipe_no << 4);
238 EINK_WUINT32(0x0, pipe_base);
239
240 return 0;
241 }
242
eink_pipe_config(struct area_info * info,unsigned int pipe_no)243 int eink_pipe_config(struct area_info *info, unsigned int pipe_no)
244 {
245 unsigned int pipe_base, tmp;
246
247 tmp = ((info->y_top & 0xfff) << 16)|(info->x_top & 0xfff);
248 pipe_base = ee_base + EE_PIPE_WIN0 + (pipe_no << 4);
249 EINK_WUINT32(tmp, pipe_base);
250
251 tmp = ((info->y_bottom & 0xfff) << 16)|(info->x_bottom & 0xfff);
252 pipe_base = ee_base + EE_PIPE_WIN1 + (pipe_no << 4);
253 EINK_WUINT32(tmp, pipe_base);
254 /*
255 * pipe_base = ee_base + EE_WAV_FILE_ADDR + (pipe_no<<4);
256 * EINK_WUINT32(wav_file_addr,pipe_base);
257 */
258 return 0;
259 }
260
eink_pipe_config_wavefile(unsigned long wav_file_addr,unsigned int pipe_no)261 int eink_pipe_config_wavefile(unsigned long wav_file_addr, unsigned int pipe_no)
262 {
263 unsigned int pipe_base;
264
265 pipe_base = ee_base + EE_WAV_FILE_ADDR + (pipe_no << 4);
266 EINK_WUINT32(wav_file_addr, pipe_base);
267
268
269 return 0;
270 }
271
eink_decoder_start(unsigned long new_idx_addr,unsigned long wav_data_addr,struct eink_init_param * para)272 int eink_decoder_start(unsigned long new_idx_addr, unsigned long wav_data_addr,
273 struct eink_init_param *para)
274 {
275 unsigned int w, h, tmp;
276
277 w = para->timing.width ? (para->timing.width - 1) & 0xfff : 0;
278 h = para->timing.height ? (para->timing.height - 1) & 0xfff : 0;
279 tmp = ((h << 16) | w);
280 EINK_WUINT32(tmp, ee_base + EE_IMG_SIZE);
281
282 tmp = para->eink_mode ? (((para->timing.lbl + para->timing.lsl +
283 para->timing.lel) << 2) +
284 (para->timing.width >> 1)) :
285 (((para->timing.lbl + para->timing.lsl +
286 para->timing.lel) << 1) +
287 (para->timing.width >> 1));
288 EINK_WUINT32(tmp, ee_base + EE_DEC_WAV_PITCH);
289 EINK_WUINT32(new_idx_addr, ee_base + EE_DEC_IDX_ADDR);
290
291 tmp = para->eink_mode ? ((para->timing.fbl + para->timing.fsl) * tmp +
292 ((para->timing.lbl + para->timing.lsl) << 2)) :
293 ((para->timing.fbl + para->timing.fsl) * tmp +
294 ((para->timing.lbl + para->timing.lsl) << 1));
295
296 tmp += wav_data_addr;
297 EINK_WUINT32(tmp, ee_base + EE_DEC_WAV_ADDR);
298
299 EINK_WUINT32(0x1, ee_base + EE_DEC_CTL);
300
301 return 0;
302 }
303
eink_edma_init(unsigned char mode)304 int eink_edma_init(unsigned char mode)
305 {
306 unsigned int tmp;
307
308 tmp = 0x1<<31;
309 tmp |= (mode<<4);
310 tmp |= 0x1;
311 EINK_WUINT32(tmp, ee_base + EDMA_CTL);
312
313 tmp = 0x1<<31;
314
315
316 /* tmp |= (0x1<<16); */
317 EINK_WUINT32(tmp, ee_base + EDMA_GLB_CTL);
318 /* tmp = EINK_RUINT32(ee_base + EDMA_GLB_CTL);*/
319 /* eink_dbuf_rdy(); */
320 return 0;
321 }
322
eink_edma_cfg(unsigned long wav_addr,struct eink_init_param * para)323 int eink_edma_cfg(unsigned long wav_addr, struct eink_init_param *para)
324 {
325 unsigned int tmp, w, h, hsync, vsync;
326
327 EINK_WUINT32(wav_addr, ee_base + EDMA_WAV_ADDR);
328 hsync = para->timing.lbl + para->timing.lsl + para->timing.lel;
329 vsync = para->timing.fbl + para->timing.fsl + para->timing.fel;
330
331 tmp = para->eink_mode ? (hsync << 3) : (hsync << 2);
332 EINK_WUINT32(((para->timing.width + tmp) >> 1),
333 ee_base + EDMA_WAV_PITCH);
334 w = para->timing.width + tmp;
335 w = w ? (w - 1) : 0;
336 h = para->timing.height + vsync;
337 h = h ? (h-1) : 0;
338 tmp = (h << 16) | w;
339 EINK_WUINT32(tmp, ee_base + EDMA_WAV_SIZE);
340
341 tmp = (para->timing.lbl + para->timing.lsl);
342 tmp = para->eink_mode ? (tmp << 3) : (tmp << 2);
343 tmp = ((para->timing.fbl + para->timing.fsl) << 16) | tmp;
344 EINK_WUINT32(tmp, ee_base + EDMA_IMG_COOR);
345 w = para->timing.width ? (para->timing.width - 1) : 0;
346 h = para->timing.height ? (para->timing.height - 1) : 0;
347 tmp = (h << 16) | w;
348 EINK_WUINT32(tmp, ee_base + EDMA_IMG_SIZE);
349
350 return 0;
351 }
352
eink_edma_cfg_addr(unsigned long wav_addr)353 int eink_edma_cfg_addr(unsigned long wav_addr)
354 {
355
356 EINK_WUINT32(wav_addr, ee_base + EDMA_WAV_ADDR);
357 /*
358 * tmp = 0x1<<31;
359 * tmp |= (0x1<<16);
360 * tmp |= 0x1;
361 * EINK_WUINT32(tmp,ee_base + EDMA_GLB_CTL);
362 */
363 return 0;
364 }
365
366
eink_edma_en(unsigned char en)367 int eink_edma_en(unsigned char en)
368 {
369 unsigned int tmp;
370
371 tmp = EINK_RUINT32(ee_base + EDMA_CTL);
372 tmp |= en & 0x1;
373 EINK_WUINT32(tmp, ee_base + EDMA_CTL);
374
375 return 0;
376 }
377
eink_dbuf_rdy(void)378 int eink_dbuf_rdy(void)
379 {
380 unsigned int tmp;
381
382 tmp = 0x1 << 31;
383 tmp |= (0x1 << 16);
384 tmp |= 0x1;
385 EINK_WUINT32(tmp, ee_base + EDMA_GLB_CTL);
386
387 return 0;
388 }
389
390 /* wb_en: default :0, enablen write back for debug */
eink_set_wb(unsigned char wb_en,unsigned long wb_addr)391 int eink_set_wb(unsigned char wb_en, unsigned long wb_addr)
392 {
393 unsigned int tmp;
394
395 tmp = 0x1 << 31;
396 tmp |= (0x1 << 16);
397 tmp |= wb_en ? (0x3 << 8) : 0x0;
398 tmp |= 0x1;
399 EINK_WUINT32(tmp, ee_base + EDMA_GLB_CTL);
400 EINK_WUINT32(wb_addr, ee_base + EDMA_WB_ADDR);
401
402 return 0;
403 }
404
405
406