2 * QEMU JZ Soc emulation
4 * Copyright (c) 2009 yajin (yajin@vm-kernel.org)
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * The emulation target is pavo demo board.
28 * http://www.ingenic.cn/eng/productServ/kfyd/Hardware/pffaqQuestionContent.aspx?Category=2&Question=3
35 #include "qemu-timer.h"
36 #include "qemu-char.h"
39 #include "audio/audio.h"
45 #define DEBUG /*global debug on/off */
47 #define DEBUG_CPM (1<<0x0)
48 #define DEBUG_EMC (1<<0x1)
49 #define DEBUG_GPIO (1<<0x2)
50 #define DEBUG_RTC (1<<0x3)
51 #define DEBUG_TCU (1<<0x4)
52 #define DEBUG_LCDC (1<<0x5)
53 #define DEBUG_DMA (1<<0x6)
54 #define DEBUG_FLAG (DEBUG_CPM|DEBUG_EMC|DEBUG_GPIO \
55 | DEBUG_RTC | DEBUG_TCU | DEBUG_LCDC | DEBUG_DMA)
56 //DEBUG_TCU// (DEBUG_CPM|DEBUG_EMC|DEBUG_GPIO
57 // | DEBUG_RTC | DEBUG_TCU | DEBUG_LCDC | DEBUG_DMA)
62 static void debug_init(void)
64 fp
= fopen("jz4740.txt", "w+");
67 fprintf(stderr
, "can not open jz4740.txt \n");
71 static void debug_out(uint32_t flag
, const char *format
, ...)
76 if (flag
& DEBUG_FLAG
)
79 vfprintf(fp
, format
, ap
);
86 static void debug_init(void)
89 static void debug_out(uint32_t flag
, const char *format
, ...)
94 uint32_t jz4740_badwidth_read8(void *opaque
, target_phys_addr_t addr
)
99 cpu_physical_memory_read(addr
, (void *) &ret
, 1);
103 void jz4740_badwidth_write8(void *opaque
, target_phys_addr_t addr
,
106 uint8_t val8
= value
;
109 cpu_physical_memory_write(addr
, (void *) &val8
, 1);
112 uint32_t jz4740_badwidth_read16(void *opaque
, target_phys_addr_t addr
)
115 JZ4740_16B_REG(addr
);
116 cpu_physical_memory_read(addr
, (void *) &ret
, 2);
120 void jz4740_badwidth_write16(void *opaque
, target_phys_addr_t addr
,
123 uint16_t val16
= value
;
125 JZ4740_16B_REG(addr
);
126 cpu_physical_memory_write(addr
, (void *) &val16
, 2);
129 uint32_t jz4740_badwidth_read32(void *opaque
, target_phys_addr_t addr
)
133 JZ4740_32B_REG(addr
);
134 cpu_physical_memory_read(addr
, (void *) &ret
, 4);
138 void jz4740_badwidth_write32(void *opaque
, target_phys_addr_t addr
,
141 JZ4740_32B_REG(addr
);
142 cpu_physical_memory_write(addr
, (void *) &value
, 4);
146 /*clock reset and power control*/
149 target_phys_addr_t base
;
150 struct jz_state_s
*soc
;
166 static void jz4740_dump_clocks(jz_clk parent
)
170 debug_out(DEBUG_CPM
, "clock %s rate %d \n", i
->name
, i
->rate
);
171 for (i
= i
->child1
; i
; i
= i
->sibling
)
172 jz4740_dump_clocks(i
);
175 static inline void jz4740_cpccr_update(struct jz4740_cpm_s
*s
,
178 uint32_t ldiv
, mdiv
, pdiv
, hdiv
, cdiv
, udiv
;
179 uint32_t div_table
[10] = {
180 1, 2, 3, 4, 6, 8, 12, 16, 24, 32
183 if (unlikely(new_value
== s
->cpccr
))
186 if (new_value
& CPM_CPCCR_PCS
)
187 jz_clk_setrate(jz_findclk(s
->soc
, "pll_divider"), 1, 1);
189 jz_clk_setrate(jz_findclk(s
->soc
, "pll_divider"), 2, 1);
192 ldiv
= (new_value
& CPM_CPCCR_LDIV_MASK
) >> CPM_CPCCR_LDIV_BIT
;
195 mdiv
= div_table
[(new_value
& CPM_CPCCR_MDIV_MASK
) >> CPM_CPCCR_MDIV_BIT
];
196 pdiv
= div_table
[(new_value
& CPM_CPCCR_PDIV_MASK
) >> CPM_CPCCR_PDIV_BIT
];
197 hdiv
= div_table
[(new_value
& CPM_CPCCR_HDIV_MASK
) >> CPM_CPCCR_HDIV_BIT
];
198 cdiv
= div_table
[(new_value
& CPM_CPCCR_CDIV_MASK
) >> CPM_CPCCR_CDIV_BIT
];
199 udiv
= div_table
[(new_value
& CPM_CPCCR_UDIV_MASK
) >> CPM_CPCCR_UDIV_BIT
];
201 jz_clk_setrate(jz_findclk(s
->soc
, "ldclk"), ldiv
, 1);
202 jz_clk_setrate(jz_findclk(s
->soc
, "mclk"), mdiv
, 1);
203 jz_clk_setrate(jz_findclk(s
->soc
, "pclk"), pdiv
, 1);
204 jz_clk_setrate(jz_findclk(s
->soc
, "hclk"), hdiv
, 1);
205 jz_clk_setrate(jz_findclk(s
->soc
, "cclk"), cdiv
, 1);
206 jz_clk_setrate(jz_findclk(s
->soc
, "usbclk"), udiv
, 1);
208 if (new_value
& CPM_CPCCR_UCS
)
209 jz_clk_reparent(jz_findclk(s
->soc
, "usbclk"),
210 jz_findclk(s
->soc
, "pll_divider"));
212 jz_clk_reparent(jz_findclk(s
->soc
, "usbclk"),
213 jz_findclk(s
->soc
, "osc_extal"));
215 if (new_value
& CPM_CPCCR_I2CS
)
216 jz_clk_reparent(jz_findclk(s
->soc
, "i2sclk"),
217 jz_findclk(s
->soc
, "pll_divider"));
219 jz_clk_reparent(jz_findclk(s
->soc
, "i2sclk"),
220 jz_findclk(s
->soc
, "osc_extal"));
222 s
->cpccr
= new_value
;
224 debug_out(DEBUG_CPM
, "write to cpccr 0x%x\n", new_value
);
226 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
230 static inline void jz4740_cppcr_update(struct jz4740_cpm_s
*s
,
233 uint32_t pllm
, plln
, pllod
, pllbp
, pllen
;
239 pllen
= new_value
& CPM_CPPCR_PLLEN
;
240 pllbp
= new_value
& CPM_CPPCR_PLLBP
;
241 if ((!pllen
) || (pllen
&& pllbp
))
243 jz_clk_setrate(jz_findclk(s
->soc
, "pll_output"), 1, 1);
244 debug_out(DEBUG_CPM
, "pll is bypassed \n");
245 s
->cppcr
= new_value
| CPM_CPPCR_PLLS
;
250 pllm
= (new_value
& CPM_CPPCR_PLLM_MASK
) >> CPM_CPPCR_PLLM_BIT
;
251 plln
= (new_value
& CPM_CPPCR_PLLN_MASK
) >> CPM_CPPCR_PLLN_BIT
;
252 pllod
= (new_value
& CPM_CPPCR_PLLOD_MASK
) >> CPM_CPPCR_PLLOD_BIT
;
253 jz_clk_setrate(jz_findclk(s
->soc
, "pll_output"), (plln
+ 2) * pll0
[pllod
],
256 s
->cppcr
= new_value
;
258 debug_out(DEBUG_CPM
, "write to cppcr 0x%x\n", new_value
);
259 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
263 static inline void jz4740_i2scdr_update(struct jz4740_cpm_s
*s
,
268 i2scdr
= new_value
& CPM_I2SCDR_I2SDIV_MASK
;
269 if (unlikely(i2scdr
== s
->i2scdr
))
273 jz_clk_setrate(jz_findclk(s
->soc
, "i2sclk"), i2scdr
+ 1, 1);
277 debug_out(DEBUG_CPM
, "write to i2scdr 0x%x\n", new_value
);
278 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
282 static inline void jz4740_lpcdr_update(struct jz4740_cpm_s
*s
,
287 ipcdr
= new_value
& CPM_LPCDR_PIXDIV_MASK
;
292 static inline void jz4740_msccdr_update(struct jz4740_cpm_s
*s
,
297 msccdr
= new_value
& CPM_MSCCDR_MSCDIV_MASK
;
299 if (unlikely(msccdr
== s
->msccdr
))
303 jz_clk_setrate(jz_findclk(s
->soc
, "mscclk"), msccdr
+ 1, 1);
307 debug_out(DEBUG_CPM
, "write to msccdr 0x%x\n", new_value
);
308 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
312 static inline void jz4740_uhccdr_update(struct jz4740_cpm_s
*s
,
317 uhccdr
= new_value
& 0xf;
322 static void jz4740_cpm_write(void *opaque
, target_phys_addr_t addr
,
325 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) opaque
;
327 debug_out(DEBUG_CPM
, "write to cpm addr %x value 0x%x\n", addr
,value
);
332 jz4740_cpccr_update(s
, value
);
335 s
->lcr
= value
& 0xff;
338 s
->clkgr
= value
& 0xffff;
341 s
->scr
= value
& 0xffff;
344 jz4740_cppcr_update(s
, value
);
347 jz4740_i2scdr_update(s
, value
);
350 jz4740_lpcdr_update(s
, value
);
353 jz4740_msccdr_update(s
, value
);
356 jz4740_uhccdr_update(s
, value
);
359 s
->uhctst
= value
& 0x3f;
362 s
->ssicdr
= value
& 0xf;
365 cpu_abort(s
->soc
->env
,
366 "jz4740_cpm_write undefined addr " JZ_FMT_plx
367 " value %x \n", addr
, value
);
373 static uint32_t jz474_cpm_read(void *opaque
, target_phys_addr_t addr
)
375 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) opaque
;
402 cpu_abort(s
->soc
->env
,
403 "jz474_cpm_read undefined addr " JZ_FMT_plx
" \n", addr
);
410 static CPUReadMemoryFunc
*jz4740_cpm_readfn
[] = {
411 jz4740_badwidth_read32
, jz4740_badwidth_read32
, jz474_cpm_read
,
414 static CPUWriteMemoryFunc
*jz4740_cpm_writefn
[] = {
415 jz4740_badwidth_write32
, jz4740_badwidth_write32
, jz4740_cpm_write
,
418 static void jz4740_cpm_reset(struct jz4740_cpm_s
*s
)
420 s
->cpccr
= 0x42040000;
421 s
->cppcr
= 0x28080011;
422 s
->i2scdr
= 0x00000004;
423 s
->lpcdr
= 0x00000004;
424 s
->msccdr
= 0x00000004;
425 s
->uhccdr
= 0x00000004;
427 s
->ssicdr
= 0x00000004;
434 static struct jz4740_cpm_s
*jz4740_cpm_init(struct jz_state_s
*soc
)
437 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) qemu_mallocz(sizeof(*s
));
438 s
->base
= JZ4740_PHYS_BASE(JZ4740_CPM_BASE
);
444 cpu_register_io_memory(0, jz4740_cpm_readfn
, jz4740_cpm_writefn
, s
);
445 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
450 /* JZ4740 interrupt controller
451 * It issues INT2 to MIPS
457 target_phys_addr_t base
;
458 struct jz_state_s
*soc
;
467 static uint32_t jz4740_intc_read(void *opaque
, target_phys_addr_t addr
)
469 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
484 cpu_abort(s
->soc
->env
,
485 "jz4740_intc_read undefined addr " JZ_FMT_plx
" \n", addr
);
491 static void jz4740_intc_write(void *opaque
, target_phys_addr_t addr
,
494 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
512 qemu_set_irq(s
->parent_irq
, 0);
515 cpu_abort(s
->soc
->env
,
516 "jz4740_intc_write undefined addr " JZ_FMT_plx
517 " value %x \n", addr
, value
);
522 static CPUReadMemoryFunc
*jz4740_intc_readfn
[] = {
523 jz4740_badwidth_read32
, jz4740_badwidth_read32
, jz4740_intc_read
,
526 static CPUWriteMemoryFunc
*jz4740_intc_writefn
[] = {
527 jz4740_badwidth_write32
, jz4740_badwidth_write32
, jz4740_intc_write
,
530 static void jz4740_intc_reset(struct jz4740_intc_s
*s
)
533 s
->icmr
= 0xffffffff;
537 static void jz4740_set_irq(void *opaque
, int irq
, int level
)
539 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
540 uint32_t irq_mask
= 1 << irq
;
546 s
->icpr
&= ~irq_mask
;
547 if (!(s
->icmr
& irq_mask
))
550 qemu_set_irq(s
->parent_irq
, 1);
556 static qemu_irq
*jz4740_intc_init(struct jz_state_s
*soc
, qemu_irq parent_irq
)
559 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) qemu_mallocz(sizeof(*s
));
560 s
->base
= JZ4740_PHYS_BASE(JZ4740_INTC_BASE
);
561 s
->parent_irq
= parent_irq
;
564 jz4740_intc_reset(s
);
567 cpu_register_io_memory(0, jz4740_intc_readfn
, jz4740_intc_writefn
, s
);
568 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
569 return qemu_allocate_irqs(jz4740_set_irq
, s
, 32);
572 /*external memory controller*/
576 target_phys_addr_t base
;
577 struct jz_state_s
*soc
;
580 uint32_t smcr1
; /*0x13010014 */
581 uint32_t smcr2
; /*0x13010018 */
582 uint32_t smcr3
; /*0x1301001c */
583 uint32_t smcr4
; /*0x13010020 */
584 uint32_t sacr1
; /*0x13010034 */
585 uint32_t sacr2
; /*0x13010038 */
586 uint32_t sacr3
; /*0x1301003c */
587 uint32_t sacr4
; /*0x13010040 */
589 uint32_t nfcsr
; /*0x13010050 */
590 uint32_t nfeccr
; /*0x13010100 */
591 uint32_t nfecc
; /*0x13010104 */
592 uint32_t nfpar0
; /*0x13010108 */
593 uint32_t nfpar1
; /*0x1301010c */
594 uint32_t nfpar2
; /*0x13010110 */
595 uint32_t nfints
; /*0x13010114 */
596 uint32_t nfinte
; /*0x13010118 */
597 uint32_t nferr0
; /*0x1301011c */
598 uint32_t nferr1
; /*0x13010120 */
599 uint32_t nferr2
; /*0x13010124 */
600 uint32_t nferr3
; /*0x13010128 */
602 uint32_t dmcr
; /*0x13010080 */
603 uint32_t rtcsr
; /*0x13010084 */
604 uint32_t rtcnt
; /*0x13010088 */
605 uint32_t rtcor
; /*0x1301008c */
606 uint32_t dmar
; /*0x13010090 */
607 uint32_t sdmr
; /*0x1301a000 */
612 static void jz4740_emc_reset(struct jz4740_emc_s
*s
)
614 s
->smcr1
= 0xfff7700;
615 s
->smcr2
= 0xfff7700;
616 s
->smcr3
= 0xfff7700;
617 s
->smcr4
= 0xfff7700;
645 static uint32_t jz4740_emc_read8(void *opaque
, target_phys_addr_t addr
)
647 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
655 return (s
->nfpar0
>> ((addr
- 0x108) * 8)) & 0xff;
660 return (s
->nfpar1
>> ((addr
- 0x10c) * 8)) & 0xff;
665 return (s
->nfpar2
>> ((addr
- 0x110) * 8)) & 0xff;
670 return (s
->sdmr
>> ((addr
- 0xa000) * 8)) & 0xff;
672 cpu_abort(s
->soc
->env
,
673 "jz4740_emc_read8 undefined addr " JZ_FMT_plx
" \n", addr
);
680 static uint32_t jz4740_emc_read16(void *opaque
, target_phys_addr_t addr
)
682 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
688 return (s
->nfpar0
>> ((addr
- 0x108) * 8)) & 0xffff;
691 return (s
->nfpar1
>> ((addr
- 0x10c) * 8)) & 0xffff;
694 return (s
->nfpar2
>> ((addr
- 0x110) * 8)) & 0xffff;
697 return (s
->nferr0
>> ((addr
- 0x11c) * 8)) & 0xffff;
700 return (s
->nferr1
>> ((addr
- 0x120) * 8)) & 0xffff;
703 return (s
->nferr2
>> ((addr
- 0x124) * 8)) & 0xffff;
706 return (s
->nferr3
>> ((addr
- 0x128) * 8)) & 0xffff;
708 cpu_abort(s
->soc
->env
,
709 "jz4740_emc_read16 undefined addr " JZ_FMT_plx
" \n", addr
);
714 static uint32_t jz4740_emc_read32(void *opaque
, target_phys_addr_t addr
)
716 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
767 cpu_abort(s
->soc
->env
,
768 "jz4740_emc_read32 undefined addr " JZ_FMT_plx
" \n", addr
);
773 static void jz4740_emc_write8(void *opaque
, target_phys_addr_t addr
,
776 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
778 debug_out(DEBUG_EMC
, "jz4740_emc_write8 addr %x value %x\n", addr
, value
);
786 s
->nfpar0
|= (value
& 0xff) << ((addr
- 0x108) * 8);
792 s
->nfpar1
|= (value
& 0xff) << ((addr
- 0x10c) * 8);
798 s
->nfpar2
|= (value
& 0xff) << ((addr
- 0x110) * 8);
800 case 0xa000 ... 0xa3ff:
803 cpu_abort(s
->soc
->env
,
804 "jz4740_emc_write8 undefined addr " JZ_FMT_plx
805 " value %x \n", addr
, value
);
808 static void jz4740_emc_write16(void *opaque
, target_phys_addr_t addr
,
811 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
813 debug_out(DEBUG_EMC
, "jz4740_emc_write16 addr %x value %x\n", addr
, value
);
818 s
->nfpar0
|= (value
& 0xffff) << ((addr
- 0x108) * 8);
822 s
->nfpar1
|= (value
& 0xffff) << ((addr
- 0x10c) * 8);
826 s
->nfpar2
|= (value
& 0xffff) << ((addr
- 0x110) * 8);
830 s
->rtcsr
|= (value
& 0xffff) << ((addr
- 0x84) * 8);
834 s
->rtcnt
|= (value
& 0xffff) << ((addr
- 0x88) * 8);
837 s
->rtcor
|= (value
& 0xffff) << ((addr
- 0x8c) * 8);
840 cpu_abort(s
->soc
->env
,
841 "jz4740_emc_write16 undefined addr " JZ_FMT_plx
842 " value %x \n", addr
, value
);
846 static void jz4740_emc_upate_interrupt(struct jz4740_emc_s
*s
)
848 qemu_set_irq(s
->irq
, s
->nfints
& s
->nfinte
);
851 static void jz4740_emc_write32(void *opaque
, target_phys_addr_t addr
,
854 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
856 debug_out(DEBUG_EMC
, "jz4740_emc_write32 addr %x value %x\n", addr
, value
);
870 s
->smcr1
= value
& 0xfff77cf;
873 s
->smcr2
= value
& 0xfff77cf;
876 s
->smcr3
= value
& 0xfff77cf;
879 s
->smcr4
= value
& 0xfff77cf;
882 s
->sacr1
= value
& 0xffff;
885 s
->sacr2
= value
& 0xffff;
888 s
->sacr3
= value
& 0xffff;
891 s
->sacr4
= value
& 0xffff;
894 s
->nfcsr
= value
& 0xffff;
897 s
->nfeccr
= value
& 0x1f;
912 /*TODO: Real RS error correction */
915 if ((s
->nfeccr
& 0x10) && (!(s
->nfeccr
& 0x8)))
927 s
->nfpar0
= 0xffffffff; /*fake value. for debug */
928 s
->nfpar1
= 0xffffffff; /*fake value */
929 s
->nfpar2
= 0xff; /*fake value */
936 jz4740_emc_upate_interrupt(s
);
945 s
->nfpar2
= value
& 0xff;
948 s
->nfints
= value
& 0x1fffffff;
949 jz4740_emc_upate_interrupt(s
);
952 s
->nfinte
= value
& 0x1f;
953 jz4740_emc_upate_interrupt(s
);
956 s
->dmcr
= value
& 0x9fbeff7f;
959 s
->dmar
= value
& 0xffff;
962 cpu_abort(s
->soc
->env
,
963 "jz4740_emc_write32 undefined addr " JZ_FMT_plx
964 " value %x \n", addr
, value
);
970 static CPUReadMemoryFunc
*jz4740_emc_readfn
[] = {
971 jz4740_emc_read8
, jz4740_emc_read16
, jz4740_emc_read32
,
974 static CPUWriteMemoryFunc
*jz4740_emc_writefn
[] = {
975 jz4740_emc_write8
, jz4740_emc_write16
, jz4740_emc_write32
,
979 static struct jz4740_emc_s
*jz4740_emc_init(struct jz_state_s
*soc
,
983 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) qemu_mallocz(sizeof(*s
));
984 s
->base
= JZ4740_PHYS_BASE(JZ4740_EMC_BASE
);
991 cpu_register_io_memory(0, jz4740_emc_readfn
, jz4740_emc_writefn
, s
);
992 cpu_register_physical_memory(s
->base
, 0x00010000, iomemtype
);
1000 target_phys_addr_t base
;
1001 struct jz_state_s
*soc
;
1014 static void jz4740_gpio_reset(struct jz4740_gpio_s
*s
)
1016 memset(s
->papin
, 0x0, sizeof(s
->papin
));
1017 memset(s
->padat
, 0x0, sizeof(s
->padat
));
1018 memset(s
->paim
, 0xffffffff, sizeof(s
->paim
));
1019 memset(s
->pape
, 0x0, sizeof(s
->pape
));
1020 memset(s
->pafun
, 0x0, sizeof(s
->pafun
));
1021 memset(s
->pasel
, 0x0, sizeof(s
->pasel
));
1022 memset(s
->padir
, 0x0, sizeof(s
->padir
));
1023 memset(s
->patrg
, 0x0, sizeof(s
->patrg
));
1024 memset(s
->paflg
, 0x0, sizeof(s
->paflg
));
1027 static uint32_t jz4740_gpio_read(void *opaque
, target_phys_addr_t addr
)
1029 struct jz4740_gpio_s
*s
= (struct jz4740_gpio_s
*) opaque
;
1031 debug_out(DEBUG_GPIO
, "jz4740_gpio_read addr %x\n", addr
);
1095 JZ4740_WO_REG(addr
);
1102 group
= (addr
- 0x0) / 0x100;
1105 /*GPIO(C) PIN 30 -> NAND FLASH R/B. */
1106 /*FOR NAND FLASH.PIN 30 ----|_____|------ */
1107 s
->papin
[2] &= 0x40000000;
1109 s
->papin
[2] &= ~0x40000000;
1111 s
->papin
[2] |= 0x40000000;
1113 return s
->papin
[group
];
1118 group
= (addr
- 0x10) / 0x100;
1119 return s
->padat
[group
];
1124 group
= (addr
- 0x20) / 0x100;
1125 return s
->paim
[group
];
1130 group
= (addr
- 0x30) / 0x100;
1131 return s
->pape
[group
];
1136 group
= (addr
- 0x40) / 0x100;
1137 return s
->pafun
[group
];
1142 group
= (addr
- 0x50) / 0x100;
1143 return s
->pasel
[group
];
1148 group
= (addr
- 0x60) / 0x100;
1149 return s
->padir
[group
];
1154 group
= (addr
- 0x70) / 0x100;
1155 return s
->patrg
[group
];
1160 group
= (addr
- 0x80) / 0x100;
1161 return s
->paflg
[group
];
1163 cpu_abort(s
->soc
->env
,
1164 "jz4740_gpio_read undefined addr " JZ_FMT_plx
" \n", addr
);
1169 static void jz4740_gpio_write(void *opaque
, target_phys_addr_t addr
,
1172 struct jz4740_gpio_s
*s
= (struct jz4740_gpio_s
*) opaque
;
1175 debug_out(DEBUG_GPIO
, "jz4740_gpio_write addr %x value %x\n", addr
, value
);
1215 JZ4740_RO_REG(addr
);
1221 group
= (addr
- 0x14) / 0x100;
1222 s
->padat
[group
] = value
;
1228 group
= (addr
- 0x18) / 0x100;
1229 s
->padat
[group
] &= ~value
;
1235 group
= (addr
- 0x24) / 0x100;
1236 s
->paim
[group
] = value
;
1242 group
= (addr
- 0x28) / 0x100;
1243 s
->paim
[group
] &= ~value
;
1249 group
= (addr
- 0x34) / 0x100;
1250 s
->pape
[group
] = value
;
1256 group
= (addr
- 0x38) / 0x100;
1257 s
->pape
[group
] &= ~value
;
1263 group
= (addr
- 0x44) / 0x100;
1264 s
->pafun
[group
] = value
;
1270 group
= (addr
- 0x48) / 0x100;
1271 s
->pafun
[group
] &= ~value
;
1277 group
= (addr
- 0x54) / 0x100;
1278 s
->pasel
[group
] = value
;
1284 group
= (addr
- 0x58) / 0x100;
1285 s
->pasel
[group
] &= ~value
;
1291 group
= (addr
- 0x64) / 0x100;
1292 s
->padir
[group
] = value
;
1298 group
= (addr
- 0x68) / 0x100;
1299 s
->padir
[group
] &= ~value
;
1305 group
= (addr
- 0x74) / 0x100;
1306 s
->patrg
[group
] = value
;
1312 group
= (addr
- 0x78) / 0x100;
1313 s
->patrg
[group
] &= ~value
;
1319 group
= (addr
- 0x74) / 0x100;
1320 s
->paflg
[group
] &= ~value
;
1323 cpu_abort(s
->soc
->env
,
1324 "jz4740_gpio_write undefined addr " JZ_FMT_plx
1325 " value %x \n", addr
, value
);
1333 static CPUReadMemoryFunc
*jz4740_gpio_readfn
[] = {
1334 jz4740_badwidth_read32
, jz4740_badwidth_read32
, jz4740_gpio_read
,
1337 static CPUWriteMemoryFunc
*jz4740_gpio_writefn
[] = {
1338 jz4740_badwidth_write32
, jz4740_badwidth_write32
, jz4740_gpio_write
,
1341 static struct jz4740_gpio_s
*jz4740_gpio_init(struct jz_state_s
*soc
,
1345 struct jz4740_gpio_s
*s
= (struct jz4740_gpio_s
*) qemu_mallocz(sizeof(*s
));
1346 s
->base
= JZ4740_PHYS_BASE(JZ4740_GPIO_BASE
);
1350 jz4740_gpio_reset(s
);
1353 cpu_register_io_memory(0, jz4740_gpio_readfn
, jz4740_gpio_writefn
, s
);
1354 cpu_register_physical_memory(s
->base
, 0x00010000, iomemtype
);
1362 target_phys_addr_t base
;
1363 struct jz_state_s
*soc
;
1385 static void jz4740_rtc_update_interrupt(struct jz4740_rtc_s
*s
)
1387 if (((s
->rtcsr
& 0x40) && (s
->rtcsr
& 0x20))
1388 || ((s
->rtcsr
& 0x10) && (s
->rtcsr
& 0x8)))
1389 qemu_set_irq(s
->irq
, 1);
1391 qemu_set_irq(s
->irq
, 0);
1394 static inline void jz4740_rtc_start(struct jz4740_rtc_s
*s
)
1396 s
->next
= +qemu_get_clock(rt_clock
);
1397 qemu_mod_timer(s
->hz_tm
, s
->next
);
1400 static inline void jz4740_rtc_stop(struct jz4740_rtc_s
*s
)
1402 qemu_del_timer(s
->hz_tm
);
1403 s
->next
= -qemu_get_clock(rt_clock
);
1408 static void jz4740_rtc_hz(void *opaque
)
1410 struct jz4740_rtc_s
*s
= (struct jz4740_rtc_s
*) opaque
;
1413 qemu_mod_timer(s
->hz_tm
, s
->next
);
1420 if (s
->rtcsr
== s
->rtcsar
)
1423 jz4740_rtc_update_interrupt(s
);
1427 static void jz4740_rtc_reset(struct jz4740_rtc_s
*s
)
1433 /*Maybe rtcsr need to be saved to file */
1435 //s->sec_offset = 0;
1436 //qemu_get_timedate(&s->tm, s->sec_offset);
1437 jz4740_rtc_start(s
);
1441 static uint32_t jz4740_rtc_read(void *opaque
, target_phys_addr_t addr
)
1443 struct jz4740_rtc_s
*s
= (struct jz4740_rtc_s
*) opaque
;
1445 debug_out(DEBUG_RTC
, "jz4740_rtc_read addr %x\n", addr
);
1449 return s
->rtccr
| 0x80;
1469 cpu_abort(s
->soc
->env
,
1470 "jz4740_rtc_read undefined addr " JZ_FMT_plx
"\n", addr
);
1476 static void jz4740_rtc_write(void *opaque
, target_phys_addr_t addr
,
1479 struct jz4740_rtc_s
*s
= (struct jz4740_rtc_s
*) opaque
;
1481 debug_out(DEBUG_RTC
, "jz4740_rtc_write addr %x value %x\n", addr
, value
);
1486 s
->rtccr
= value
& 0x2d;
1493 jz4740_rtc_start(s
);
1494 jz4740_rtc_update_interrupt(s
);
1499 //s->sec_offset = qemu_timedate_diff(&s->tm);
1505 s
->rtcgr
= value
& 0x13ffffff;
1508 s
->hcr
= value
& 0x1;
1511 s
->hwfcr
= value
& 0xffe0;
1514 s
->hrcr
= value
& 0xfe0;
1517 s
->hwcr
= value
& 0x1;
1520 s
->hwrsr
= value
& 0x33;
1526 cpu_abort(s
->soc
->env
,
1527 "jz4740_rtc_write undefined addr " JZ_FMT_plx
1528 " value %x \n", addr
, value
);
1533 static CPUReadMemoryFunc
*jz4740_rtc_readfn
[] = {
1534 jz4740_badwidth_read32
, jz4740_badwidth_read32
, jz4740_rtc_read
,
1537 static CPUWriteMemoryFunc
*jz4740_rtc_writefn
[] = {
1538 jz4740_badwidth_write32
, jz4740_badwidth_write32
, jz4740_rtc_write
,
1541 static struct jz4740_rtc_s
*jz4740_rtc_init(struct jz_state_s
*soc
,
1545 struct jz4740_rtc_s
*s
= (struct jz4740_rtc_s
*) qemu_mallocz(sizeof(*s
));
1546 s
->base
= JZ4740_PHYS_BASE(JZ4740_RTC_BASE
);
1550 s
->hz_tm
= qemu_new_timer(rt_clock
, jz4740_rtc_hz
, s
);
1552 jz4740_rtc_reset(s
);
1555 cpu_register_io_memory(0, jz4740_rtc_readfn
, jz4740_rtc_writefn
, s
);
1556 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
1566 target_phys_addr_t base
;
1567 struct jz_state_s
*soc
;
1570 QEMUTimer
*half_timer
[8];
1571 QEMUTimer
*full_timer
[8];
1584 uint32_t prescale
[8];
1588 static void jz4740_tcu_update_interrupt(struct jz4740_tcu_s
*s
)
1590 //printf("s->tfr %x s->tmr %x \n",s->tfr,s->tmr);
1591 if (((s
->tfr
& 0x1) & (~(s
->tmr
& 0x1)))
1592 || ((s
->tfr
& 0x10000) & (~(s
->tmr
& 0x10000))))
1594 qemu_set_irq(s
->tcu_irq0
, 1);
1597 qemu_set_irq(s
->tcu_irq0
, 0);
1599 if (((s
->tfr
& 0x2) & (~(s
->tmr
& 0x2)))
1600 || ((s
->tfr
& 0x20000) & (~(s
->tmr
& 0x20000))))
1602 qemu_set_irq(s
->tcu_irq1
, 1);
1605 qemu_set_irq(s
->tcu_irq1
, 0);
1607 if (((s
->tfr
& 0xfc) & (~(s
->tmr
& 0xfc)))
1608 || ((s
->tfr
& 0xfc0000) & (~(s
->tmr
& 0xfc0000))))
1610 qemu_set_irq(s
->tcu_irq2
, 1);
1613 qemu_set_irq(s
->tcu_irq2
, 0);
1619 #include "mips_jz_glue.h"
1621 #include "mips_jz_glue.h"
1623 #include "mips_jz_glue.h"
1625 #include "mips_jz_glue.h"
1627 #include "mips_jz_glue.h"
1629 #include "mips_jz_glue.h"
1631 #include "mips_jz_glue.h"
1633 #include "mips_jz_glue.h"
1636 #define jz4740_tcu_start(s) do { \
1637 jz4740_tcu_start_half0(s); \
1638 jz4740_tcu_start_full0(s); \
1639 jz4740_tcu_start_half1(s); \
1640 jz4740_tcu_start_full1(s); \
1641 jz4740_tcu_start_half2(s); \
1642 jz4740_tcu_start_full2(s); \
1643 jz4740_tcu_start_half3(s); \
1644 jz4740_tcu_start_full3(s); \
1645 jz4740_tcu_start_half4(s); \
1646 jz4740_tcu_start_full4(s); \
1647 jz4740_tcu_start_half5(s); \
1648 jz4740_tcu_start_full5(s); \
1649 jz4740_tcu_start_half6(s); \
1650 jz4740_tcu_start_full6(s); \
1651 jz4740_tcu_start_half7(s); \
1652 jz4740_tcu_start_full7(s); \
1655 static void jz4740_tcu_if_reset(struct jz4740_tcu_s
*s
)
1663 for (i
= 0; i
< 8; i
++)
1665 s
->tdfr
[i
] = 0xffff;
1666 s
->tdhr
[i
] = 0x8000;
1669 s
->half_timer
[i
] = NULL
;
1670 s
->full_timer
[i
] = NULL
;
1674 static void jz4740_tcu_if_write8(void *opaque
, target_phys_addr_t addr
,
1677 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) opaque
;
1679 debug_out(DEBUG_TCU
, "jz4740_tcu_if_write8 addr %x value %x\n", addr
,
1685 s
->ter
|= (value
& 0xff);
1686 jz4740_tcu_start(s
);
1689 s
->ter
&= ~(value
& 0xff);
1690 jz4740_tcu_start(s
);
1693 cpu_abort(s
->soc
->env
,
1694 "jz4740_tcu_if_write8 undefined addr " JZ_FMT_plx
1695 " value %x \n", addr
, value
);
1700 static void jz4740_tcu_if_write32(void *opaque
, target_phys_addr_t addr
,
1703 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) opaque
;
1705 debug_out(DEBUG_TCU
, "jz4740_tcu_if_write32 addr %x value %x\n", addr
,
1708 fprintf(fp
, "jz4740_tcu_if_write32 addr %x value %x\n", addr
,
1713 s
->tsr
|= (value
& 0x100ff);
1714 jz4740_tcu_start(s
);
1717 s
->tsr
&= ~(value
& 0x100ff);
1718 jz4740_tcu_start(s
);
1721 s
->tfr
|= (value
& 0xff00ff);
1724 s
->tfr
&= ~(value
& 0xff00ff);
1727 s
->tmr
|= (value
& 0xff00ff);
1728 jz4740_tcu_update_interrupt(s
);
1731 s
->tmr
&= ~(value
& 0xff00ff);
1732 jz4740_tcu_update_interrupt(s
);
1735 cpu_abort(s
->soc
->env
,
1736 "jz4740_tcu_if_write32 undefined addr " JZ_FMT_plx
1737 " value %x \n", addr
, value
);
1742 static uint32_t jz4740_tcu_if_read8(void *opaque
, target_phys_addr_t addr
)
1744 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) opaque
;
1746 debug_out(DEBUG_TCU
, "jz4740_tcu_if_read8 addr %x\n", addr
);
1753 cpu_abort(s
->soc
->env
,
1754 "jz4740_tcu_if_read8 undefined addr " JZ_FMT_plx
"\n", addr
);
1759 static uint32_t jz4740_tcu_if_read32(void *opaque
, target_phys_addr_t addr
)
1761 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) opaque
;
1763 debug_out(DEBUG_TCU
, "jz4740_tcu_if_read32 addr %x\n", addr
);
1774 cpu_abort(s
->soc
->env
,
1775 "jz4740_tcu_if_read32 undefined addr " JZ_FMT_plx
"\n", addr
);
1782 static CPUReadMemoryFunc
*jz4740_tcu_if_readfn
[] = {
1783 jz4740_tcu_if_read8
, jz4740_badwidth_read32
, jz4740_tcu_if_read32
,
1786 static CPUWriteMemoryFunc
*jz4740_tcu_if_writefn
[] = {
1787 jz4740_tcu_if_write8
, jz4740_badwidth_write32
, jz4740_tcu_if_write32
,
1790 static struct jz4740_tcu_s
*jz4740_tcu_if_init(struct jz_state_s
*soc
,
1798 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) qemu_mallocz(sizeof(*s
));
1799 s
->base
= JZ4740_PHYS_BASE(JZ4740_TCU_BASE
);
1801 s
->tcu_irq0
= tcu_irq0
;
1802 s
->tcu_irq1
= tcu_irq1
;
1803 s
->tcu_irq2
= tcu_irq2
;
1805 jz4740_tcu_if_reset(s
);
1808 cpu_register_io_memory(0, jz4740_tcu_if_readfn
, jz4740_tcu_if_writefn
,
1810 cpu_register_physical_memory(s
->base
, 0x00000040, iomemtype
);
1815 static void jz4740_tcu_init(struct jz_state_s
*soc
,
1816 struct jz4740_tcu_s
*s
, int timer_index
)
1818 switch (timer_index
)
1821 jz4740_tcu_init0(soc
, s
);
1824 jz4740_tcu_init1(soc
, s
);
1827 jz4740_tcu_init2(soc
, s
);
1830 jz4740_tcu_init3(soc
, s
);
1833 jz4740_tcu_init4(soc
, s
);
1836 jz4740_tcu_init5(soc
, s
);
1839 jz4740_tcu_init6(soc
, s
);
1842 jz4740_tcu_init7(soc
, s
);
1845 cpu_abort(s
->soc
->env
,
1846 "jz4740_tcu_init undefined timer %x \n", timer_index
);
1850 typedef void (*jz4740_lcd_fn_t
) (uint8_t * d
, const uint8_t * s
, int width
,
1851 const uint16_t * pal
);
1852 struct jz_fb_descriptor
1854 uint32_t fdadr
; /* Frame descriptor address register */
1855 uint32_t fsadr
; /* Frame source address register */
1856 uint32_t fidr
; /* Frame ID register */
1857 uint32_t ldcmd
; /* Command register */
1860 struct jz4740_lcdc_s
1864 target_phys_addr_t base
;
1865 struct jz_state_s
*soc
;
1867 DisplayState
*state
;
1868 QEMUConsole
*console
;
1869 jz4740_lcd_fn_t
*line_fn_tab
;
1870 jz4740_lcd_fn_t line_fn
;
1899 uint32_t bpp
; /*bit per second */
1900 uint16_t palette
[256];
1901 uint32_t invalidate
;
1906 static const int jz4740_lcd_bpp
[0x6] = {
1907 1, 2, 4, 8, 16, 32 /*4740 uses 32 bit for 24bpp */
1910 static void jz4740_lcdc_reset(struct jz4740_lcdc_s
*s
)
1915 static uint32_t jz4740_lcdc_read(void *opaque
, target_phys_addr_t addr
)
1917 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) opaque
;
1919 debug_out(DEBUG_LCDC
, "jz4740_lcdc_read addr %x \n", addr
);
1965 cpu_abort(s
->soc
->env
,
1966 "jz4740_lcdc_read undefined addr " JZ_FMT_plx
" \n", addr
);
1972 static void jz4740_lcdc_write(void *opaque
, target_phys_addr_t addr
,
1975 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) opaque
;
1977 debug_out(DEBUG_LCDC
, "jz4740_lcdc_write addr %x value %x\n", addr
, value
);
1984 JZ4740_RO_REG(addr
);
1987 s
->lcdcfg
= value
& 0x80ffffbf;
1990 s
->lcdvsync
= value
& 0x7ff07ff;
1993 s
->lcdhsync
= value
& 0x7ff07ff;
1996 s
->lcdvat
= value
& 0x7ff07ff;
1999 s
->lcddah
= value
& 0x7ff07ff;
2000 s
->width
= (value
& 0x7ff) - ((value
>> 16) & 0x7ff);
2003 s
->height
= (value
& 0x7ff) - ((value
>> 16) & 0x7ff);
2004 s
->lcddav
= value
& 0x7ff07ff;
2007 s
->lcdps
= value
& 0x7ff07ff;
2010 s
->lcdcls
= value
& 0x7ff07ff;
2013 s
->lcdspl
= value
& 0x7ff07ff;
2016 s
->lcdrev
= value
& 0x7ff0000;
2019 s
->lcdctrl
= value
& 0x3fff3fff;
2020 s
->ena
= (value
& 0x8) >> 3;
2021 s
->dis
= (value
& 0x10) >> 4;
2022 s
->bpp
= jz4740_lcd_bpp
[value
& 0x7];
2025 fprintf(stderr
, "bpp =1 is not supported\n");
2028 s
->line_fn
= s
->line_fn_tab
[value
& 0x7];
2031 s
->lcdstate
= value
& 0xbf;
2043 cpu_abort(s
->soc
->env
,
2044 "jz4740_lcdc_write undefined addr " JZ_FMT_plx
" value %x \n",
2050 static CPUReadMemoryFunc
*jz4740_lcdc_readfn
[] = {
2051 jz4740_badwidth_read32
, jz4740_badwidth_read32
, jz4740_lcdc_read
,
2054 static CPUWriteMemoryFunc
*jz4740_lcdc_writefn
[] = {
2055 jz4740_badwidth_write32
, jz4740_badwidth_write32
, jz4740_lcdc_write
,
2058 #include "pixel_ops.h"
2059 #define JZ4740_LCD_PANEL
2061 #include "mips_jz_glue.h"
2063 #include "mips_jz_glue.h"
2065 #include "mips_jz_glue.h"
2067 #include "mips_jz_glue.h"
2069 #include "mips_jz_glue.h"
2070 #undef JZ4740_LCD_PANEL
2072 static void *jz4740_lcd_get_buffer(struct jz4740_lcdc_s
*s
,
2073 target_phys_addr_t addr
)
2077 pd
= cpu_get_physical_page_desc(addr
);
2078 if ((pd
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2080 cpu_abort(cpu_single_env
, "%s: framebuffer outside RAM!\n",
2083 return phys_ram_base
+
2084 (pd
& TARGET_PAGE_MASK
) + (addr
& ~TARGET_PAGE_MASK
);
2087 static void jz4740_lcd_update_display(void *opaque
)
2089 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) opaque
;
2091 uint8_t *src
, *dest
;
2092 struct jz_fb_descriptor
*fb_des
;
2106 fb_des
= (struct jz_fb_descriptor
*) jz4740_lcd_get_buffer(s
, s
->lcdda0
);
2107 s
->lcdda0
= fb_des
->fdadr
;
2108 s
->lcdsa0
= fb_des
->fsadr
;
2109 s
->lcdfid0
= fb_des
->fidr
;
2110 s
->lcdcmd0
= fb_des
->ldcmd
;
2112 src
= (uint8_t *) jz4740_lcd_get_buffer(s
, fb_des
->fsadr
);
2113 if (s
->lcdcmd0
& (0x1 << 28))
2116 memcpy(s
->palette
, src
, sizeof(s
->palette
));
2122 if (s
->width
!= ds_get_width(s
->state
) ||
2123 s
->height
!= ds_get_height(s
->state
))
2125 qemu_console_resize(s
->console
, s
->width
, s
->height
);
2129 step
= (s
->width
* s
->bpp
) >> 3;
2130 dest
= ds_get_data(s
->state
);
2131 linesize
= ds_get_linesize(s
->state
);
2133 //printf("s->width %d s->height %d s->bpp %d linesize %d \n",s->width,s->height ,s->bpp,linesize);
2135 for (y
= 0; y
< s
->height
; y
++)
2137 s
->line_fn(dest
, src
, s
->width
, s
->palette
);
2138 //memcpy(dest,src,step);
2144 dpy_update(s
->state
, 0, 0, s
->width
, s
->height
);
2145 s
->lcdstate
|= 0x20;
2146 if ((s
->lcdcmd0
& 0x40000000) && (!(s
->lcdctrl
& 0x2000)))
2147 qemu_set_irq(s
->irq
, 1);
2150 static inline void jz4740_lcd_invalidate_display(void *opaque
)
2152 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) opaque
;
2156 static struct jz4740_lcdc_s
*jz4740_lcdc_init(struct jz_state_s
*soc
,
2157 qemu_irq irq
, DisplayState
* ds
)
2161 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) qemu_mallocz(sizeof(*s
));
2162 s
->base
= JZ4740_PHYS_BASE(JZ4740_LCD_BASE
);
2168 jz4740_lcdc_reset(s
);
2171 cpu_register_io_memory(0, jz4740_lcdc_readfn
, jz4740_lcdc_writefn
, s
);
2172 cpu_register_physical_memory(s
->base
, 0x10000, iomemtype
);
2174 s
->console
= graphic_console_init(s
->state
, jz4740_lcd_update_display
,
2175 jz4740_lcd_invalidate_display
,
2177 switch (ds_get_bits_per_pixel(s
->state
))
2180 s
->line_fn_tab
= qemu_mallocz(sizeof(jz4740_lcd_fn_t
) * 6);
2183 s
->line_fn_tab
= jz4740_lcd_draw_fn_8
;
2186 s
->line_fn_tab
= jz4740_lcd_draw_fn_15
;
2189 s
->line_fn_tab
= jz4740_lcd_draw_fn_16
;
2192 s
->line_fn_tab
= jz4740_lcd_draw_fn_24
;
2195 s
->line_fn_tab
= jz4740_lcd_draw_fn_32
;
2198 fprintf(stderr
, "%s: Bad color depth\n", __FUNCTION__
);
2206 #define JZ4740_DMA_NUM 6
2211 target_phys_addr_t base
;
2212 struct jz_state_s
*soc
;
2219 uint32_t dsa
[JZ4740_DMA_NUM
];
2220 uint32_t dta
[JZ4740_DMA_NUM
];
2221 uint32_t dtc
[JZ4740_DMA_NUM
];
2222 uint32_t drs
[JZ4740_DMA_NUM
];
2223 uint32_t dcs
[JZ4740_DMA_NUM
];
2224 uint32_t dcm
[JZ4740_DMA_NUM
];
2225 uint32_t dda
[JZ4740_DMA_NUM
];
2229 struct jz4740_desc_s
2231 uint32_t dcmd
; /* DCMD value for the current transfer */
2232 uint32_t dsadr
; /* DSAR value for the current transfer */
2233 uint32_t dtadr
; /* DTAR value for the current transfer */
2234 uint32_t ddadr
; /* Points to the next descriptor + transfer count */
2237 static inline void jz4740_dma_transfer(struct jz4740_dma_s
*s
,
2238 target_phys_addr_t src
,
2239 target_phys_addr_t dest
, uint32_t len
)
2241 uint32_t pd_src
, pd_dest
;
2244 pd_src
= cpu_get_physical_page_desc(src
);
2245 if ((pd_src
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2247 cpu_abort(cpu_single_env
, "%s: DMA source address %x outside RAM!\n",
2250 sr
= phys_ram_base
+
2251 (pd_src
& TARGET_PAGE_MASK
) + (src
& ~TARGET_PAGE_MASK
);
2253 pd_dest
= cpu_get_physical_page_desc(dest
);
2254 if ((pd_dest
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2256 cpu_abort(cpu_single_env
,
2257 "%s: DMA destination address %x outside RAM!\n",
2258 __FUNCTION__
, dest
);
2260 de
= phys_ram_base
+
2261 (pd_dest
& TARGET_PAGE_MASK
) + (dest
& ~TARGET_PAGE_MASK
);
2263 memcpy(de
, sr
, len
);
2266 static inline uint32_t jz4740_dma_unit_size(struct jz4740_dma_s
*s
,
2269 switch ((cmd
& 0x700) >> 8)
2286 /*No-descriptor transfer*/
2287 static inline void jz4740_dma_ndrun(struct jz4740_dma_s
*s
, int channel
)
2291 len
= jz4740_dma_unit_size(s
, s
->dcs
[channel
]) * s
->dtc
[channel
];
2293 jz4740_dma_transfer(s
, s
->dsa
[channel
], s
->dta
[channel
], len
);
2295 /*finish dma transfer */
2296 s
->dtc
[channel
] = 0;
2298 s
->dirqp
|= 1 << channel
;
2300 /*some cleanup work */
2301 /*clean AR TT GLOBAL AR */
2302 s
->dcs
[channel
] &= 0xffffffe7;
2303 s
->dmac
&= 0xfffffffb;
2305 if (s
->dcm
[channel
] & 0x2)
2306 qemu_set_irq(s
->irq
, 1);
2309 /*descriptor transfer */
2310 static inline void jz4740_dma_drun(struct jz4740_dma_s
*s
, int channel
)
2312 struct jz4740_desc_s
*desc
;
2313 target_phys_addr_t desc_phy
;
2316 desc_phy
= s
->dda
[channel
];
2318 cpu_abort(s
->soc
->env
,
2319 "jz4740_dma_drun descriptor address " JZ_FMT_plx
2320 " must be 4 bytes aligned \n", desc_phy
);
2322 pd
= cpu_get_physical_page_desc(desc_phy
);
2323 if ((pd
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2324 cpu_abort(cpu_single_env
,
2325 "%s: DMA descriptor address " JZ_FMT_plx
" outside RAM!\n",
2326 __FUNCTION__
, desc_phy
);
2328 desc
= (struct jz4740_desc_s
*) (phys_ram_base
+
2329 (pd
& TARGET_PAGE_MASK
) +
2330 (desc_phy
& ~TARGET_PAGE_MASK
));
2333 cpu_abort(cpu_single_env
,
2334 "%s: DMA descriptor " JZ_FMT_plx
" is NULL!\n", __FUNCTION__
,
2339 if ((desc
->dcmd
& 0x8) && (!(desc
->dcmd
& 0x10)))
2341 /*Stop DMA and set DCSN.INV=1 */
2342 s
->dcs
[channel
] |= 1 << 6;
2345 jz4740_dma_transfer(s
, desc
->dtadr
, desc
->dsadr
,
2346 (desc
->ddadr
& 0xffffff) *
2347 jz4740_dma_unit_size(s
, desc
->dcmd
));
2349 if ((desc
->dcmd
) & (1 << 3))
2351 desc
->dcmd
&= ~(1 << 4);
2352 if (desc
->dcmd
& 0x1)
2354 s
->dcs
[channel
] |= 0x2;
2357 s
->dcs
[channel
] |= 0x8;
2359 if (desc
->dcmd
& 0x2)
2360 qemu_set_irq(s
->irq
, 1);
2362 if ((desc
->dcmd
) & 0x1)
2364 /*fetch next descriptor */
2365 desc_phy
= s
->dda
[channel
] & 0xfffff000;
2366 desc_phy
+= (desc
->dtadr
& 0xff000000) >> 24;
2367 pd
= cpu_get_physical_page_desc(desc_phy
);
2368 if ((pd
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2369 cpu_abort(cpu_single_env
,
2370 "%s: DMA descriptor address %x outside RAM!\n",
2371 __FUNCTION__
, desc_phy
);
2373 desc
= (struct jz4740_desc_s
*) (phys_ram_base
+
2374 (pd
& TARGET_PAGE_MASK
)
2377 ~TARGET_PAGE_MASK
));
2379 cpu_abort(cpu_single_env
,
2380 "%s: DMA descriptor %x is NULL!\n",
2381 __FUNCTION__
, (uint32_t) desc
);
2388 static void jz4740_dma_en_channel(struct jz4740_dma_s
*s
, int channel
)
2392 if (s
->dcs
[channel
] & (1 << 31))
2395 jz4740_dma_ndrun(s
, channel
);
2400 static inline void jz4740_dma_en_global(struct jz4740_dma_s
*s
)
2403 for (channel
= 0; channel
< JZ4740_DMA_NUM
; channel
++)
2405 jz4740_dma_en_channel(s
, channel
);
2409 static inline void jz4740_dma_en_dbn(struct jz4740_dma_s
*s
, int channel
)
2411 if ((s
->dmac
& 0x1) && (s
->dcs
[channel
] & (1 << 31)))
2413 jz4740_dma_drun(s
, channel
);
2417 static void jz4740_dma_reset(struct jz4740_dma_s
*s
)
2422 static uint32_t jz4740_dma_read(void *opaque
, target_phys_addr_t addr
)
2424 struct jz4740_dma_s
*s
= (struct jz4740_dma_s
*) opaque
;
2427 debug_out(DEBUG_DMA
, "jz4740_dma_read addr %x \n", addr
);
2442 channel
= (addr
- 0x0) / 0x20;
2443 return s
->dsa
[channel
];
2450 channel
= (addr
- 0x4) / 0x20;
2451 return s
->dta
[channel
];
2458 channel
= (addr
- 0x8) / 0x20;
2459 return s
->dtc
[channel
];
2466 channel
= (addr
- 0xc) / 0x20;
2467 return s
->drs
[channel
];
2474 channel
= (addr
- 0x10) / 0x20;
2475 return s
->dcs
[channel
];
2482 channel
= (addr
- 0x14) / 0x20;
2483 return s
->dcm
[channel
];
2490 channel
= (addr
- 0x18) / 0x20;
2491 return s
->dda
[channel
];
2493 cpu_abort(s
->soc
->env
,
2494 "jz4740_dma_read undefined addr " JZ_FMT_plx
" \n", addr
);
2499 static void jz4740_dma_write(void *opaque
, target_phys_addr_t addr
,
2502 struct jz4740_dma_s
*s
= (struct jz4740_dma_s
*) opaque
;
2505 debug_out(DEBUG_DMA
, "jz4740_dma_write addr %x value %x \n", addr
, value
);
2509 JZ4740_RO_REG(addr
);
2512 s
->dmac
= value
& 0x30d;
2514 jz4740_dma_en_global(s
);
2518 s
->ddr
= value
& 0xff;
2519 for (channel
= 0; channel
< JZ4740_DMA_NUM
; channel
++)
2521 if (s
->ddr
& (1 << channel
))
2523 jz4740_dma_en_dbn(s
, channel
);
2534 channel
= (addr
- 0x0) / 0x20;
2535 s
->dsa
[channel
] = value
;
2543 channel
= (addr
- 0x4) / 0x20;
2544 s
->dta
[channel
] = value
;
2552 channel
= (addr
- 0x8) / 0x20;
2553 s
->dtc
[channel
] = value
;
2561 channel
= (addr
- 0xc) / 0x20;
2562 s
->drs
[channel
] = value
& 0x10;
2563 if (s
->drs
[channel
] != 0x8)
2565 fprintf(stderr
, "Only auto request is supproted \n");
2574 channel
= (addr
- 0x10) / 0x20;
2575 s
->dcs
[channel
] = value
& 0x80ff005f;
2576 if (s
->dcs
[channel
] & 0x1)
2577 jz4740_dma_en_channel(s
, channel
);
2585 channel
= (addr
- 0x14) / 0x20;
2586 s
->dcm
[channel
] = value
& 0xcff79f;
2594 channel
= (addr
- 0x18) / 0x20;
2595 s
->dda
[channel
] = 0xfffffff0;
2598 cpu_abort(s
->soc
->env
,
2599 "jz4740_dma_read undefined addr " JZ_FMT_plx
" \n", addr
);
2604 static CPUReadMemoryFunc
*jz4740_dma_readfn
[] = {
2605 jz4740_badwidth_read32
, jz4740_badwidth_read32
, jz4740_dma_read
,
2608 static CPUWriteMemoryFunc
*jz4740_dma_writefn
[] = {
2609 jz4740_badwidth_write32
, jz4740_badwidth_write32
, jz4740_dma_write
,
2613 static struct jz4740_dma_s
*jz4740_dma_init(struct jz_state_s
*soc
,
2617 struct jz4740_dma_s
*s
= (struct jz4740_dma_s
*) qemu_mallocz(sizeof(*s
));
2618 s
->base
= JZ4740_PHYS_BASE(JZ4740_DMAC_BASE
);
2622 jz4740_dma_reset(s
);
2625 cpu_register_io_memory(0, jz4740_dma_readfn
, jz4740_dma_writefn
, s
);
2626 cpu_register_physical_memory(s
->base
, 0x00010000, iomemtype
);
2631 static void jz4740_cpu_reset(void *opaque
)
2633 fprintf(stderr
, "%s: UNIMPLEMENTED!", __FUNCTION__
);
2636 struct jz_state_s
*jz4740_init(unsigned long sdram_size
,
2637 uint32_t osc_extal_freq
, DisplayState
* ds
)
2639 struct jz_state_s
*s
= (struct jz_state_s
*)
2640 qemu_mallocz(sizeof(struct jz_state_s
));
2641 ram_addr_t sram_base
, sdram_base
;
2644 s
->mpu_model
= jz4740
;
2645 s
->env
= cpu_init("jz4740");
2649 fprintf(stderr
, "Unable to find CPU definition\n");
2654 qemu_register_reset(jz4740_cpu_reset
, s
->env
);
2656 s
->sdram_size
= sdram_size
;
2657 s
->sram_size
= JZ4740_SRAM_SIZE
;
2660 jz_clk_init(s
, osc_extal_freq
);
2662 /*map sram to 0x80000000 and sdram to 0x80004000 */
2663 sram_base
= qemu_ram_alloc(s
->sram_size
);
2664 cpu_register_physical_memory(0x0, s
->sram_size
, (sram_base
| IO_MEM_RAM
));
2665 sdram_base
= qemu_ram_alloc(s
->sdram_size
);
2666 cpu_register_physical_memory(JZ4740_SRAM_SIZE
, s
->sdram_size
,
2667 (sdram_base
| IO_MEM_RAM
));
2669 /* Init internal devices */
2670 cpu_mips_irq_init_cpu(s
->env
);
2671 cpu_mips_clock_init(s
->env
);
2675 jz_clk_init(s
, osc_extal_freq
);
2677 intc
= jz4740_intc_init(s
, s
->env
->irq
[2]);
2678 s
->cpm
= jz4740_cpm_init(s
);
2679 s
->emc
= jz4740_emc_init(s
, intc
[2]);
2680 s
->gpio
= jz4740_gpio_init(s
, intc
[25]);
2681 s
->rtc
= jz4740_rtc_init(s
, intc
[15]);
2682 s
->tcu
= jz4740_tcu_if_init(s
, intc
[23], intc
[22], intc
[21]);
2683 jz4740_tcu_init(s
, s
->tcu
, 0);
2684 s
->lcdc
= jz4740_lcdc_init(s
, intc
[30], ds
);
2685 s
->dma
= jz4740_dma_init(s
, intc
[20]);
2688 serial_mm_init(0x10030000, 2, intc
[9], 57600, serial_hds
[0], 1);