]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/ipu/arm/imx/v1_0/src/ipu_dma.c
TX51 pre-release
[karo-tx-redboot.git] / packages / devs / ipu / arm / imx / v1_0 / src / ipu_dma.c
1 //==========================================================================
2 //
3 //      IPU_COMMON.c
4 //
5 //      common functions definitions for IPU modules operation
6 //
7 //==========================================================================
8 //#####DESCRIPTIONBEGIN####
9 //
10 // Author(s):       Ray Sun <Yanfei.Sun@freescale.com>
11 // Create Date: 2008-07-31
12 //
13 //####DESCRIPTIONEND####
14 //
15 //==========================================================================
16
17 #include <string.h>
18 #include <cyg/io/ipu_common.h>
19
20 void ipu_idmac_params_init(ipu_channel_parameter_t *ipu_channel_params_ptr)
21 {
22         memset(ipu_channel_params_ptr, 0, sizeof(ipu_channel_parameter_t));
23 }
24
25 /*
26 * config the dma channel to be interleaved mode
27 */
28 void ipu_idmac_interleaved_channel_config(ipu_channel_parameter_t ipu_channel_params)
29 {
30         int w0_d0 = 0, w0_d1 = 0, w0_d2 = 0, w0_d3 = 0, w0_d4 = 0, w1_d0 = 0, w1_d1 = 0, w1_d2 =
31                 0, w1_d3 = 0, w1_d4 = 0;
32
33         w0_d0 = ipu_channel_params.xb << 19 | ipu_channel_params.yv << 10 | ipu_channel_params.xv;
34         w0_d1 =
35                 ipu_channel_params.sy << 26 | ipu_channel_params.sx << 14 | ipu_channel_params.
36                 cf << 13 | ipu_channel_params.nsb_b << 12 | ipu_channel_params.yb;
37         w0_d2 =
38                 ipu_channel_params.sm << 22 | ipu_channel_params.sdx << 15 | ipu_channel_params.
39                 ns << 5 | ipu_channel_params.sy >> 6;
40         w0_d3 =
41                 ipu_channel_params.fw << 29 | ipu_channel_params.cae << 28 | ipu_channel_params.
42                 cap << 27 | ipu_channel_params.the << 26 | ipu_channel_params.vf << 25 | ipu_channel_params.
43                 hf << 24 | ipu_channel_params.rot << 23 | ipu_channel_params.bm << 21 | ipu_channel_params.
44                 bndm << 18 | ipu_channel_params.so << 17 | ipu_channel_params.
45                 dim << 16 | ipu_channel_params.dec_sel << 14 | ipu_channel_params.
46                 bpp << 11 | ipu_channel_params.sdry << 10 | ipu_channel_params.
47                 sdrx << 9 | ipu_channel_params.sdy << 2 | ipu_channel_params.sce << 1 | ipu_channel_params.
48                 scc;
49         w0_d4 = ipu_channel_params.fh << 10 | ipu_channel_params.fw >> 3;
50
51         w1_d0 = ipu_channel_params.eba1 << 29 | ipu_channel_params.eba0;
52         w1_d1 = ipu_channel_params.ilo << 26 | ipu_channel_params.eba1 >> 3;
53         w1_d2 =
54                 ipu_channel_params.th << 31 | ipu_channel_params.id << 29 | ipu_channel_params.
55                 albm << 26 | ipu_channel_params.alu << 25 | ipu_channel_params.
56                 pfs << 21 | ipu_channel_params.npb << 14 | ipu_channel_params.ilo >> 6;
57         w1_d3 =
58                 ipu_channel_params.wid3 << 29 | ipu_channel_params.wid2 << 26 | ipu_channel_params.
59                 wid1 << 23 | ipu_channel_params.wid0 << 20 | ipu_channel_params.
60                 sl << 6 | ipu_channel_params.th >> 1;
61         w1_d4 =
62                 ipu_channel_params.ofs3 << 15 | ipu_channel_params.ofs2 << 10 | ipu_channel_params.
63                 ofs1 << 5 | ipu_channel_params.ofs0;
64
65         /* config the cpmem */
66         writel(w0_d0,
67                 IPU_CTRL_BASE_ADDR + CPMEM_WORD0_DATA0_INT__ADDR + (ipu_channel_params.channel << 6));
68         writel(w0_d1,
69                 IPU_CTRL_BASE_ADDR + CPMEM_WORD0_DATA1_INT__ADDR + (ipu_channel_params.channel << 6));
70         writel(w0_d2,
71                 IPU_CTRL_BASE_ADDR + CPMEM_WORD0_DATA2_INT__ADDR + (ipu_channel_params.channel << 6));
72         writel(w0_d3,
73                 IPU_CTRL_BASE_ADDR + CPMEM_WORD0_DATA3_INT__ADDR + (ipu_channel_params.channel << 6));
74         writel(w0_d4,
75                 IPU_CTRL_BASE_ADDR + CPMEM_WORD0_DATA4_INT__ADDR + (ipu_channel_params.channel << 6));
76
77         writel(w1_d0,
78                 IPU_CTRL_BASE_ADDR + CPMEM_WORD1_DATA0_INT__ADDR + (ipu_channel_params.channel << 6));
79         writel(w1_d1,
80                 IPU_CTRL_BASE_ADDR + CPMEM_WORD1_DATA1_INT__ADDR + (ipu_channel_params.channel << 6));
81         writel(w1_d2,
82                 IPU_CTRL_BASE_ADDR + CPMEM_WORD1_DATA2_INT__ADDR + (ipu_channel_params.channel << 6));
83         writel(w1_d3,
84                 IPU_CTRL_BASE_ADDR + CPMEM_WORD1_DATA3_INT__ADDR + (ipu_channel_params.channel << 6));
85         writel(w1_d4,
86                 IPU_CTRL_BASE_ADDR + CPMEM_WORD1_DATA4_INT__ADDR + (ipu_channel_params.channel << 6));
87 }
88
89 void ipu_idmac_channel_buf_ready(int channel, int buf)
90 {
91         int idx = channel / 32;
92         int offset = channel % 32;
93         if (idx) {
94                 if (buf) {
95                         ipu_write_field(IPU_IPU_GPR__IPU_CH_BUF1_RDY1_CLR, 0);
96                         ipu_write_field(IPU_IPU_CH_BUF1_RDY1__ADDR, 1 << offset, 1);
97                 } else {
98                         ipu_write_field(IPU_IPU_GPR__IPU_CH_BUF0_RDY1_CLR, 0);
99                         ipu_write_field(IPU_IPU_CH_BUF0_RDY1__ADDR, 1 << offset, 1);
100                 }
101         } else {
102                 if (buf) {
103                         ipu_write_field(IPU_IPU_GPR__IPU_CH_BUF1_RDY0_CLR, 0);
104                         ipu_write_field(IPU_IPU_CH_BUF1_RDY0__ADDR, 1 << offset, 1);
105                 } else {
106                         ipu_write_field(IPU_IPU_GPR__IPU_CH_BUF0_RDY0_CLR, 0);
107                         ipu_write_field(IPU_IPU_CH_BUF0_RDY0__ADDR, 1 << offset, 1);
108                 }
109         }
110 }
111
112 void ipu_idmac_channel_mode_sel(int channel, int double_buf_en)
113 {
114         int idx = channel / 32;
115         int offset = channel % 32;
116         ipu_write_field(IPU_IPU_CH_DB_MODE_SEL_0__ADDR + idx * 4, 1 << offset, double_buf_en);
117 }
118
119 void ipu_idmac_channel_enable(int channel, int enable)
120 {
121         int idx = channel / 32;
122         int offset = channel % 32;
123         ipu_write_field(IPU_IDMAC_CH_EN_1__ADDR + idx * 4, 1 << offset, enable);
124 }
125
126 int ipu_idmac_channel_busy(int channel)
127 {
128         int idx, offset;
129         idx = channel / 32;
130         offset = channel % 32;
131         return ((readl(IPU_CTRL_BASE_ADDR + IPU_IDMAC_CH_BUSY_1__ADDR + 4 * idx) & (1 << offset)) >>
132                         offset);
133 }
134
135 int ipu_idmac_chan_cur_buff(int channel)
136 {
137         int idx, offset;
138         idx = channel / 32;
139         offset = channel % 32;
140         return ((readl(IPU_CTRL_BASE_ADDR + IPU_IPU_CUR_BUF_0__ADDR + 4 * idx) & (1 << offset)) >>
141                         offset);
142 }
143
144 int ipu_idamc_chan_eof_int(int channel)
145 {
146         int idx, offset;
147         idx = channel / 32;
148         offset = channel % 32;
149         return ((readl(IPU_CTRL_BASE_ADDR + IPU_IPU_INT_STAT_1__ADDR + 4 * idx) & (1 << offset)) >>
150                         offset);
151 }
152
153 int ipu_idmac_chan_till_idle(int channel, int timeout)
154 {
155         int i = 0;
156         unsigned int chanBusy;
157
158         while (i < timeout) {
159                 chanBusy = ipu_idmac_channel_busy(channel);
160                 if (!chanBusy) {
161 //          diag_printf("\ncount cycles:%d\n",i);
162                         __asm("nop");
163                         return 0;
164                 }
165                 i++;
166         }
167         ERRDP("can not get channel %d idle state\n", channel);
168         return -1;
169 }
170
171 /*
172 * allocate dmfc fifo for ipu display channel
173 */
174 int ipu_dmfc_fifo_allocate(int channel, int fifo_size, int burst_size, int offset_addr)
175 {
176
177         if (fifo_size > 7 || fifo_size < 0) {
178                 ERRDP("FIFO size is wrong! range from 0 to 7.\n");
179                 return -1;
180         }
181         if (burst_size > 3 || burst_size < 0) {
182                 ERRDP("Burst size is wrong! range from 0 to 3.\n");
183                 return -1;
184         }
185         if (offset_addr < 0 || offset_addr > 7) {
186                 ERRDP("Start addr of FIFO is wrong! range from 0 to 7.\n");
187                 return -1;
188         }
189         switch (channel) {
190         case 28:
191                 ipu_write_field(IPU_DMFC_WR_CHAN__DMFC_FIFO_SIZE_1, fifo_size);
192                 ipu_write_field(IPU_DMFC_WR_CHAN__DMFC_BURST_SIZE_1, burst_size);
193                 ipu_write_field(IPU_DMFC_WR_CHAN__DMFC_ST_ADDR_1, offset_addr);
194                 ipu_write_field(IPU_DMFC_WR_CHAN_DEF__DMFC_WM_CLR_1, 0);
195                 ipu_write_field(IPU_DMFC_WR_CHAN_DEF__DMFC_WM_SET_1, 0);
196                 ipu_write_field(IPU_DMFC_WR_CHAN_DEF__DMFC_WM_EN_1, 0);
197                 ipu_write_field(IPU_DMFC_GENERAL1__WAIT4EOT_1, 0);
198                 break;
199
200         case 23:
201                 ipu_write_field(IPU_DMFC_DP_CHAN__DMFC_FIFO_SIZE_5B, fifo_size);
202                 ipu_write_field(IPU_DMFC_DP_CHAN__DMFC_BURST_SIZE_5B, burst_size);
203                 ipu_write_field(IPU_DMFC_DP_CHAN__DMFC_ST_ADDR_5B, offset_addr);
204                 ipu_write_field(IPU_DMFC_DP_CHAN_DEF__DMFC_WM_CLR_5B, 0);
205                 ipu_write_field(IPU_DMFC_DP_CHAN_DEF__DMFC_WM_SET_5B, 0);
206                 ipu_write_field(IPU_DMFC_DP_CHAN_DEF__DMFC_WM_EN_5B, 0);
207                 ipu_write_field(IPU_DMFC_GENERAL1__WAIT4EOT_5B, 0);
208                 break;
209
210         case 27:
211                 ipu_write_field(IPU_DMFC_DP_CHAN__DMFC_FIFO_SIZE_5F, fifo_size);
212                 ipu_write_field(IPU_DMFC_DP_CHAN__DMFC_BURST_SIZE_5F, burst_size);
213                 ipu_write_field(IPU_DMFC_DP_CHAN__DMFC_ST_ADDR_5F, offset_addr);
214                 ipu_write_field(IPU_DMFC_DP_CHAN_DEF__DMFC_WM_CLR_5F, 0);
215                 ipu_write_field(IPU_DMFC_DP_CHAN_DEF__DMFC_WM_SET_5F, 0);
216                 ipu_write_field(IPU_DMFC_DP_CHAN_DEF__DMFC_WM_EN_5F, 0);
217                 ipu_write_field(IPU_DMFC_GENERAL1__WAIT4EOT_5F, 0);
218                 break;
219         default:
220                 ERRDP("Channel selection error!!\n");
221                 return -1;
222         }
223         return 0;
224 }