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