4 * Copyright (C) 2007 OpenMoko, Inc.
5 * Author: Chia-I Wu <olv@openmoko.org>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 or
10 * (at your option) version 3 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 #define DMA_CMDQ_SIZE (1 * 1024)
32 static void dma_cmdq_init(struct glamo_dma_manager
*dma
)
36 cmdq_len
= (DMA_CMDQ_SIZE
>> 10) - 1;
38 dma
->cmdq
= (GLAMO_REG_TYPE
*) (glamo_fb
+ GLAMO_VRAM_CMDQ
);
39 dma
->size
= DMA_CMDQ_SIZE
;
43 dma
->cmdq
[dma
->size
>> 1] = 0x0;
44 dma
->cmdq
[(dma
->size
>> 1) + 1] = 0x0;
46 glamo_hw_engine_enable(GLAMO_ENGINE_CMDQ
);
47 glamo_hw_engine_reset(GLAMO_ENGINE_CMDQ
);
49 GLAMO_OUT_REG(GLAMO_REG_CMDQ_BASE_ADDRL
,
50 GLAMO_VRAM_CMDQ
& 0xffff);
51 GLAMO_OUT_REG(GLAMO_REG_CMDQ_BASE_ADDRH
,
52 (GLAMO_VRAM_CMDQ
>> 16) & 0x7f);
53 GLAMO_OUT_REG(GLAMO_REG_CMDQ_LEN
, cmdq_len
);
55 GLAMO_OUT_REG(GLAMO_REG_CMDQ_WRITE_ADDRH
, 0);
56 GLAMO_OUT_REG(GLAMO_REG_CMDQ_WRITE_ADDRL
, 0);
57 GLAMO_OUT_REG(GLAMO_REG_CMDQ_READ_ADDRH
, 0);
58 GLAMO_OUT_REG(GLAMO_REG_CMDQ_READ_ADDRL
, 0);
59 GLAMO_OUT_REG(GLAMO_REG_CMDQ_CONTROL
,
60 1 << 12 | /* turbo flip */
61 0 << 11 | /* no triple buffer */
62 5 << 8 | /* no interrupt */
63 8 << 4 | /* HQ threshold */
64 0 << 2 | /* no auto-correction */
65 0 << 1); /* SQ mode */
68 static void dma_cmdq_flush(struct glamo_dma_manager
*dma
)
70 GLAMO_REG_TYPE
*p
= (GLAMO_REG_TYPE
*) dma
->lbuf
;
71 int ring_size
= dma
->size
>> 1;
72 int ring_count
= dma
->llen
>> 1;
77 /* write pointer can be ring_size, but not zero */
80 if (dma
->w
>= ring_size
)
83 dma
->cmdq
[dma
->w
++] = *p
++;
85 while (dma
->r
== dma
->w
)
87 dma
->r
= GLAMO_IN_REG(GLAMO_REG_CMDQ_READ_ADDRL
);
88 dma
->r
|= (GLAMO_IN_REG(GLAMO_REG_CMDQ_READ_ADDRH
) & 0x7) << 16;
92 GLAMO_OUT_REG(GLAMO_REG_CMDQ_WRITE_ADDRH
, (dma
->w
>> 15) & 0x7);
93 GLAMO_OUT_REG(GLAMO_REG_CMDQ_WRITE_ADDRL
, (dma
->w
<< 1) & 0xffff);
98 static void dma_mmio_flush(struct glamo_dma_manager
*dma
)
100 GLAMO_REG_TYPE
*p
= (GLAMO_REG_TYPE
*) dma
->lbuf
;
102 while ((unsigned char *) p
< dma
->lbuf
+ dma
->llen
)
104 GLAMO_REG_TYPE reg
, val
;
115 for (i
= 0; i
< n
; i
++, reg
+= 2)
118 //printf("burst 0x%x to 0x%x\n", val, reg);
119 GLAMO_OUT_REG(reg
, val
);
126 GLAMO_OUT_REG(reg
, val
);
132 void glamo_dma_wait(struct glamo_dma_manager
*dma
, enum glamo_dma_wait_type t
)
138 case GLAMO_DMA_MODE_CMDQ
:
141 case GLAMO_DMA_WAIT_CMDQ
:
145 case GLAMO_DMA_WAIT_ISP
:
146 mask
= 0x3 | (1 << 8);
148 case GLAMO_DMA_WAIT_ALL
:
160 status
= GLAMO_IN_REG(GLAMO_REG_CMDQ_STATUS
);
161 if ((status
& mask
) == val
)
165 case GLAMO_DMA_MODE_MMIO
:
171 void glamo_dma_flush(struct glamo_dma_manager
*dma
)
178 case GLAMO_DMA_MODE_CMDQ
:
181 case GLAMO_DMA_MODE_MMIO
:
188 struct glamo_dma_manager
*glamo_dma_new(enum glamo_dma_mode mode
)
190 struct glamo_dma_manager
*dma
;
192 dma
= malloc(sizeof(*dma
));
197 dma
->lsize
= DMA_CMDQ_SIZE
;
198 dma
->lbuf
= malloc(dma
->lsize
);
203 case GLAMO_DMA_MODE_CMDQ
:
206 case GLAMO_DMA_MODE_MMIO
:
214 void glamo_dma_destroy(struct glamo_dma_manager
*dma
)
218 case GLAMO_DMA_MODE_CMDQ
:
219 glamo_hw_engine_reset(GLAMO_ENGINE_CMDQ
);
220 glamo_hw_engine_disable(GLAMO_ENGINE_CMDQ
);
222 case GLAMO_DMA_MODE_MMIO
:
231 void glamo_dma_dump(struct glamo_dma_manager
*dma
)
237 case GLAMO_DMA_MODE_CMDQ
:
238 glamo_hw_dump(GLAMO_REG_CMDQ_BASE_ADDRL
, 10);
239 printf("w 0x%x, r 0x%x\n", dma
->w
<< 1, dma
->r
<< 1);
240 for (i
= 0; i
< 16; i
++)
241 printf("0x%04x%c", dma
->cmdq
[i
], ((i
% 16) == 15) ? '\n' : ' ');
243 case GLAMO_DMA_MODE_MMIO
: