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 /******************************************************************************
12  * 2016-1-14 All Winner Tech, All Right Reserved. 2014-2015 Copyright (c)
13  * File name   :     de_ase.c
14  * Description :     display engine 2.0 ase basic function definition
15  * History     :     2014/04/01  vito cheng  v0.1  Initial version
16  * 2014/04/25  vito cheng  v0.11 Add block updated function
17  ******************************************************************************/
18 
19 #ifdef CONFIG_DISP2_SUNXI_SUPPORT_ENAHNCE
20 #include "de_ase_type.h"
21 #include "de_rtmx.h"
22 #include "de_enhance.h"
23 
24 static volatile struct __ase_reg_t *ase_dev[DE_NUM][CHN_NUM];
25 static struct de_reg_blocks ase_block[DE_NUM][CHN_NUM];
26 
27 /*****************************************************************************
28  * function       : de_ase_set_reg_base(unsigned int sel, unsigned int chno,
29  *                       unsigned int base)
30  * description    : set ase reg base
31  * parameters     :
32  *                  sel         <rtmx select>
33  *                  chno        <overlay select>
34  *                  base        <reg base>
35  * return         :
36  *                  success
37  *****************************************************************************/
38 
de_ase_set_reg_base(unsigned int sel,unsigned int chno,void * base)39 int de_ase_set_reg_base(unsigned int sel, unsigned int chno, void *base)
40 {
41     ase_dev[sel][chno] = (struct __ase_reg_t *) base;
42 
43     return 0;
44 }
45 
de_ase_update_regs(unsigned int sel,unsigned int chno)46 int de_ase_update_regs(unsigned int sel, unsigned int chno)
47 {
48     if (ase_block[sel][chno].dirty == 0x1) {
49         regwrite((void *)ase_block[sel][chno].off,
50             ase_block[sel][chno].val, ase_block[sel][chno].size);
51         ase_block[sel][chno].dirty = 0x0;
52     }
53 
54     return 0;
55 }
56 
de_ase_init(unsigned int sel,unsigned int chno,uintptr_t reg_base)57 int de_ase_init(unsigned int sel, unsigned int chno, uintptr_t reg_base)
58 {
59     uintptr_t base;
60     void *memory;
61 
62     base = reg_base + (sel + 1) * 0x00100000 + ASE_OFST;
63 #if defined(CONFIG_ARCH_SUN50IW10)
64     if (sel)
65         base = base - 0x00100000;
66 #endif
67     /*FIXME  display path offset should be defined*/
68     DE_INF("sel %d, ase_base[%d]=0x%p\n", sel, chno, (void *)base);
69 
70     memory = disp_sys_malloc(sizeof(struct __ase_reg_t));
71     if (memory == NULL) {
72         DE_WRN("disp_sys_malloc ase[%d][%d] memory fail! size=0x%x\n", sel, chno,
73             (unsigned int)sizeof(struct __ase_reg_t));
74         return -1;
75     }
76 
77     ase_block[sel][chno].off = base;
78     ase_block[sel][chno].val = memory;
79     ase_block[sel][chno].size = 0x14;
80     ase_block[sel][chno].dirty = 0;
81 
82     de_ase_set_reg_base(sel, chno, memory);
83 
84     return 0;
85 }
86 
de_ase_exit(unsigned int sel,unsigned int chno)87 int de_ase_exit(unsigned int sel, unsigned int chno)
88 {
89     disp_sys_free(ase_block[sel][chno].val);
90 
91     return 0;
92 }
93 
94 /*****************************************************************************
95  * function       : de_ase_enable(unsigned int sel, unsigned int chno,
96  *                           unsigned int en)
97  * description    : enable/disable ase
98  * parameters     :
99  *                  sel         <rtmx select>
100  *                  chno        <overlay select>
101  *                  en          <enable: 0-disable; 1-enable>
102  * return         :
103  *                   success
104  ******************************************************************************/
de_ase_enable(unsigned int sel,unsigned int chno,unsigned int en)105 int de_ase_enable(unsigned int sel, unsigned int chno, unsigned int en)
106 {
107     ase_dev[sel][chno]->ctrl.bits.en = en;
108     ase_block[sel][chno].dirty = 1;
109     return 0;
110 }
111 
112 /*****************************************************************************
113  * function       : de_ase_set_size(unsigned int sel, unsigned int chno,
114  *                         unsigned int width, unsigned int height)
115  * description    : set ase size
116  * parameters     :
117  *                  sel         <rtmx select>
118  *                  chno        <overlay select>
119  *                  width       <input width>
120  *                  height  <input height>
121  * return         :
122  *                     success
123  ******************************************************************************/
de_ase_set_size(unsigned int sel,unsigned int chno,unsigned int width,unsigned int height)124 int de_ase_set_size(unsigned int sel, unsigned int chno, unsigned int width,
125                 unsigned int height)
126 {
127     ase_dev[sel][chno]->size.bits.width = width - 1;
128     ase_dev[sel][chno]->size.bits.height = height - 1;
129     ase_block[sel][chno].dirty = 1;
130     return 0;
131 }
132 
133 /*****************************************************************************
134  * function       : de_ase_set_window(unsigned int sel, unsigned int chno,
135  *                   unsigned int win_enable, struct de_rect window)
136  * description    : set ase window
137  * parameters     :
138  *                  sel         <rtmx select>
139  *                  chno        <overlay select>
140  *                  win_enable  <enable: 0-window mode disable;
141  *                  1-window mode enable>
142  *                  window  <window rectangle>
143  * return         :
144  *                  success
145  ******************************************************************************/
de_ase_set_window(unsigned int sel,unsigned int chno,unsigned int win_enable,struct de_rect window)146 int de_ase_set_window(unsigned int sel, unsigned int chno,
147                     unsigned int win_enable,
148                     struct de_rect window)
149 {
150     ase_dev[sel][chno]->ctrl.bits.win_en = win_enable;
151 
152     if (win_enable) {
153         ase_dev[sel][chno]->win0.bits.left = window.x;
154         ase_dev[sel][chno]->win0.bits.top = window.y;
155         ase_dev[sel][chno]->win1.bits.right = window.x + window.w - 1;
156         ase_dev[sel][chno]->win1.bits.bot = window.y + window.h - 1;
157     }
158     ase_block[sel][chno].dirty = 1;
159     return 0;
160 }
161 
162 /*****************************************************************************
163  * function       : de_ase_set_para(unsigned int sel, unsigned int chno,
164  *                  unsigned int gain)
165  * description    : set ase para
166  * parameters     :
167  *                  sel         <rtmx select>
168  *                  chno        <overlay select>
169  *                  gain        <ase gain: normal setting 16-24>
170  * return         :
171  *                  success
172  ******************************************************************************/
de_ase_set_para(unsigned int sel,unsigned int chno,unsigned int gain)173 int de_ase_set_para(unsigned int sel, unsigned int chno, unsigned int gain)
174 {
175     ase_dev[sel][chno]->gain.bits.gain = gain;
176     ase_block[sel][chno].dirty = 1;
177     return 0;
178 }
179 
180 /**
181  * function       : de_ase_info2para
182  * description    : info->para conversion
183  * parameters     :
184  *                  auto_color  <gain info from user>
185  *                  window              <window info>
186  *                  para                <bsp para>
187  * return         :
188  *                  success
189  */
de_ase_info2para(unsigned int auto_color,struct de_rect window,struct __ase_config_data * para)190 int de_ase_info2para(unsigned int auto_color, struct de_rect window,
191                  struct __ase_config_data *para)
192 {
193     int ase_mode;
194     int ase_para[ASE_PARA_NUM][ASE_MODE_NUM] = {
195         {0, 12, 16, 20}
196     };
197 
198     ase_mode = ((auto_color >> 4) & 0xf) ? 1 : 0;
199     para->ase_en = ase_mode ? 1 : 0;
200     para->gain = ase_para[0][ase_mode];
201 
202     return 0;
203 }
204 #endif
205