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_SADC (1<<0x7)
55 #define DEBUG_FLAG DEBUG_SADC //(DEBUG_CPM|DEBUG_EMC|DEBUG_GPIO \
56 // | DEBUG_RTC | DEBUG_TCU | DEBUG_LCDC | DEBUG_DMA)
57 //DEBUG_TCU// (DEBUG_CPM|DEBUG_EMC|DEBUG_GPIO
58 // | DEBUG_RTC | DEBUG_TCU | DEBUG_LCDC | DEBUG_DMA)
63 static void debug_init(void)
65 fp
= fopen("jz4740.txt", "w+");
68 fprintf(stderr
, "can not open jz4740.txt \n");
72 static void debug_out(uint32_t flag
, const char *format
, ...)
77 if (flag
& DEBUG_FLAG
)
80 vfprintf(fp
, format
, ap
);
87 static void debug_init(void)
90 static void debug_out(uint32_t flag
, const char *format
, ...)
95 uint32_t jz4740_badwidth_read8(void *opaque
, target_phys_addr_t addr
)
100 cpu_physical_memory_read(addr
, (void *) &ret
, 1);
104 void jz4740_badwidth_write8(void *opaque
, target_phys_addr_t addr
,
107 uint8_t val8
= value
;
110 cpu_physical_memory_write(addr
, (void *) &val8
, 1);
113 uint32_t jz4740_badwidth_read16(void *opaque
, target_phys_addr_t addr
)
116 JZ4740_16B_REG(addr
);
117 cpu_physical_memory_read(addr
, (void *) &ret
, 2);
121 void jz4740_badwidth_write16(void *opaque
, target_phys_addr_t addr
,
124 uint16_t val16
= value
;
126 JZ4740_16B_REG(addr
);
127 cpu_physical_memory_write(addr
, (void *) &val16
, 2);
130 uint32_t jz4740_badwidth_read32(void *opaque
, target_phys_addr_t addr
)
134 JZ4740_32B_REG(addr
);
135 cpu_physical_memory_read(addr
, (void *) &ret
, 4);
139 void jz4740_badwidth_write32(void *opaque
, target_phys_addr_t addr
,
142 JZ4740_32B_REG(addr
);
143 cpu_physical_memory_write(addr
, (void *) &value
, 4);
147 /*clock reset and power control*/
150 target_phys_addr_t base
;
151 struct jz_state_s
*soc
;
167 static void jz4740_dump_clocks(jz_clk parent
)
171 debug_out(DEBUG_CPM
, "clock %s rate %d \n", i
->name
, i
->rate
);
172 for (i
= i
->child1
; i
; i
= i
->sibling
)
173 jz4740_dump_clocks(i
);
176 static inline void jz4740_cpccr_update(struct jz4740_cpm_s
*s
,
179 uint32_t ldiv
, mdiv
, pdiv
, hdiv
, cdiv
, udiv
;
180 uint32_t div_table
[10] = {
181 1, 2, 3, 4, 6, 8, 12, 16, 24, 32
184 if (unlikely(new_value
== s
->cpccr
))
187 if (new_value
& CPM_CPCCR_PCS
)
188 jz_clk_setrate(jz_findclk(s
->soc
, "pll_divider"), 1, 1);
190 jz_clk_setrate(jz_findclk(s
->soc
, "pll_divider"), 2, 1);
193 ldiv
= (new_value
& CPM_CPCCR_LDIV_MASK
) >> CPM_CPCCR_LDIV_BIT
;
196 mdiv
= div_table
[(new_value
& CPM_CPCCR_MDIV_MASK
) >> CPM_CPCCR_MDIV_BIT
];
197 pdiv
= div_table
[(new_value
& CPM_CPCCR_PDIV_MASK
) >> CPM_CPCCR_PDIV_BIT
];
198 hdiv
= div_table
[(new_value
& CPM_CPCCR_HDIV_MASK
) >> CPM_CPCCR_HDIV_BIT
];
199 cdiv
= div_table
[(new_value
& CPM_CPCCR_CDIV_MASK
) >> CPM_CPCCR_CDIV_BIT
];
200 udiv
= div_table
[(new_value
& CPM_CPCCR_UDIV_MASK
) >> CPM_CPCCR_UDIV_BIT
];
202 jz_clk_setrate(jz_findclk(s
->soc
, "ldclk"), ldiv
, 1);
203 jz_clk_setrate(jz_findclk(s
->soc
, "mclk"), mdiv
, 1);
204 jz_clk_setrate(jz_findclk(s
->soc
, "pclk"), pdiv
, 1);
205 jz_clk_setrate(jz_findclk(s
->soc
, "hclk"), hdiv
, 1);
206 jz_clk_setrate(jz_findclk(s
->soc
, "cclk"), cdiv
, 1);
207 jz_clk_setrate(jz_findclk(s
->soc
, "usbclk"), udiv
, 1);
209 if (new_value
& CPM_CPCCR_UCS
)
210 jz_clk_reparent(jz_findclk(s
->soc
, "usbclk"),
211 jz_findclk(s
->soc
, "pll_divider"));
213 jz_clk_reparent(jz_findclk(s
->soc
, "usbclk"),
214 jz_findclk(s
->soc
, "osc_extal"));
216 if (new_value
& CPM_CPCCR_I2CS
)
217 jz_clk_reparent(jz_findclk(s
->soc
, "i2sclk"),
218 jz_findclk(s
->soc
, "pll_divider"));
220 jz_clk_reparent(jz_findclk(s
->soc
, "i2sclk"),
221 jz_findclk(s
->soc
, "osc_extal"));
223 s
->cpccr
= new_value
;
225 debug_out(DEBUG_CPM
, "write to cpccr 0x%x\n", new_value
);
227 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
231 static inline void jz4740_cppcr_update(struct jz4740_cpm_s
*s
,
234 uint32_t pllm
, plln
, pllod
, pllbp
, pllen
;
240 pllen
= new_value
& CPM_CPPCR_PLLEN
;
241 pllbp
= new_value
& CPM_CPPCR_PLLBP
;
242 if ((!pllen
) || (pllen
&& pllbp
))
244 jz_clk_setrate(jz_findclk(s
->soc
, "pll_output"), 1, 1);
245 debug_out(DEBUG_CPM
, "pll is bypassed \n");
246 s
->cppcr
= new_value
| CPM_CPPCR_PLLS
;
251 pllm
= (new_value
& CPM_CPPCR_PLLM_MASK
) >> CPM_CPPCR_PLLM_BIT
;
252 plln
= (new_value
& CPM_CPPCR_PLLN_MASK
) >> CPM_CPPCR_PLLN_BIT
;
253 pllod
= (new_value
& CPM_CPPCR_PLLOD_MASK
) >> CPM_CPPCR_PLLOD_BIT
;
254 jz_clk_setrate(jz_findclk(s
->soc
, "pll_output"), (plln
+ 2) * pll0
[pllod
],
257 s
->cppcr
= new_value
;
259 debug_out(DEBUG_CPM
, "write to cppcr 0x%x\n", new_value
);
260 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
264 static inline void jz4740_i2scdr_update(struct jz4740_cpm_s
*s
,
269 i2scdr
= new_value
& CPM_I2SCDR_I2SDIV_MASK
;
270 if (unlikely(i2scdr
== s
->i2scdr
))
274 jz_clk_setrate(jz_findclk(s
->soc
, "i2sclk"), i2scdr
+ 1, 1);
278 debug_out(DEBUG_CPM
, "write to i2scdr 0x%x\n", new_value
);
279 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
283 static inline void jz4740_lpcdr_update(struct jz4740_cpm_s
*s
,
288 ipcdr
= new_value
& CPM_LPCDR_PIXDIV_MASK
;
293 static inline void jz4740_msccdr_update(struct jz4740_cpm_s
*s
,
298 msccdr
= new_value
& CPM_MSCCDR_MSCDIV_MASK
;
300 if (unlikely(msccdr
== s
->msccdr
))
304 jz_clk_setrate(jz_findclk(s
->soc
, "mscclk"), msccdr
+ 1, 1);
308 debug_out(DEBUG_CPM
, "write to msccdr 0x%x\n", new_value
);
309 jz4740_dump_clocks(jz_findclk(s
->soc
, "osc_extal"));
313 static inline void jz4740_uhccdr_update(struct jz4740_cpm_s
*s
,
318 uhccdr
= new_value
& 0xf;
323 static void jz4740_cpm_write(void *opaque
, target_phys_addr_t addr
,
326 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) opaque
;
328 debug_out(DEBUG_CPM
, "write to cpm addr %x value 0x%x\n", addr
, value
);
333 jz4740_cpccr_update(s
, value
);
336 s
->lcr
= value
& 0xff;
339 s
->clkgr
= value
& 0xffff;
342 s
->scr
= value
& 0xffff;
345 jz4740_cppcr_update(s
, value
);
348 jz4740_i2scdr_update(s
, value
);
351 jz4740_lpcdr_update(s
, value
);
354 jz4740_msccdr_update(s
, value
);
357 jz4740_uhccdr_update(s
, value
);
360 s
->uhctst
= value
& 0x3f;
363 s
->ssicdr
= value
& 0xf;
366 cpu_abort(s
->soc
->env
,
367 "jz4740_cpm_write undefined addr " JZ_FMT_plx
368 " value %x \n", addr
, value
);
374 static uint32_t jz474_cpm_read(void *opaque
, target_phys_addr_t addr
)
376 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) opaque
;
403 cpu_abort(s
->soc
->env
,
404 "jz474_cpm_read undefined addr " JZ_FMT_plx
" \n", addr
);
411 static CPUReadMemoryFunc
*jz4740_cpm_readfn
[] = {
412 jz4740_badwidth_read32
,
413 jz4740_badwidth_read32
,
417 static CPUWriteMemoryFunc
*jz4740_cpm_writefn
[] = {
418 jz4740_badwidth_write32
,
419 jz4740_badwidth_write32
,
423 static void jz4740_cpm_reset(struct jz4740_cpm_s
*s
)
425 s
->cpccr
= 0x42040000;
426 s
->cppcr
= 0x28080011;
427 s
->i2scdr
= 0x00000004;
428 s
->lpcdr
= 0x00000004;
429 s
->msccdr
= 0x00000004;
430 s
->uhccdr
= 0x00000004;
432 s
->ssicdr
= 0x00000004;
439 static struct jz4740_cpm_s
*jz4740_cpm_init(struct jz_state_s
*soc
)
442 struct jz4740_cpm_s
*s
= (struct jz4740_cpm_s
*) qemu_mallocz(sizeof(*s
));
443 s
->base
= JZ4740_PHYS_BASE(JZ4740_CPM_BASE
);
449 cpu_register_io_memory(0, jz4740_cpm_readfn
, jz4740_cpm_writefn
, s
);
450 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
455 /* JZ4740 interrupt controller
456 * It issues INT2 to MIPS
462 target_phys_addr_t base
;
463 struct jz_state_s
*soc
;
472 static uint32_t jz4740_intc_read(void *opaque
, target_phys_addr_t addr
)
474 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
489 cpu_abort(s
->soc
->env
,
490 "jz4740_intc_read undefined addr " JZ_FMT_plx
" \n", addr
);
496 static void jz4740_intc_write(void *opaque
, target_phys_addr_t addr
,
499 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
517 qemu_set_irq(s
->parent_irq
, 0);
520 cpu_abort(s
->soc
->env
,
521 "jz4740_intc_write undefined addr " JZ_FMT_plx
522 " value %x \n", addr
, value
);
527 static CPUReadMemoryFunc
*jz4740_intc_readfn
[] = {
528 jz4740_badwidth_read32
,
529 jz4740_badwidth_read32
,
533 static CPUWriteMemoryFunc
*jz4740_intc_writefn
[] = {
534 jz4740_badwidth_write32
,
535 jz4740_badwidth_write32
,
539 static void jz4740_intc_reset(struct jz4740_intc_s
*s
)
542 s
->icmr
= 0xffffffff;
546 static void jz4740_set_irq(void *opaque
, int irq
, int level
)
548 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) opaque
;
549 uint32_t irq_mask
= 1 << irq
;
555 s
->icpr
&= ~irq_mask
;
556 if (!(s
->icmr
& irq_mask
))
559 qemu_set_irq(s
->parent_irq
, 1);
565 static qemu_irq
*jz4740_intc_init(struct jz_state_s
*soc
, qemu_irq parent_irq
)
568 struct jz4740_intc_s
*s
= (struct jz4740_intc_s
*) qemu_mallocz(sizeof(*s
));
569 s
->base
= JZ4740_PHYS_BASE(JZ4740_INTC_BASE
);
570 s
->parent_irq
= parent_irq
;
573 jz4740_intc_reset(s
);
576 cpu_register_io_memory(0, jz4740_intc_readfn
, jz4740_intc_writefn
, s
);
577 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
578 return qemu_allocate_irqs(jz4740_set_irq
, s
, 32);
581 /*external memory controller*/
585 target_phys_addr_t base
;
586 struct jz_state_s
*soc
;
589 uint32_t smcr1
; /*0x13010014 */
590 uint32_t smcr2
; /*0x13010018 */
591 uint32_t smcr3
; /*0x1301001c */
592 uint32_t smcr4
; /*0x13010020 */
593 uint32_t sacr1
; /*0x13010034 */
594 uint32_t sacr2
; /*0x13010038 */
595 uint32_t sacr3
; /*0x1301003c */
596 uint32_t sacr4
; /*0x13010040 */
598 uint32_t nfcsr
; /*0x13010050 */
599 uint32_t nfeccr
; /*0x13010100 */
600 uint32_t nfecc
; /*0x13010104 */
601 uint32_t nfpar0
; /*0x13010108 */
602 uint32_t nfpar1
; /*0x1301010c */
603 uint32_t nfpar2
; /*0x13010110 */
604 uint32_t nfints
; /*0x13010114 */
605 uint32_t nfinte
; /*0x13010118 */
606 uint32_t nferr0
; /*0x1301011c */
607 uint32_t nferr1
; /*0x13010120 */
608 uint32_t nferr2
; /*0x13010124 */
609 uint32_t nferr3
; /*0x13010128 */
611 uint32_t dmcr
; /*0x13010080 */
612 uint32_t rtcsr
; /*0x13010084 */
613 uint32_t rtcnt
; /*0x13010088 */
614 uint32_t rtcor
; /*0x1301008c */
615 uint32_t dmar
; /*0x13010090 */
616 uint32_t sdmr
; /*0x1301a000 */
621 static void jz4740_emc_reset(struct jz4740_emc_s
*s
)
623 s
->smcr1
= 0xfff7700;
624 s
->smcr2
= 0xfff7700;
625 s
->smcr3
= 0xfff7700;
626 s
->smcr4
= 0xfff7700;
654 static uint32_t jz4740_emc_read8(void *opaque
, target_phys_addr_t addr
)
656 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
664 return (s
->nfpar0
>> ((addr
- 0x108) * 8)) & 0xff;
669 return (s
->nfpar1
>> ((addr
- 0x10c) * 8)) & 0xff;
674 return (s
->nfpar2
>> ((addr
- 0x110) * 8)) & 0xff;
679 return (s
->sdmr
>> ((addr
- 0xa000) * 8)) & 0xff;
681 cpu_abort(s
->soc
->env
,
682 "jz4740_emc_read8 undefined addr " JZ_FMT_plx
" \n", addr
);
689 static uint32_t jz4740_emc_read16(void *opaque
, target_phys_addr_t addr
)
691 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
697 return (s
->nfpar0
>> ((addr
- 0x108) * 8)) & 0xffff;
700 return (s
->nfpar1
>> ((addr
- 0x10c) * 8)) & 0xffff;
703 return (s
->nfpar2
>> ((addr
- 0x110) * 8)) & 0xffff;
706 return (s
->nferr0
>> ((addr
- 0x11c) * 8)) & 0xffff;
709 return (s
->nferr1
>> ((addr
- 0x120) * 8)) & 0xffff;
712 return (s
->nferr2
>> ((addr
- 0x124) * 8)) & 0xffff;
715 return (s
->nferr3
>> ((addr
- 0x128) * 8)) & 0xffff;
717 cpu_abort(s
->soc
->env
,
718 "jz4740_emc_read16 undefined addr " JZ_FMT_plx
" \n", addr
);
723 static uint32_t jz4740_emc_read32(void *opaque
, target_phys_addr_t addr
)
725 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
776 cpu_abort(s
->soc
->env
,
777 "jz4740_emc_read32 undefined addr " JZ_FMT_plx
" \n", addr
);
782 static void jz4740_emc_write8(void *opaque
, target_phys_addr_t addr
,
785 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
787 debug_out(DEBUG_EMC
, "jz4740_emc_write8 addr %x value %x\n", addr
, value
);
795 s
->nfpar0
|= (value
& 0xff) << ((addr
- 0x108) * 8);
801 s
->nfpar1
|= (value
& 0xff) << ((addr
- 0x10c) * 8);
807 s
->nfpar2
|= (value
& 0xff) << ((addr
- 0x110) * 8);
809 case 0xa000 ... 0xa3ff:
812 cpu_abort(s
->soc
->env
,
813 "jz4740_emc_write8 undefined addr " JZ_FMT_plx
814 " value %x \n", addr
, value
);
817 static void jz4740_emc_write16(void *opaque
, target_phys_addr_t addr
,
820 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
822 debug_out(DEBUG_EMC
, "jz4740_emc_write16 addr %x value %x\n", addr
, value
);
827 s
->nfpar0
|= (value
& 0xffff) << ((addr
- 0x108) * 8);
831 s
->nfpar1
|= (value
& 0xffff) << ((addr
- 0x10c) * 8);
835 s
->nfpar2
|= (value
& 0xffff) << ((addr
- 0x110) * 8);
839 s
->rtcsr
|= (value
& 0xffff) << ((addr
- 0x84) * 8);
843 s
->rtcnt
|= (value
& 0xffff) << ((addr
- 0x88) * 8);
846 s
->rtcor
|= (value
& 0xffff) << ((addr
- 0x8c) * 8);
849 cpu_abort(s
->soc
->env
,
850 "jz4740_emc_write16 undefined addr " JZ_FMT_plx
851 " value %x \n", addr
, value
);
855 static void jz4740_emc_upate_interrupt(struct jz4740_emc_s
*s
)
857 qemu_set_irq(s
->irq
, s
->nfints
& s
->nfinte
);
860 static void jz4740_emc_write32(void *opaque
, target_phys_addr_t addr
,
863 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) opaque
;
865 debug_out(DEBUG_EMC
, "jz4740_emc_write32 addr %x value %x\n", addr
, value
);
879 s
->smcr1
= value
& 0xfff77cf;
882 s
->smcr2
= value
& 0xfff77cf;
885 s
->smcr3
= value
& 0xfff77cf;
888 s
->smcr4
= value
& 0xfff77cf;
891 s
->sacr1
= value
& 0xffff;
894 s
->sacr2
= value
& 0xffff;
897 s
->sacr3
= value
& 0xffff;
900 s
->sacr4
= value
& 0xffff;
903 s
->nfcsr
= value
& 0xffff;
906 s
->nfeccr
= value
& 0x1f;
921 /*TODO: Real RS error correction */
924 if ((s
->nfeccr
& 0x10) && (!(s
->nfeccr
& 0x8)))
936 s
->nfpar0
= 0xffffffff; /*fake value. for debug */
937 s
->nfpar1
= 0xffffffff; /*fake value */
938 s
->nfpar2
= 0xff; /*fake value */
945 jz4740_emc_upate_interrupt(s
);
954 s
->nfpar2
= value
& 0xff;
957 s
->nfints
= value
& 0x1fffffff;
958 jz4740_emc_upate_interrupt(s
);
961 s
->nfinte
= value
& 0x1f;
962 jz4740_emc_upate_interrupt(s
);
965 s
->dmcr
= value
& 0x9fbeff7f;
968 s
->dmar
= value
& 0xffff;
971 cpu_abort(s
->soc
->env
,
972 "jz4740_emc_write32 undefined addr " JZ_FMT_plx
973 " value %x \n", addr
, value
);
979 static CPUReadMemoryFunc
*jz4740_emc_readfn
[] = {
985 static CPUWriteMemoryFunc
*jz4740_emc_writefn
[] = {
992 static struct jz4740_emc_s
*jz4740_emc_init(struct jz_state_s
*soc
,
996 struct jz4740_emc_s
*s
= (struct jz4740_emc_s
*) qemu_mallocz(sizeof(*s
));
997 s
->base
= JZ4740_PHYS_BASE(JZ4740_EMC_BASE
);
1001 jz4740_emc_reset(s
);
1004 cpu_register_io_memory(0, jz4740_emc_readfn
, jz4740_emc_writefn
, s
);
1005 cpu_register_physical_memory(s
->base
, 0x00010000, iomemtype
);
1010 struct jz4740_gpio_s
1013 target_phys_addr_t base
;
1014 struct jz_state_s
*soc
;
1027 static void jz4740_gpio_reset(struct jz4740_gpio_s
*s
)
1029 memset(s
->papin
, 0x0, sizeof(s
->papin
));
1030 memset(s
->padat
, 0x0, sizeof(s
->padat
));
1031 memset(s
->paim
, 0xffffffff, sizeof(s
->paim
));
1032 memset(s
->pape
, 0x0, sizeof(s
->pape
));
1033 memset(s
->pafun
, 0x0, sizeof(s
->pafun
));
1034 memset(s
->pasel
, 0x0, sizeof(s
->pasel
));
1035 memset(s
->padir
, 0x0, sizeof(s
->padir
));
1036 memset(s
->patrg
, 0x0, sizeof(s
->patrg
));
1037 memset(s
->paflg
, 0x0, sizeof(s
->paflg
));
1040 static uint32_t jz4740_gpio_read(void *opaque
, target_phys_addr_t addr
)
1042 struct jz4740_gpio_s
*s
= (struct jz4740_gpio_s
*) opaque
;
1044 debug_out(DEBUG_GPIO
, "jz4740_gpio_read addr %x\n", addr
);
1108 JZ4740_WO_REG(addr
);
1115 group
= (addr
- 0x0) / 0x100;
1118 /*GPIO(C) PIN 30 -> NAND FLASH R/B. */
1119 /*FOR NAND FLASH.PIN 30 ----|_____|------ */
1120 s
->papin
[2] &= 0x40000000;
1122 s
->papin
[2] &= ~0x40000000;
1124 s
->papin
[2] |= 0x40000000;
1126 return s
->papin
[group
];
1131 group
= (addr
- 0x10) / 0x100;
1132 return s
->padat
[group
];
1137 group
= (addr
- 0x20) / 0x100;
1138 return s
->paim
[group
];
1143 group
= (addr
- 0x30) / 0x100;
1144 return s
->pape
[group
];
1149 group
= (addr
- 0x40) / 0x100;
1150 return s
->pafun
[group
];
1155 group
= (addr
- 0x50) / 0x100;
1156 return s
->pasel
[group
];
1161 group
= (addr
- 0x60) / 0x100;
1162 return s
->padir
[group
];
1167 group
= (addr
- 0x70) / 0x100;
1168 return s
->patrg
[group
];
1173 group
= (addr
- 0x80) / 0x100;
1174 return s
->paflg
[group
];
1176 cpu_abort(s
->soc
->env
,
1177 "jz4740_gpio_read undefined addr " JZ_FMT_plx
" \n", addr
);
1182 static void jz4740_gpio_write(void *opaque
, target_phys_addr_t addr
,
1185 struct jz4740_gpio_s
*s
= (struct jz4740_gpio_s
*) opaque
;
1188 debug_out(DEBUG_GPIO
, "jz4740_gpio_write addr %x value %x\n", addr
, value
);
1228 JZ4740_RO_REG(addr
);
1234 group
= (addr
- 0x14) / 0x100;
1235 s
->padat
[group
] = value
;
1241 group
= (addr
- 0x18) / 0x100;
1242 s
->padat
[group
] &= ~value
;
1248 group
= (addr
- 0x24) / 0x100;
1249 s
->paim
[group
] = value
;
1255 group
= (addr
- 0x28) / 0x100;
1256 s
->paim
[group
] &= ~value
;
1262 group
= (addr
- 0x34) / 0x100;
1263 s
->pape
[group
] = value
;
1269 group
= (addr
- 0x38) / 0x100;
1270 s
->pape
[group
] &= ~value
;
1276 group
= (addr
- 0x44) / 0x100;
1277 s
->pafun
[group
] = value
;
1283 group
= (addr
- 0x48) / 0x100;
1284 s
->pafun
[group
] &= ~value
;
1290 group
= (addr
- 0x54) / 0x100;
1291 s
->pasel
[group
] = value
;
1297 group
= (addr
- 0x58) / 0x100;
1298 s
->pasel
[group
] &= ~value
;
1304 group
= (addr
- 0x64) / 0x100;
1305 s
->padir
[group
] = value
;
1311 group
= (addr
- 0x68) / 0x100;
1312 s
->padir
[group
] &= ~value
;
1318 group
= (addr
- 0x74) / 0x100;
1319 s
->patrg
[group
] = value
;
1325 group
= (addr
- 0x78) / 0x100;
1326 s
->patrg
[group
] &= ~value
;
1332 group
= (addr
- 0x74) / 0x100;
1333 s
->paflg
[group
] &= ~value
;
1336 cpu_abort(s
->soc
->env
,
1337 "jz4740_gpio_write undefined addr " JZ_FMT_plx
1338 " value %x \n", addr
, value
);
1346 static CPUReadMemoryFunc
*jz4740_gpio_readfn
[] = {
1347 jz4740_badwidth_read32
,
1348 jz4740_badwidth_read32
,
1352 static CPUWriteMemoryFunc
*jz4740_gpio_writefn
[] = {
1353 jz4740_badwidth_write32
,
1354 jz4740_badwidth_write32
,
1358 static struct jz4740_gpio_s
*jz4740_gpio_init(struct jz_state_s
*soc
,
1362 struct jz4740_gpio_s
*s
= (struct jz4740_gpio_s
*) qemu_mallocz(sizeof(*s
));
1363 s
->base
= JZ4740_PHYS_BASE(JZ4740_GPIO_BASE
);
1367 jz4740_gpio_reset(s
);
1370 cpu_register_io_memory(0, jz4740_gpio_readfn
, jz4740_gpio_writefn
, s
);
1371 cpu_register_physical_memory(s
->base
, 0x00010000, iomemtype
);
1379 target_phys_addr_t base
;
1380 struct jz_state_s
*soc
;
1402 static void jz4740_rtc_update_interrupt(struct jz4740_rtc_s
*s
)
1404 /* if (((s->rtcsr & 0x40) && (s->rtcsr & 0x20))
1405 || ((s->rtcsr & 0x10) && (s->rtcsr & 0x8)))
1406 qemu_set_irq(s->irq, 1);*/
1408 // qemu_set_irq(s->irq, 0);
1411 static inline void jz4740_rtc_start(struct jz4740_rtc_s
*s
)
1413 s
->next
= +qemu_get_clock(rt_clock
);
1414 qemu_mod_timer(s
->hz_tm
, s
->next
);
1417 static inline void jz4740_rtc_stop(struct jz4740_rtc_s
*s
)
1419 qemu_del_timer(s
->hz_tm
);
1420 s
->next
= -qemu_get_clock(rt_clock
);
1425 static void jz4740_rtc_hz(void *opaque
)
1427 struct jz4740_rtc_s
*s
= (struct jz4740_rtc_s
*) opaque
;
1430 qemu_mod_timer(s
->hz_tm
, s
->next
);
1437 if (s
->rtcsr
== s
->rtcsar
)
1440 jz4740_rtc_update_interrupt(s
);
1444 static void jz4740_rtc_reset(struct jz4740_rtc_s
*s
)
1450 /*Maybe rtcsr need to be saved to file */
1452 //s->sec_offset = 0;
1453 //qemu_get_timedate(&s->tm, s->sec_offset);
1454 jz4740_rtc_start(s
);
1458 static uint32_t jz4740_rtc_read(void *opaque
, target_phys_addr_t addr
)
1460 struct jz4740_rtc_s
*s
= (struct jz4740_rtc_s
*) opaque
;
1462 debug_out(DEBUG_RTC
, "jz4740_rtc_read addr %x\n", addr
);
1466 return s
->rtccr
| 0x80;
1486 cpu_abort(s
->soc
->env
,
1487 "jz4740_rtc_read undefined addr " JZ_FMT_plx
"\n", addr
);
1493 static void jz4740_rtc_write(void *opaque
, target_phys_addr_t addr
,
1496 struct jz4740_rtc_s
*s
= (struct jz4740_rtc_s
*) opaque
;
1498 debug_out(DEBUG_RTC
, "jz4740_rtc_write addr %x value %x\n", addr
, value
);
1503 s
->rtccr
= value
& 0x2d;
1510 //jz4740_rtc_start(s);
1511 jz4740_rtc_update_interrupt(s
);
1518 //s->sec_offset = qemu_timedate_diff(&s->tm);
1524 s
->rtcgr
= value
& 0x13ffffff;
1527 s
->hcr
= value
& 0x1;
1530 s
->hwfcr
= value
& 0xffe0;
1533 s
->hrcr
= value
& 0xfe0;
1536 s
->hwcr
= value
& 0x1;
1539 s
->hwrsr
= value
& 0x33;
1545 cpu_abort(s
->soc
->env
,
1546 "jz4740_rtc_write undefined addr " JZ_FMT_plx
1547 " value %x \n", addr
, value
);
1552 static CPUReadMemoryFunc
*jz4740_rtc_readfn
[] = {
1553 jz4740_badwidth_read32
,
1554 jz4740_badwidth_read32
,
1558 static CPUWriteMemoryFunc
*jz4740_rtc_writefn
[] = {
1559 jz4740_badwidth_write32
,
1560 jz4740_badwidth_write32
,
1564 static struct jz4740_rtc_s
*jz4740_rtc_init(struct jz_state_s
*soc
,
1568 struct jz4740_rtc_s
*s
= (struct jz4740_rtc_s
*) qemu_mallocz(sizeof(*s
));
1569 s
->base
= JZ4740_PHYS_BASE(JZ4740_RTC_BASE
);
1573 s
->hz_tm
= qemu_new_timer(rt_clock
, jz4740_rtc_hz
, s
);
1575 jz4740_rtc_reset(s
);
1578 cpu_register_io_memory(0, jz4740_rtc_readfn
, jz4740_rtc_writefn
, s
);
1579 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
1589 target_phys_addr_t base
;
1590 struct jz_state_s
*soc
;
1593 QEMUTimer
*half_timer
[8];
1594 QEMUTimer
*full_timer
[8];
1607 uint32_t prescale
[8];
1611 static void jz4740_tcu_update_interrupt(struct jz4740_tcu_s
*s
)
1613 //printf("s->tfr %x s->tmr %x \n",s->tfr,s->tmr);
1614 if (((s
->tfr
& 0x1) & (~(s
->tmr
& 0x1)))
1615 || ((s
->tfr
& 0x10000) & (~(s
->tmr
& 0x10000))))
1617 qemu_set_irq(s
->tcu_irq0
, 1);
1620 qemu_set_irq(s
->tcu_irq0
, 0);
1622 if (((s
->tfr
& 0x2) & (~(s
->tmr
& 0x2)))
1623 || ((s
->tfr
& 0x20000) & (~(s
->tmr
& 0x20000))))
1625 qemu_set_irq(s
->tcu_irq1
, 1);
1628 qemu_set_irq(s
->tcu_irq1
, 0);
1630 if (((s
->tfr
& 0xfc) & (~(s
->tmr
& 0xfc)))
1631 || ((s
->tfr
& 0xfc0000) & (~(s
->tmr
& 0xfc0000))))
1633 qemu_set_irq(s
->tcu_irq2
, 1);
1636 qemu_set_irq(s
->tcu_irq2
, 0);
1642 #include "mips_jz_glue.h"
1644 #include "mips_jz_glue.h"
1646 #include "mips_jz_glue.h"
1648 #include "mips_jz_glue.h"
1650 #include "mips_jz_glue.h"
1652 #include "mips_jz_glue.h"
1654 #include "mips_jz_glue.h"
1656 #include "mips_jz_glue.h"
1659 #define jz4740_tcu_start(s) do { \
1660 jz4740_tcu_start_half0(s); \
1661 jz4740_tcu_start_full0(s); \
1662 jz4740_tcu_start_half1(s); \
1663 jz4740_tcu_start_full1(s); \
1664 jz4740_tcu_start_half2(s); \
1665 jz4740_tcu_start_full2(s); \
1666 jz4740_tcu_start_half3(s); \
1667 jz4740_tcu_start_full3(s); \
1668 jz4740_tcu_start_half4(s); \
1669 jz4740_tcu_start_full4(s); \
1670 jz4740_tcu_start_half5(s); \
1671 jz4740_tcu_start_full5(s); \
1672 jz4740_tcu_start_half6(s); \
1673 jz4740_tcu_start_full6(s); \
1674 jz4740_tcu_start_half7(s); \
1675 jz4740_tcu_start_full7(s); \
1678 static void jz4740_tcu_if_reset(struct jz4740_tcu_s
*s
)
1686 for (i
= 0; i
< 8; i
++)
1688 s
->tdfr
[i
] = 0xffff;
1689 s
->tdhr
[i
] = 0x8000;
1692 s
->half_timer
[i
] = NULL
;
1693 s
->full_timer
[i
] = NULL
;
1697 static void jz4740_tcu_if_write8(void *opaque
, target_phys_addr_t addr
,
1700 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) opaque
;
1702 debug_out(DEBUG_TCU
, "jz4740_tcu_if_write8 addr %x value %x\n", addr
,
1708 s
->ter
|= (value
& 0xff);
1709 jz4740_tcu_start(s
);
1712 s
->ter
&= ~(value
& 0xff);
1713 jz4740_tcu_start(s
);
1716 cpu_abort(s
->soc
->env
,
1717 "jz4740_tcu_if_write8 undefined addr " JZ_FMT_plx
1718 " value %x \n", addr
, value
);
1723 static void jz4740_tcu_if_write32(void *opaque
, target_phys_addr_t addr
,
1726 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) opaque
;
1728 debug_out(DEBUG_TCU
, "jz4740_tcu_if_write32 addr %x value %x\n", addr
,
1734 s
->tsr
|= (value
& 0x100ff);
1735 jz4740_tcu_start(s
);
1738 s
->tsr
&= ~(value
& 0x100ff);
1739 jz4740_tcu_start(s
);
1742 s
->tfr
|= (value
& 0xff00ff);
1745 s
->tfr
&= ~(value
& 0xff00ff);
1748 s
->tmr
|= (value
& 0xff00ff);
1749 jz4740_tcu_update_interrupt(s
);
1752 s
->tmr
&= ~(value
& 0xff00ff);
1753 jz4740_tcu_update_interrupt(s
);
1756 cpu_abort(s
->soc
->env
,
1757 "jz4740_tcu_if_write32 undefined addr " JZ_FMT_plx
1758 " value %x \n", addr
, value
);
1763 static uint32_t jz4740_tcu_if_read8(void *opaque
, target_phys_addr_t addr
)
1765 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) opaque
;
1767 debug_out(DEBUG_TCU
, "jz4740_tcu_if_read8 addr %x\n", addr
);
1774 cpu_abort(s
->soc
->env
,
1775 "jz4740_tcu_if_read8 undefined addr " JZ_FMT_plx
"\n", addr
);
1780 static uint32_t jz4740_tcu_if_read32(void *opaque
, target_phys_addr_t addr
)
1782 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) opaque
;
1784 debug_out(DEBUG_TCU
, "jz4740_tcu_if_read32 addr %x\n", addr
);
1795 cpu_abort(s
->soc
->env
,
1796 "jz4740_tcu_if_read32 undefined addr " JZ_FMT_plx
"\n", addr
);
1803 static CPUReadMemoryFunc
*jz4740_tcu_if_readfn
[] = {
1804 jz4740_tcu_if_read8
,
1805 jz4740_badwidth_read32
,
1806 jz4740_tcu_if_read32
,
1809 static CPUWriteMemoryFunc
*jz4740_tcu_if_writefn
[] = {
1810 jz4740_tcu_if_write8
,
1811 jz4740_badwidth_write32
,
1812 jz4740_tcu_if_write32
,
1815 static struct jz4740_tcu_s
*jz4740_tcu_if_init(struct jz_state_s
*soc
,
1823 struct jz4740_tcu_s
*s
= (struct jz4740_tcu_s
*) qemu_mallocz(sizeof(*s
));
1824 s
->base
= JZ4740_PHYS_BASE(JZ4740_TCU_BASE
);
1826 s
->tcu_irq0
= tcu_irq0
;
1827 s
->tcu_irq1
= tcu_irq1
;
1828 s
->tcu_irq2
= tcu_irq2
;
1830 jz4740_tcu_if_reset(s
);
1833 cpu_register_io_memory(0, jz4740_tcu_if_readfn
, jz4740_tcu_if_writefn
,
1835 cpu_register_physical_memory(s
->base
, 0x00000040, iomemtype
);
1840 static void jz4740_tcu_init(struct jz_state_s
*soc
,
1841 struct jz4740_tcu_s
*s
, int timer_index
)
1843 switch (timer_index
)
1846 jz4740_tcu_init0(soc
, s
);
1849 jz4740_tcu_init1(soc
, s
);
1852 jz4740_tcu_init2(soc
, s
);
1855 jz4740_tcu_init3(soc
, s
);
1858 jz4740_tcu_init4(soc
, s
);
1861 jz4740_tcu_init5(soc
, s
);
1864 jz4740_tcu_init6(soc
, s
);
1867 jz4740_tcu_init7(soc
, s
);
1870 cpu_abort(s
->soc
->env
,
1871 "jz4740_tcu_init undefined timer %x \n", timer_index
);
1875 typedef void (*jz4740_lcd_fn_t
) (uint8_t * d
, const uint8_t * s
, int width
,
1876 const uint16_t * pal
);
1877 struct jz_fb_descriptor
1879 uint32_t fdadr
; /* Frame descriptor address register */
1880 uint32_t fsadr
; /* Frame source address register */
1881 uint32_t fidr
; /* Frame ID register */
1882 uint32_t ldcmd
; /* Command register */
1885 struct jz4740_lcdc_s
1889 target_phys_addr_t base
;
1890 struct jz_state_s
*soc
;
1892 DisplayState
*state
;
1893 QEMUConsole
*console
;
1894 jz4740_lcd_fn_t
*line_fn_tab
;
1895 jz4740_lcd_fn_t line_fn
;
1924 uint32_t bpp
; /*bit per second */
1925 uint16_t palette
[256];
1926 uint32_t invalidate
;
1931 static const int jz4740_lcd_bpp
[0x6] = {
1932 1, 2, 4, 8, 16, 32 /*4740 uses 32 bit for 24bpp */
1935 static void jz4740_lcdc_reset(struct jz4740_lcdc_s
*s
)
1940 static uint32_t jz4740_lcdc_read(void *opaque
, target_phys_addr_t addr
)
1942 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) opaque
;
1944 debug_out(DEBUG_LCDC
, "jz4740_lcdc_read addr %x \n", addr
);
1990 cpu_abort(s
->soc
->env
,
1991 "jz4740_lcdc_read undefined addr " JZ_FMT_plx
" \n", addr
);
1997 static void jz4740_lcdc_write(void *opaque
, target_phys_addr_t addr
,
2000 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) opaque
;
2002 debug_out(DEBUG_LCDC
, "jz4740_lcdc_write addr %x value %x\n", addr
, value
);
2009 JZ4740_RO_REG(addr
);
2012 s
->lcdcfg
= value
& 0x80ffffbf;
2015 s
->lcdvsync
= value
& 0x7ff07ff;
2018 s
->lcdhsync
= value
& 0x7ff07ff;
2021 s
->lcdvat
= value
& 0x7ff07ff;
2024 s
->lcddah
= value
& 0x7ff07ff;
2025 s
->width
= (value
& 0x7ff) - ((value
>> 16) & 0x7ff);
2028 s
->height
= (value
& 0x7ff) - ((value
>> 16) & 0x7ff);
2029 s
->lcddav
= value
& 0x7ff07ff;
2032 s
->lcdps
= value
& 0x7ff07ff;
2035 s
->lcdcls
= value
& 0x7ff07ff;
2038 s
->lcdspl
= value
& 0x7ff07ff;
2041 s
->lcdrev
= value
& 0x7ff0000;
2044 s
->lcdctrl
= value
& 0x3fff3fff;
2045 s
->ena
= (value
& 0x8) >> 3;
2046 s
->dis
= (value
& 0x10) >> 4;
2047 s
->bpp
= jz4740_lcd_bpp
[value
& 0x7];
2050 fprintf(stderr
, "bpp =1 is not supported\n");
2053 s
->line_fn
= s
->line_fn_tab
[value
& 0x7];
2056 s
->lcdstate
= value
& 0xbf;
2068 cpu_abort(s
->soc
->env
,
2069 "jz4740_lcdc_write undefined addr " JZ_FMT_plx
" value %x \n",
2075 static CPUReadMemoryFunc
*jz4740_lcdc_readfn
[] = {
2076 jz4740_badwidth_read32
,
2077 jz4740_badwidth_read32
,
2081 static CPUWriteMemoryFunc
*jz4740_lcdc_writefn
[] = {
2082 jz4740_badwidth_write32
,
2083 jz4740_badwidth_write32
,
2087 #include "pixel_ops.h"
2088 #define JZ4740_LCD_PANEL
2090 #include "mips_jz_glue.h"
2092 #include "mips_jz_glue.h"
2094 #include "mips_jz_glue.h"
2096 #include "mips_jz_glue.h"
2098 #include "mips_jz_glue.h"
2099 #undef JZ4740_LCD_PANEL
2101 static void *jz4740_lcd_get_buffer(struct jz4740_lcdc_s
*s
,
2102 target_phys_addr_t addr
)
2106 pd
= cpu_get_physical_page_desc(addr
);
2107 if ((pd
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2109 cpu_abort(cpu_single_env
, "%s: framebuffer outside RAM!\n",
2112 return phys_ram_base
+
2113 (pd
& TARGET_PAGE_MASK
) + (addr
& ~TARGET_PAGE_MASK
);
2116 static void jz4740_lcd_update_display(void *opaque
)
2118 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) opaque
;
2120 uint8_t *src
, *dest
;
2121 struct jz_fb_descriptor
*fb_des
;
2135 fb_des
= (struct jz_fb_descriptor
*) jz4740_lcd_get_buffer(s
, s
->lcdda0
);
2136 s
->lcdda0
= fb_des
->fdadr
;
2137 s
->lcdsa0
= fb_des
->fsadr
;
2138 s
->lcdfid0
= fb_des
->fidr
;
2139 s
->lcdcmd0
= fb_des
->ldcmd
;
2141 src
= (uint8_t *) jz4740_lcd_get_buffer(s
, fb_des
->fsadr
);
2142 if (s
->lcdcmd0
& (0x1 << 28))
2145 memcpy(s
->palette
, src
, sizeof(s
->palette
));
2151 if (s
->width
!= ds_get_width(s
->state
) ||
2152 s
->height
!= ds_get_height(s
->state
))
2154 qemu_console_resize(s
->console
, s
->width
, s
->height
);
2158 step
= (s
->width
* s
->bpp
) >> 3;
2159 dest
= ds_get_data(s
->state
);
2160 linesize
= ds_get_linesize(s
->state
);
2162 //printf("s->width %d s->height %d s->bpp %d linesize %d \n",s->width,s->height ,s->bpp,linesize);
2164 for (y
= 0; y
< s
->height
; y
++)
2166 s
->line_fn(dest
, src
, s
->width
, s
->palette
);
2167 //memcpy(dest,src,step);
2173 dpy_update(s
->state
, 0, 0, s
->width
, s
->height
);
2174 s
->lcdstate
|= 0x20;
2175 if ((s
->lcdcmd0
& 0x40000000) && (!(s
->lcdctrl
& 0x2000)))
2176 qemu_set_irq(s
->irq
, 1);
2179 static inline void jz4740_lcd_invalidate_display(void *opaque
)
2181 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) opaque
;
2185 static struct jz4740_lcdc_s
*jz4740_lcdc_init(struct jz_state_s
*soc
,
2186 qemu_irq irq
, DisplayState
* ds
)
2190 struct jz4740_lcdc_s
*s
= (struct jz4740_lcdc_s
*) qemu_mallocz(sizeof(*s
));
2191 s
->base
= JZ4740_PHYS_BASE(JZ4740_LCD_BASE
);
2197 jz4740_lcdc_reset(s
);
2200 cpu_register_io_memory(0, jz4740_lcdc_readfn
, jz4740_lcdc_writefn
, s
);
2201 cpu_register_physical_memory(s
->base
, 0x10000, iomemtype
);
2203 s
->console
= graphic_console_init(s
->state
, jz4740_lcd_update_display
,
2204 jz4740_lcd_invalidate_display
,
2206 switch (ds_get_bits_per_pixel(s
->state
))
2209 s
->line_fn_tab
= qemu_mallocz(sizeof(jz4740_lcd_fn_t
) * 6);
2212 s
->line_fn_tab
= jz4740_lcd_draw_fn_8
;
2215 s
->line_fn_tab
= jz4740_lcd_draw_fn_15
;
2218 s
->line_fn_tab
= jz4740_lcd_draw_fn_16
;
2221 s
->line_fn_tab
= jz4740_lcd_draw_fn_24
;
2224 s
->line_fn_tab
= jz4740_lcd_draw_fn_32
;
2227 fprintf(stderr
, "%s: Bad color depth\n", __FUNCTION__
);
2235 #define JZ4740_DMA_NUM 6
2240 target_phys_addr_t base
;
2241 struct jz_state_s
*soc
;
2248 uint32_t dsa
[JZ4740_DMA_NUM
];
2249 uint32_t dta
[JZ4740_DMA_NUM
];
2250 uint32_t dtc
[JZ4740_DMA_NUM
];
2251 uint32_t drs
[JZ4740_DMA_NUM
];
2252 uint32_t dcs
[JZ4740_DMA_NUM
];
2253 uint32_t dcm
[JZ4740_DMA_NUM
];
2254 uint32_t dda
[JZ4740_DMA_NUM
];
2258 struct jz4740_desc_s
2260 uint32_t dcmd
; /* DCMD value for the current transfer */
2261 uint32_t dsadr
; /* DSAR value for the current transfer */
2262 uint32_t dtadr
; /* DTAR value for the current transfer */
2263 uint32_t ddadr
; /* Points to the next descriptor + transfer count */
2266 static inline void jz4740_dma_transfer(struct jz4740_dma_s
*s
,
2267 target_phys_addr_t src
,
2268 target_phys_addr_t dest
, uint32_t len
)
2270 uint32_t pd_src
, pd_dest
;
2273 pd_src
= cpu_get_physical_page_desc(src
);
2274 if ((pd_src
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2276 cpu_abort(cpu_single_env
, "%s: DMA source address %x outside RAM!\n",
2279 sr
= phys_ram_base
+
2280 (pd_src
& TARGET_PAGE_MASK
) + (src
& ~TARGET_PAGE_MASK
);
2282 pd_dest
= cpu_get_physical_page_desc(dest
);
2283 if ((pd_dest
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2285 cpu_abort(cpu_single_env
,
2286 "%s: DMA destination address %x outside RAM!\n",
2287 __FUNCTION__
, dest
);
2289 de
= phys_ram_base
+
2290 (pd_dest
& TARGET_PAGE_MASK
) + (dest
& ~TARGET_PAGE_MASK
);
2292 memcpy(de
, sr
, len
);
2295 static inline uint32_t jz4740_dma_unit_size(struct jz4740_dma_s
*s
,
2298 switch ((cmd
& 0x700) >> 8)
2315 /*No-descriptor transfer*/
2316 static inline void jz4740_dma_ndrun(struct jz4740_dma_s
*s
, int channel
)
2320 len
= jz4740_dma_unit_size(s
, s
->dcs
[channel
]) * s
->dtc
[channel
];
2322 jz4740_dma_transfer(s
, s
->dsa
[channel
], s
->dta
[channel
], len
);
2324 /*finish dma transfer */
2325 s
->dtc
[channel
] = 0;
2327 s
->dirqp
|= 1 << channel
;
2329 /*some cleanup work */
2330 /*clean AR TT GLOBAL AR */
2331 s
->dcs
[channel
] &= 0xffffffe7;
2332 s
->dmac
&= 0xfffffffb;
2334 if (s
->dcm
[channel
] & 0x2)
2335 qemu_set_irq(s
->irq
, 1);
2338 /*descriptor transfer */
2339 static inline void jz4740_dma_drun(struct jz4740_dma_s
*s
, int channel
)
2341 struct jz4740_desc_s
*desc
;
2342 target_phys_addr_t desc_phy
;
2345 desc_phy
= s
->dda
[channel
];
2347 cpu_abort(s
->soc
->env
,
2348 "jz4740_dma_drun descriptor address " JZ_FMT_plx
2349 " must be 4 bytes aligned \n", desc_phy
);
2351 pd
= cpu_get_physical_page_desc(desc_phy
);
2352 if ((pd
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2353 cpu_abort(cpu_single_env
,
2354 "%s: DMA descriptor address " JZ_FMT_plx
" outside RAM!\n",
2355 __FUNCTION__
, desc_phy
);
2357 desc
= (struct jz4740_desc_s
*) (phys_ram_base
+
2358 (pd
& TARGET_PAGE_MASK
) +
2359 (desc_phy
& ~TARGET_PAGE_MASK
));
2362 cpu_abort(cpu_single_env
,
2363 "%s: DMA descriptor " JZ_FMT_plx
" is NULL!\n", __FUNCTION__
,
2368 if ((desc
->dcmd
& 0x8) && (!(desc
->dcmd
& 0x10)))
2370 /*Stop DMA and set DCSN.INV=1 */
2371 s
->dcs
[channel
] |= 1 << 6;
2374 jz4740_dma_transfer(s
, desc
->dtadr
, desc
->dsadr
,
2375 (desc
->ddadr
& 0xffffff) *
2376 jz4740_dma_unit_size(s
, desc
->dcmd
));
2378 if ((desc
->dcmd
) & (1 << 3))
2380 desc
->dcmd
&= ~(1 << 4);
2381 if (desc
->dcmd
& 0x1)
2383 s
->dcs
[channel
] |= 0x2;
2386 s
->dcs
[channel
] |= 0x8;
2388 if (desc
->dcmd
& 0x2)
2389 qemu_set_irq(s
->irq
, 1);
2391 if ((desc
->dcmd
) & 0x1)
2393 /*fetch next descriptor */
2394 desc_phy
= s
->dda
[channel
] & 0xfffff000;
2395 desc_phy
+= (desc
->dtadr
& 0xff000000) >> 24;
2396 pd
= cpu_get_physical_page_desc(desc_phy
);
2397 if ((pd
& ~TARGET_PAGE_MASK
) != IO_MEM_RAM
)
2398 cpu_abort(cpu_single_env
,
2399 "%s: DMA descriptor address %x outside RAM!\n",
2400 __FUNCTION__
, desc_phy
);
2402 desc
= (struct jz4740_desc_s
*) (phys_ram_base
+
2403 (pd
& TARGET_PAGE_MASK
)
2406 ~TARGET_PAGE_MASK
));
2408 cpu_abort(cpu_single_env
,
2409 "%s: DMA descriptor %x is NULL!\n",
2410 __FUNCTION__
, (uint32_t) desc
);
2417 static void jz4740_dma_en_channel(struct jz4740_dma_s
*s
, int channel
)
2421 if (s
->dcs
[channel
] & (1 << 31))
2424 jz4740_dma_ndrun(s
, channel
);
2429 static inline void jz4740_dma_en_global(struct jz4740_dma_s
*s
)
2432 for (channel
= 0; channel
< JZ4740_DMA_NUM
; channel
++)
2434 jz4740_dma_en_channel(s
, channel
);
2438 static inline void jz4740_dma_en_dbn(struct jz4740_dma_s
*s
, int channel
)
2440 if ((s
->dmac
& 0x1) && (s
->dcs
[channel
] & (1 << 31)))
2442 jz4740_dma_drun(s
, channel
);
2446 static void jz4740_dma_reset(struct jz4740_dma_s
*s
)
2451 static uint32_t jz4740_dma_read(void *opaque
, target_phys_addr_t addr
)
2453 struct jz4740_dma_s
*s
= (struct jz4740_dma_s
*) opaque
;
2456 debug_out(DEBUG_DMA
, "jz4740_dma_read addr %x \n", addr
);
2471 channel
= (addr
- 0x0) / 0x20;
2472 return s
->dsa
[channel
];
2479 channel
= (addr
- 0x4) / 0x20;
2480 return s
->dta
[channel
];
2487 channel
= (addr
- 0x8) / 0x20;
2488 return s
->dtc
[channel
];
2495 channel
= (addr
- 0xc) / 0x20;
2496 return s
->drs
[channel
];
2503 channel
= (addr
- 0x10) / 0x20;
2504 return s
->dcs
[channel
];
2511 channel
= (addr
- 0x14) / 0x20;
2512 return s
->dcm
[channel
];
2519 channel
= (addr
- 0x18) / 0x20;
2520 return s
->dda
[channel
];
2522 cpu_abort(s
->soc
->env
,
2523 "jz4740_dma_read undefined addr " JZ_FMT_plx
" \n", addr
);
2528 static void jz4740_dma_write(void *opaque
, target_phys_addr_t addr
,
2531 struct jz4740_dma_s
*s
= (struct jz4740_dma_s
*) opaque
;
2534 debug_out(DEBUG_DMA
, "jz4740_dma_write addr %x value %x \n", addr
, value
);
2538 JZ4740_RO_REG(addr
);
2541 s
->dmac
= value
& 0x30d;
2543 jz4740_dma_en_global(s
);
2547 s
->ddr
= value
& 0xff;
2548 for (channel
= 0; channel
< JZ4740_DMA_NUM
; channel
++)
2550 if (s
->ddr
& (1 << channel
))
2552 jz4740_dma_en_dbn(s
, channel
);
2563 channel
= (addr
- 0x0) / 0x20;
2564 s
->dsa
[channel
] = value
;
2572 channel
= (addr
- 0x4) / 0x20;
2573 s
->dta
[channel
] = value
;
2581 channel
= (addr
- 0x8) / 0x20;
2582 s
->dtc
[channel
] = value
;
2590 channel
= (addr
- 0xc) / 0x20;
2591 s
->drs
[channel
] = value
& 0x10;
2592 if (s
->drs
[channel
] != 0x8)
2594 fprintf(stderr
, "Only auto request is supproted \n");
2603 channel
= (addr
- 0x10) / 0x20;
2604 s
->dcs
[channel
] = value
& 0x80ff005f;
2605 if (s
->dcs
[channel
] & 0x1)
2606 jz4740_dma_en_channel(s
, channel
);
2614 channel
= (addr
- 0x14) / 0x20;
2615 s
->dcm
[channel
] = value
& 0xcff79f;
2623 channel
= (addr
- 0x18) / 0x20;
2624 s
->dda
[channel
] = 0xfffffff0;
2627 cpu_abort(s
->soc
->env
,
2628 "jz4740_dma_read undefined addr " JZ_FMT_plx
" \n", addr
);
2633 static CPUReadMemoryFunc
*jz4740_dma_readfn
[] = {
2634 jz4740_badwidth_read32
,
2635 jz4740_badwidth_read32
,
2639 static CPUWriteMemoryFunc
*jz4740_dma_writefn
[] = {
2640 jz4740_badwidth_write32
,
2641 jz4740_badwidth_write32
,
2646 static struct jz4740_dma_s
*jz4740_dma_init(struct jz_state_s
*soc
,
2650 struct jz4740_dma_s
*s
= (struct jz4740_dma_s
*) qemu_mallocz(sizeof(*s
));
2651 s
->base
= JZ4740_PHYS_BASE(JZ4740_DMAC_BASE
);
2655 jz4740_dma_reset(s
);
2658 cpu_register_io_memory(0, jz4740_dma_readfn
, jz4740_dma_writefn
, s
);
2659 cpu_register_physical_memory(s
->base
, 0x00010000, iomemtype
);
2666 struct jz4740_sadc_s
2670 target_phys_addr_t base
;
2671 struct jz_state_s
*soc
;
2698 static void jz4740_touchscreen_interrupt(struct jz4740_sadc_s
*s
)
2703 if ((s
->adctrl
)&(s
->adstate
))
2705 debug_out(DEBUG_SADC
,"irq s->adctrl %x s->adstate %x \n",s
->adctrl
,s
->adstate
);
2706 qemu_set_irq(s
->irq
,1);
2711 static void jz4740_touchscreen_event(void *opaque
,
2712 int x
, int y
, int z
, int buttons_state
)
2714 struct jz4740_sadc_s
*s
= opaque
;
2719 s
->x
= (x
*4096)/0x7FFF;
2720 s
->y
= (y
*4096)/0x7FFF;
2722 if ((s
->pen_state
== PEN_UP
)&&(buttons_state
==PEN_DOWN
))
2725 jz4740_touchscreen_interrupt(s
);
2727 else if ((s
->pen_state
== PEN_DOWN
)&&(buttons_state
==PEN_UP
))
2730 jz4740_touchscreen_interrupt(s
);
2732 s
->pen_state
= buttons_state
;
2736 static uint32_t jz4740_sadc_read8(void *opaque
, target_phys_addr_t addr
)
2738 struct jz4740_sadc_s
*s
= (struct jz4740_sadc_s
*) opaque
;
2749 cpu_abort(s
->soc
->env
,
2750 "jz4740_sadc_read8 undefined addr " JZ_FMT_plx
" \n", addr
);
2755 static uint32_t jz4740_sdac_read16(void *opaque
, target_phys_addr_t addr
)
2757 struct jz4740_sadc_s
*s
= (struct jz4740_sadc_s
*) opaque
;
2770 cpu_abort(s
->soc
->env
,
2771 "jz4740_sdac_read16 undefined addr " JZ_FMT_plx
" \n", addr
);
2776 static uint32_t jz4740_sdac_read32(void *opaque
, target_phys_addr_t addr
)
2778 struct jz4740_sadc_s
*s
= (struct jz4740_sadc_s
*) opaque
;
2784 /*TODO: Other type format*/
2785 if (s
->read_index
==0)
2788 return (((s
->x
) & 0x7fff) | ((s
->y
& 0x7ffff) << 16));
2796 cpu_abort(s
->soc
->env
,
2797 "jz4740_sdac_read32 undefined addr " JZ_FMT_plx
" \n", addr
);
2802 static void jz4740_sadc_write8(void *opaque
, target_phys_addr_t addr
,
2805 struct jz4740_sadc_s
*s
= (struct jz4740_sadc_s
*) opaque
;
2807 debug_out(DEBUG_SADC
, "jz4740_sadc_write8 addr %x value %x\n", addr
, value
);
2812 s
->adena
= value
& 0x7;
2813 s
->tchen
= value
& 0x4;
2816 s
->adctrl
= value
& 0x1f;
2819 s
->adstate
&= ~(value
& 0x1f);
2822 cpu_abort(s
->soc
->env
,
2823 "jz4740_sadc_write8 undefined addr " JZ_FMT_plx
" value %x \n", addr
,value
);
2827 static void jz4740_sadc_write16(void *opaque
, target_phys_addr_t addr
,
2830 struct jz4740_sadc_s
*s
= (struct jz4740_sadc_s
*) opaque
;
2832 debug_out(DEBUG_SADC
, "jz4740_sadc_write16 addr %x value %x\n", addr
, value
);
2837 s
->adsame
= value
& 0xffff;
2840 s
->adsdat
= value
& 0xffff;
2847 cpu_abort(s
->soc
->env
,
2848 "jz4740_sadc_write16 undefined addr " JZ_FMT_plx
" value %x \n", addr
,value
);
2852 static void jz4740_sadc_write32(void *opaque
, target_phys_addr_t addr
,
2855 struct jz4740_sadc_s
*s
= (struct jz4740_sadc_s
*) opaque
;
2858 debug_out(DEBUG_SADC
, "jz4740_sadc_write32 addr %x value %x\n", addr
, value
);
2863 s
->adcfg
= value
& 0xc007ffff;
2864 s
->ex_in
= (value
& 0x40000000)>>30;
2865 s
->xyz
= (value
& 0x6fff)>>13;
2866 s
->snum
= ((value
& 0x1cff)>>10)+1;
2869 s
->adtch
= value
& 0x8fff8fff;
2872 cpu_abort(s
->soc
->env
,
2873 "jz4740_sadc_write32 undefined addr " JZ_FMT_plx
" value %x \n", addr
,value
);
2877 static void jz4740_sadc_reset(struct jz4740_sadc_s
*s
)
2879 s
->adcfg
= 0x0002002c;
2886 static CPUReadMemoryFunc
*jz4740_sadc_readfn
[] = {
2892 static CPUWriteMemoryFunc
*jz4740_sadc_writefn
[] = {
2894 jz4740_sadc_write16
,
2895 jz4740_sadc_write32
,
2898 static struct jz4740_sadc_s
*jz4740_sadc_init(struct jz_state_s
*soc
,
2902 struct jz4740_sadc_s
*s
;
2904 s
= (struct jz4740_sadc_s
*)
2905 qemu_mallocz(sizeof(struct jz4740_sadc_s
));
2906 s
->base
= JZ4740_PHYS_BASE(JZ4740_SADC_BASE
);
2910 qemu_add_mouse_event_handler(jz4740_touchscreen_event
, s
, 1,
2911 "QEMU JZ4740 Touchscreen");
2913 jz4740_sadc_reset(s
);
2916 cpu_register_io_memory(0, jz4740_sadc_readfn
, jz4740_sadc_writefn
, s
);
2917 cpu_register_physical_memory(s
->base
, 0x00001000, iomemtype
);
2921 static void jz4740_cpu_reset(void *opaque
)
2923 fprintf(stderr
, "%s: UNIMPLEMENTED!", __FUNCTION__
);
2926 struct jz_state_s
*jz4740_init(unsigned long sdram_size
,
2927 uint32_t osc_extal_freq
, DisplayState
* ds
)
2929 struct jz_state_s
*s
= (struct jz_state_s
*)
2930 qemu_mallocz(sizeof(struct jz_state_s
));
2931 ram_addr_t sram_base
, sdram_base
;
2934 s
->mpu_model
= jz4740
;
2935 s
->env
= cpu_init("jz4740");
2939 fprintf(stderr
, "Unable to find CPU definition\n");
2944 qemu_register_reset(jz4740_cpu_reset
, s
->env
);
2946 s
->sdram_size
= sdram_size
;
2947 s
->sram_size
= JZ4740_SRAM_SIZE
;
2950 jz_clk_init(s
, osc_extal_freq
);
2952 /*map sram to 0x80000000 and sdram to 0x80004000 */
2953 sram_base
= qemu_ram_alloc(s
->sram_size
);
2954 cpu_register_physical_memory(0x0, s
->sram_size
, (sram_base
| IO_MEM_RAM
));
2955 sdram_base
= qemu_ram_alloc(s
->sdram_size
);
2956 cpu_register_physical_memory(JZ4740_SRAM_SIZE
, s
->sdram_size
,
2957 (sdram_base
| IO_MEM_RAM
));
2959 /* Init internal devices */
2960 cpu_mips_irq_init_cpu(s
->env
);
2961 cpu_mips_clock_init(s
->env
);
2965 jz_clk_init(s
, osc_extal_freq
);
2967 intc
= jz4740_intc_init(s
, s
->env
->irq
[2]);
2968 s
->cpm
= jz4740_cpm_init(s
);
2969 s
->emc
= jz4740_emc_init(s
, intc
[2]);
2970 s
->gpio
= jz4740_gpio_init(s
, intc
[25]);
2971 s
->rtc
= jz4740_rtc_init(s
, intc
[15]);
2972 s
->tcu
= jz4740_tcu_if_init(s
, intc
[23], intc
[22], intc
[21]);
2973 jz4740_tcu_init(s
, s
->tcu
, 0);
2974 s
->lcdc
= jz4740_lcdc_init(s
, intc
[30], ds
);
2975 s
->dma
= jz4740_dma_init(s
, intc
[20]);
2976 s
->sadc
= jz4740_sadc_init(s
,intc
[12]);
2979 serial_mm_init(0x10030000, 2, intc
[9], 57600, serial_hds
[0], 1);