913a06df12cfa40c53f50373d2e72fe3db9bfa28
[qemu/qemu-JZ.git] / hw / mips_jz.c
blob913a06df12cfa40c53f50373d2e72fe3db9bfa28
1 /*
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
22 * THE SOFTWARE.
27 * The emulation target is pavo demo board.
28 * http://www.ingenic.cn/eng/productServ/kfyd/Hardware/pffaqQuestionContent.aspx?Category=2&Question=3
32 #include "hw.h"
33 #include "mips.h"
34 #include "sysemu.h"
35 #include "qemu-timer.h"
36 #include "qemu-char.h"
37 #include "flash.h"
38 #include "soc_dma.h"
39 #include "audio/audio.h"
40 #include "pc.h"
41 #include "osdep.h"
42 #include "mips_jz.h"
43 #include "console.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 0 //(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)
61 #ifdef DEBUG
62 FILE *fp;
63 static void debug_init(void)
65 fp = fopen("jz4740.txt", "w+");
66 if (fp == NULL)
68 fprintf(stderr, "can not open jz4740.txt \n");
69 exit(-1);
72 static void debug_out(uint32_t flag, const char *format, ...)
74 va_list ap;
75 if (fp)
77 if (flag & DEBUG_FLAG)
79 va_start(ap, format);
80 vfprintf(fp, format, ap);
81 fflush(fp);
82 va_end(ap);
86 #else
87 static void debug_init(void)
90 static void debug_out(uint32_t flag, const char *format, ...)
93 #endif
95 uint32_t jz4740_badwidth_read8(void *opaque, target_phys_addr_t addr)
97 uint8_t ret;
99 JZ4740_8B_REG(addr);
100 cpu_physical_memory_read(addr, (void *) &ret, 1);
101 return ret;
104 void jz4740_badwidth_write8(void *opaque, target_phys_addr_t addr,
105 uint32_t value)
107 uint8_t val8 = value;
109 JZ4740_8B_REG(addr);
110 cpu_physical_memory_write(addr, (void *) &val8, 1);
113 uint32_t jz4740_badwidth_read16(void *opaque, target_phys_addr_t addr)
115 uint16_t ret;
116 JZ4740_16B_REG(addr);
117 cpu_physical_memory_read(addr, (void *) &ret, 2);
118 return ret;
121 void jz4740_badwidth_write16(void *opaque, target_phys_addr_t addr,
122 uint32_t value)
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)
132 uint32_t ret;
134 JZ4740_32B_REG(addr);
135 cpu_physical_memory_read(addr, (void *) &ret, 4);
136 return ret;
139 void jz4740_badwidth_write32(void *opaque, target_phys_addr_t addr,
140 uint32_t value)
142 JZ4740_32B_REG(addr);
143 cpu_physical_memory_write(addr, (void *) &value, 4);
147 /*clock reset and power control*/
148 struct jz4740_cpm_s
150 target_phys_addr_t base;
151 struct jz_state_s *soc;
153 uint32_t cpccr;
154 uint32_t cppcr;
155 uint32_t i2scdr;
156 uint32_t lpcdr;
157 uint32_t msccdr;
158 uint32_t uhccdr;
159 uint32_t uhctst;
160 uint32_t ssicdr;
162 uint32_t lcr;
163 uint32_t clkgr;
164 uint32_t scr;
167 static void jz4740_dump_clocks(jz_clk parent)
169 jz_clk i = 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,
177 uint32_t new_value)
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))
185 return;
187 if (new_value & CPM_CPCCR_PCS)
188 jz_clk_setrate(jz_findclk(s->soc, "pll_divider"), 1, 1);
189 else
190 jz_clk_setrate(jz_findclk(s->soc, "pll_divider"), 2, 1);
193 ldiv = (new_value & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT;
194 ldiv++;
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"));
212 else
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"));
219 else
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,
232 uint32_t new_value)
234 uint32_t pllm, plln, pllod, pllbp, pllen;
235 uint32_t pll0[4] = {
236 1, 2, 2, 4
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;
247 return;
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],
255 pllm + 2);
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,
265 uint32_t new_value)
267 uint32_t i2scdr;
269 i2scdr = new_value & CPM_I2SCDR_I2SDIV_MASK;
270 if (unlikely(i2scdr == s->i2scdr))
271 return;
274 jz_clk_setrate(jz_findclk(s->soc, "i2sclk"), i2scdr + 1, 1);
276 s->i2scdr = i2scdr;
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,
284 uint32_t new_value)
286 uint32_t ipcdr;
288 ipcdr = new_value & CPM_LPCDR_PIXDIV_MASK;
289 /*TODO: */
290 s->lpcdr = ipcdr;
293 static inline void jz4740_msccdr_update(struct jz4740_cpm_s *s,
294 uint32_t new_value)
296 uint32_t msccdr;
298 msccdr = new_value & CPM_MSCCDR_MSCDIV_MASK;
300 if (unlikely(msccdr == s->msccdr))
301 return;
304 jz_clk_setrate(jz_findclk(s->soc, "mscclk"), msccdr + 1, 1);
306 s->msccdr = msccdr;
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,
314 uint32_t new_value)
316 uint32_t uhccdr;
318 uhccdr = new_value & 0xf;
319 /*TODO: */
320 s->uhccdr = uhccdr;
323 static void jz4740_cpm_write(void *opaque, target_phys_addr_t addr,
324 uint32_t value)
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);
330 switch (addr)
332 case 0x0:
333 jz4740_cpccr_update(s, value);
334 break;
335 case 0x4:
336 s->lcr = value & 0xff;
337 break;
338 case 0x20:
339 s->clkgr = value & 0xffff;
340 break;
341 case 0x24:
342 s->scr = value & 0xffff;
343 break;
344 case 0x10:
345 jz4740_cppcr_update(s, value);
346 break;
347 case 0x60:
348 jz4740_i2scdr_update(s, value);
349 break;
350 case 0x64:
351 jz4740_lpcdr_update(s, value);
352 break;
353 case 0x68:
354 jz4740_msccdr_update(s, value);
355 break;
356 case 0x6c:
357 jz4740_uhccdr_update(s, value);
358 break;
359 case 0x70:
360 s->uhctst = value & 0x3f;
361 break;
362 case 0x74:
363 s->ssicdr = value & 0xf;
364 break;
365 default:
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;
378 switch (addr)
380 case 0x0:
381 return s->cpccr;
382 case 0x4:
383 return s->lcr;
384 case 0x20:
385 return s->clkgr;
386 case 0x24:
387 return s->scr;
388 case 0x10:
389 return s->cppcr;
390 case 0x60:
391 return s->i2scdr;
392 case 0x64:
393 return s->lpcdr;
394 case 0x68:
395 return s->msccdr;
396 case 0x6c:
397 return s->uhccdr;
398 case 0x70:
399 return s->uhctst;
400 case 0x74:
401 return s->ssicdr;
402 default:
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,
414 jz474_cpm_read,
417 static CPUWriteMemoryFunc *jz4740_cpm_writefn[] = {
418 jz4740_badwidth_write32,
419 jz4740_badwidth_write32,
420 jz4740_cpm_write,
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;
431 s->uhctst = 0x0;
432 s->ssicdr = 0x00000004;
434 s->lcr = 0xf8;
435 s->clkgr = 0x0;
436 s->scr = 0x1500;
439 static struct jz4740_cpm_s *jz4740_cpm_init(struct jz_state_s *soc)
441 int iomemtype;
442 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) qemu_mallocz(sizeof(*s));
443 s->base = JZ4740_PHYS_BASE(JZ4740_CPM_BASE);
444 s->soc = soc;
446 jz4740_cpm_reset(s);
448 iomemtype =
449 cpu_register_io_memory(0, jz4740_cpm_readfn, jz4740_cpm_writefn, s);
450 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
451 return s;
455 /* JZ4740 interrupt controller
456 * It issues INT2 to MIPS
458 struct jz4740_intc_s
460 qemu_irq parent_irq;
462 target_phys_addr_t base;
463 struct jz_state_s *soc;
465 uint32_t icsr;
466 uint32_t icmr;
467 uint32_t icmsr;
468 uint32_t icmcr;
469 uint32_t icpr;
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;
476 switch (addr)
478 case 0x8:
479 case 0xc:
480 JZ4740_WO_REG(addr);
481 break;
482 case 0x0:
483 return s->icsr;
484 case 0x4:
485 return s->icmr;
486 case 0x10:
487 return s->icpr;
488 default:
489 cpu_abort(s->soc->env,
490 "jz4740_intc_read undefined addr " JZ_FMT_plx " \n", addr);
493 return (0);
496 static void jz4740_intc_write(void *opaque, target_phys_addr_t addr,
497 uint32_t value)
499 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
501 switch (addr)
503 case 0x0:
504 JZ4740_RO_REG(addr);
505 break;
506 case 0x4:
507 s->icmr = value;
508 break;
509 case 0x8:
510 s->icmr |= value;
511 break;
512 case 0xc:
513 s->icmr &= ~value;
514 break;
515 case 0x10:
516 s->icpr &= ~value;
517 qemu_set_irq(s->parent_irq, 0);
518 break;
519 default:
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,
530 jz4740_intc_read,
533 static CPUWriteMemoryFunc *jz4740_intc_writefn[] = {
534 jz4740_badwidth_write32,
535 jz4740_badwidth_write32,
536 jz4740_intc_write,
539 static void jz4740_intc_reset(struct jz4740_intc_s *s)
541 s->icsr = 0x0;
542 s->icmr = 0xffffffff;
543 s->icpr = 0x0;
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;
552 if (level)
554 s->icsr |= irq_mask;
555 s->icpr &= ~irq_mask;
556 if (!(s->icmr & irq_mask))
558 s->icpr |= 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)
567 int iomemtype;
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;
571 s->soc = soc;
573 jz4740_intc_reset(s);
575 iomemtype =
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*/
582 struct jz4740_emc_s
584 qemu_irq irq;
585 target_phys_addr_t base;
586 struct jz_state_s *soc;
588 uint32_t bcr;
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;
627 s->sacr1 = 0x18fc;
628 s->sacr2 = 0x16fe;
629 s->sacr3 = 0x14fe;
630 s->sacr4 = 0xcfc;
632 s->nfcsr = 0x0;
633 s->nfeccr = 0x0;
634 s->nfecc = 0x0;
635 s->nfpar0 = 0x0;
636 s->nfpar1 = 0x0;
637 s->nfpar2 = 0x0;
638 s->nfints = 0x0;
639 s->nfinte = 0x0;
640 s->nferr0 = 0x0;
641 s->nferr1 = 0x0;
642 s->nferr2 = 0x0;
643 s->nferr3 = 0x0;
645 s->dmcr = 0x0;
646 s->rtcsr = 0x0;
647 s->rtcnt = 0x0;
648 s->rtcor = 0x0;
649 s->dmar = 0x20f8;
650 s->sdmr = 0x0;
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;
658 switch (addr)
660 case 0x108:
661 case 0x109:
662 case 0x10a:
663 case 0x10b:
664 return (s->nfpar0 >> ((addr - 0x108) * 8)) & 0xff;
665 case 0x10c:
666 case 0x10d:
667 case 0x10e:
668 case 0x10f:
669 return (s->nfpar1 >> ((addr - 0x10c) * 8)) & 0xff;
670 case 0x110:
671 case 0x111:
672 case 0x112:
673 case 0x113:
674 return (s->nfpar2 >> ((addr - 0x110) * 8)) & 0xff;
675 case 0xa000:
676 case 0xa001:
677 case 0xa002:
678 case 0xa003:
679 return (s->sdmr >> ((addr - 0xa000) * 8)) & 0xff;
680 default:
681 cpu_abort(s->soc->env,
682 "jz4740_emc_read8 undefined addr " JZ_FMT_plx " \n", addr);
686 return (0);
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;
693 switch (addr)
695 case 0x108:
696 case 0x10a:
697 return (s->nfpar0 >> ((addr - 0x108) * 8)) & 0xffff;
698 case 0x10c:
699 case 0x10e:
700 return (s->nfpar1 >> ((addr - 0x10c) * 8)) & 0xffff;
701 case 0x110:
702 case 0x112:
703 return (s->nfpar2 >> ((addr - 0x110) * 8)) & 0xffff;
704 case 0x11c:
705 case 0x11e:
706 return (s->nferr0 >> ((addr - 0x11c) * 8)) & 0xffff;
707 case 0x120:
708 case 0x122:
709 return (s->nferr1 >> ((addr - 0x120) * 8)) & 0xffff;
710 case 0x124:
711 case 0x126:
712 return (s->nferr2 >> ((addr - 0x124) * 8)) & 0xffff;
713 case 0x128:
714 case 0x12a:
715 return (s->nferr3 >> ((addr - 0x128) * 8)) & 0xffff;
716 default:
717 cpu_abort(s->soc->env,
718 "jz4740_emc_read16 undefined addr " JZ_FMT_plx " \n", addr);
720 return (0);
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;
727 switch (addr)
729 case 0x0:
730 return s->bcr;
731 case 0x14:
732 return s->smcr1;
733 case 0x18:
734 return s->smcr2;
735 case 0x1c:
736 return s->smcr3;
737 case 0x20:
738 return s->smcr4;
739 case 0x34:
740 return s->sacr1;
741 case 0x38:
742 return s->sacr2;
743 case 0x3c:
744 return s->sacr3;
745 case 0x40:
746 return s->sacr4;
747 case 0x50:
748 return s->nfcsr;
749 case 0x100:
750 return s->nfeccr;
751 case 0x104:
752 return s->nfecc;
753 case 0x108:
754 return s->nfpar0;
755 case 0x10c:
756 return s->nfpar1;
757 case 0x110:
758 return s->nfpar2;
759 case 0x114:
760 return s->nfints;
761 case 0x118:
762 return s->nfinte;
763 case 0x11c:
764 return s->nferr0;
765 case 0x120:
766 return s->nferr1;
767 case 0x124:
768 return s->nferr2;
769 case 0x128:
770 return s->nferr3;
771 case 0x80:
772 return s->dmcr;
773 case 0x90:
774 return s->dmar;
775 default:
776 cpu_abort(s->soc->env,
777 "jz4740_emc_read32 undefined addr " JZ_FMT_plx " \n", addr);
779 return (0);
782 static void jz4740_emc_write8(void *opaque, target_phys_addr_t addr,
783 uint32_t value)
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);
789 switch (addr)
791 case 0x108:
792 case 0x109:
793 case 0x10a:
794 case 0x10b:
795 s->nfpar0 |= (value & 0xff) << ((addr - 0x108) * 8);
796 break;
797 case 0x10c:
798 case 0x10d:
799 case 0x10e:
800 case 0x10f:
801 s->nfpar1 |= (value & 0xff) << ((addr - 0x10c) * 8);
802 break;
803 case 0x110:
804 case 0x111:
805 case 0x112:
806 case 0x113:
807 s->nfpar2 |= (value & 0xff) << ((addr - 0x110) * 8);
808 break;
809 case 0xa000 ... 0xa3ff:
810 break;
811 default:
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,
818 uint32_t value)
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);
823 switch (addr)
825 case 0x108:
826 case 0x10a:
827 s->nfpar0 |= (value & 0xffff) << ((addr - 0x108) * 8);
828 break;
829 case 0x10c:
830 case 0x10e:
831 s->nfpar1 |= (value & 0xffff) << ((addr - 0x10c) * 8);
832 break;
833 case 0x110:
834 case 0x112:
835 s->nfpar2 |= (value & 0xffff) << ((addr - 0x110) * 8);
836 break;
837 case 0x84:
838 case 0x86:
839 s->rtcsr |= (value & 0xffff) << ((addr - 0x84) * 8);
840 break;
841 case 0x88:
842 case 0x8a:
843 s->rtcnt |= (value & 0xffff) << ((addr - 0x88) * 8);
844 break;
845 case 0x8c:
846 s->rtcor |= (value & 0xffff) << ((addr - 0x8c) * 8);
847 break;
848 default:
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,
861 uint32_t value)
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);
866 switch (addr)
868 case 0x104:
869 case 0x11c:
870 case 0x120:
871 case 0x124:
872 case 0x128:
873 JZ4740_RO_REG(addr);
874 break;
875 case 0x0:
876 s->bcr = value;
877 break;
878 case 0x14:
879 s->smcr1 = value & 0xfff77cf;
880 break;
881 case 0x18:
882 s->smcr2 = value & 0xfff77cf;
883 break;
884 case 0x1c:
885 s->smcr3 = value & 0xfff77cf;
886 break;
887 case 0x20:
888 s->smcr4 = value & 0xfff77cf;
889 break;
890 case 0x34:
891 s->sacr1 = value & 0xffff;
892 break;
893 case 0x38:
894 s->sacr2 = value & 0xffff;
895 break;
896 case 0x3c:
897 s->sacr3 = value & 0xffff;
898 break;
899 case 0x40:
900 s->sacr4 = value & 0xffff;
901 break;
902 case 0x50:
903 s->nfcsr = value & 0xffff;
904 break;
905 case 0x100:
906 s->nfeccr = value & 0x1f;
907 if (s->nfeccr & 0x2)
909 s->nfecc = 0x0;
910 s->nfpar0 = 0x0;
911 s->nfpar1 = 0x0;
912 s->nfpar2 = 0x0;
913 s->nfints = 0x0;
914 s->nfinte = 0x0;
915 s->nferr0 = 0x0;
916 s->nferr1 = 0x0;
917 s->nferr2 = 0x0;
918 s->nferr3 = 0x0;
920 /*RS*/
921 /*TODO: Real RS error correction */
922 if (s->nfeccr & 0x4)
924 if ((s->nfeccr & 0x10) && (!(s->nfeccr & 0x8)))
926 /*decode */
927 s->nfints = 0x8;
928 s->nferr0 = 0x0;
929 s->nferr1 = 0x0;
930 s->nferr2 = 0x0;
932 if (s->nfeccr & 0x8)
934 /*encoding */
935 s->nfints = 0x4;
936 s->nfpar0 = 0xffffffff; /*fake value. for debug */
937 s->nfpar1 = 0xffffffff; /*fake value */
938 s->nfpar2 = 0xff; /*fake value */
941 else
943 s->nfecc = 0xffffff;
945 jz4740_emc_upate_interrupt(s);
946 break;
947 case 0x108:
948 s->nfpar0 = value;
949 break;
950 case 0x10c:
951 s->nfpar1 = value;
952 break;
953 case 0x110:
954 s->nfpar2 = value & 0xff;
955 break;
956 case 0x114:
957 s->nfints = value & 0x1fffffff;
958 jz4740_emc_upate_interrupt(s);
959 break;
960 case 0x118:
961 s->nfinte = value & 0x1f;
962 jz4740_emc_upate_interrupt(s);
963 break;
964 case 0x080:
965 s->dmcr = value & 0x9fbeff7f;
966 break;
967 case 0x90:
968 s->dmar = value & 0xffff;
969 break;
970 default:
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[] = {
980 jz4740_emc_read8,
981 jz4740_emc_read16,
982 jz4740_emc_read32,
985 static CPUWriteMemoryFunc *jz4740_emc_writefn[] = {
986 jz4740_emc_write8,
987 jz4740_emc_write16,
988 jz4740_emc_write32,
992 static struct jz4740_emc_s *jz4740_emc_init(struct jz_state_s *soc,
993 qemu_irq irq)
995 int iomemtype;
996 struct jz4740_emc_s *s = (struct jz4740_emc_s *) qemu_mallocz(sizeof(*s));
997 s->base = JZ4740_PHYS_BASE(JZ4740_EMC_BASE);
998 s->soc = soc;
999 s->irq = irq;
1001 jz4740_emc_reset(s);
1003 iomemtype =
1004 cpu_register_io_memory(0, jz4740_emc_readfn, jz4740_emc_writefn, s);
1005 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
1006 return s;
1010 struct jz4740_gpio_s
1012 qemu_irq irq;
1013 target_phys_addr_t base;
1014 struct jz_state_s *soc;
1016 uint32_t papin[4];
1017 uint32_t padat[4];
1018 uint32_t paim[4];
1019 uint32_t pape[4];
1020 uint32_t pafun[4];
1021 uint32_t pasel[4];
1022 uint32_t padir[4];
1023 uint32_t patrg[4];
1024 uint32_t paflg[4];
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;
1043 uint32_t group;
1044 debug_out(DEBUG_GPIO, "jz4740_gpio_read addr %x\n", addr);
1046 switch (addr)
1048 case 0x14:
1049 case 0x114:
1050 case 0x214:
1051 case 0x314:
1052 case 0x18:
1053 case 0x118:
1054 case 0x218:
1055 case 0x318:
1056 case 0x24:
1057 case 0x124:
1058 case 0x224:
1059 case 0x324:
1060 case 0x28:
1061 case 0x128:
1062 case 0x228:
1063 case 0x328:
1064 case 0x34:
1065 case 0x134:
1066 case 0x234:
1067 case 0x334:
1068 case 0x38:
1069 case 0x138:
1070 case 0x238:
1071 case 0x338:
1072 case 0x44:
1073 case 0x144:
1074 case 0x244:
1075 case 0x344:
1076 case 0x48:
1077 case 0x148:
1078 case 0x248:
1079 case 0x348:
1080 case 0x54:
1081 case 0x154:
1082 case 0x254:
1083 case 0x354:
1084 case 0x58:
1085 case 0x158:
1086 case 0x258:
1087 case 0x358:
1088 case 0x64:
1089 case 0x164:
1090 case 0x264:
1091 case 0x364:
1092 case 0x68:
1093 case 0x168:
1094 case 0x268:
1095 case 0x368:
1096 case 0x74:
1097 case 0x174:
1098 case 0x274:
1099 case 0x374:
1100 case 0x78:
1101 case 0x178:
1102 case 0x278:
1103 case 0x378:
1104 case 0x84:
1105 case 0x184:
1106 case 0x284:
1107 case 0x384:
1108 JZ4740_WO_REG(addr);
1109 break;
1111 case 0x0:
1112 case 0x100:
1113 case 0x200:
1114 case 0x300:
1115 group = (addr - 0x0) / 0x100;
1116 if (addr == 0x200)
1118 /*GPIO(C) PIN 30 -> NAND FLASH R/B. */
1119 /*FOR NAND FLASH.PIN 30 ----|_____|------ */
1120 s->papin[2] &= 0x40000000;
1121 if (s->papin[2])
1122 s->papin[2] &= ~0x40000000;
1123 else
1124 s->papin[2] |= 0x40000000;
1126 return s->papin[group];
1127 case 0x10:
1128 case 0x110:
1129 case 0x210:
1130 case 0x310:
1131 group = (addr - 0x10) / 0x100;
1132 return s->padat[group];
1133 case 0x20:
1134 case 0x120:
1135 case 0x220:
1136 case 0x320:
1137 group = (addr - 0x20) / 0x100;
1138 return s->paim[group];
1139 case 0x30:
1140 case 0x130:
1141 case 0x230:
1142 case 0x330:
1143 group = (addr - 0x30) / 0x100;
1144 return s->pape[group];
1145 case 0x40:
1146 case 0x140:
1147 case 0x240:
1148 case 0x340:
1149 group = (addr - 0x40) / 0x100;
1150 return s->pafun[group];
1151 case 0x50:
1152 case 0x150:
1153 case 0x250:
1154 case 0x350:
1155 group = (addr - 0x50) / 0x100;
1156 return s->pasel[group];
1157 case 0x60:
1158 case 0x160:
1159 case 0x260:
1160 case 0x360:
1161 group = (addr - 0x60) / 0x100;
1162 return s->padir[group];
1163 case 0x70:
1164 case 0x170:
1165 case 0x270:
1166 case 0x370:
1167 group = (addr - 0x70) / 0x100;
1168 return s->patrg[group];
1169 case 0x80:
1170 case 0x180:
1171 case 0x280:
1172 case 0x380:
1173 group = (addr - 0x80) / 0x100;
1174 return s->paflg[group];
1175 default:
1176 cpu_abort(s->soc->env,
1177 "jz4740_gpio_read undefined addr " JZ_FMT_plx " \n", addr);
1179 return (0);
1182 static void jz4740_gpio_write(void *opaque, target_phys_addr_t addr,
1183 uint32_t value)
1185 struct jz4740_gpio_s *s = (struct jz4740_gpio_s *) opaque;
1186 uint32_t group;
1188 debug_out(DEBUG_GPIO, "jz4740_gpio_write addr %x value %x\n", addr, value);
1190 switch (addr)
1192 case 0x0:
1193 case 0x100:
1194 case 0x200:
1195 case 0x300:
1196 case 0x10:
1197 case 0x110:
1198 case 0x210:
1199 case 0x310:
1200 case 0x20:
1201 case 0x120:
1202 case 0x220:
1203 case 0x320:
1204 case 0x30:
1205 case 0x130:
1206 case 0x230:
1207 case 0x330:
1208 case 0x40:
1209 case 0x140:
1210 case 0x240:
1211 case 0x340:
1212 case 0x50:
1213 case 0x150:
1214 case 0x250:
1215 case 0x350:
1216 case 0x60:
1217 case 0x160:
1218 case 0x260:
1219 case 0x360:
1220 case 0x70:
1221 case 0x170:
1222 case 0x270:
1223 case 0x370:
1224 case 0x80:
1225 case 0x180:
1226 case 0x280:
1227 case 0x380:
1228 JZ4740_RO_REG(addr);
1229 break;
1230 case 0x14:
1231 case 0x114:
1232 case 0x214:
1233 case 0x314:
1234 group = (addr - 0x14) / 0x100;
1235 s->padat[group] = value;
1236 break;
1237 case 0x18:
1238 case 0x118:
1239 case 0x218:
1240 case 0x318:
1241 group = (addr - 0x18) / 0x100;
1242 s->padat[group] &= ~value;
1243 break;
1244 case 0x24:
1245 case 0x124:
1246 case 0x224:
1247 case 0x324:
1248 group = (addr - 0x24) / 0x100;
1249 s->paim[group] = value;
1250 break;
1251 case 0x28:
1252 case 0x128:
1253 case 0x228:
1254 case 0x328:
1255 group = (addr - 0x28) / 0x100;
1256 s->paim[group] &= ~value;
1257 break;
1258 case 0x34:
1259 case 0x134:
1260 case 0x234:
1261 case 0x334:
1262 group = (addr - 0x34) / 0x100;
1263 s->pape[group] = value;
1264 break;
1265 case 0x38:
1266 case 0x138:
1267 case 0x238:
1268 case 0x338:
1269 group = (addr - 0x38) / 0x100;
1270 s->pape[group] &= ~value;
1271 break;
1272 case 0x44:
1273 case 0x144:
1274 case 0x244:
1275 case 0x344:
1276 group = (addr - 0x44) / 0x100;
1277 s->pafun[group] = value;
1278 break;
1279 case 0x48:
1280 case 0x148:
1281 case 0x248:
1282 case 0x348:
1283 group = (addr - 0x48) / 0x100;
1284 s->pafun[group] &= ~value;
1285 break;
1286 case 0x54:
1287 case 0x154:
1288 case 0x254:
1289 case 0x354:
1290 group = (addr - 0x54) / 0x100;
1291 s->pasel[group] = value;
1292 break;
1293 case 0x58:
1294 case 0x158:
1295 case 0x258:
1296 case 0x358:
1297 group = (addr - 0x58) / 0x100;
1298 s->pasel[group] &= ~value;
1299 break;
1300 case 0x64:
1301 case 0x164:
1302 case 0x264:
1303 case 0x364:
1304 group = (addr - 0x64) / 0x100;
1305 s->padir[group] = value;
1306 break;
1307 case 0x68:
1308 case 0x168:
1309 case 0x268:
1310 case 0x368:
1311 group = (addr - 0x68) / 0x100;
1312 s->padir[group] &= ~value;
1313 break;
1314 case 0x74:
1315 case 0x174:
1316 case 0x274:
1317 case 0x374:
1318 group = (addr - 0x74) / 0x100;
1319 s->patrg[group] = value;
1320 break;
1321 case 0x78:
1322 case 0x178:
1323 case 0x278:
1324 case 0x378:
1325 group = (addr - 0x78) / 0x100;
1326 s->patrg[group] &= ~value;
1327 break;
1328 case 0x84:
1329 case 0x184:
1330 case 0x284:
1331 case 0x384:
1332 group = (addr - 0x74) / 0x100;
1333 s->paflg[group] &= ~value;
1334 break;
1335 default:
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,
1349 jz4740_gpio_read,
1352 static CPUWriteMemoryFunc *jz4740_gpio_writefn[] = {
1353 jz4740_badwidth_write32,
1354 jz4740_badwidth_write32,
1355 jz4740_gpio_write,
1358 static struct jz4740_gpio_s *jz4740_gpio_init(struct jz_state_s *soc,
1359 qemu_irq irq)
1361 int iomemtype;
1362 struct jz4740_gpio_s *s = (struct jz4740_gpio_s *) qemu_mallocz(sizeof(*s));
1363 s->base = JZ4740_PHYS_BASE(JZ4740_GPIO_BASE);
1364 s->soc = soc;
1365 s->irq = irq;
1367 jz4740_gpio_reset(s);
1369 iomemtype =
1370 cpu_register_io_memory(0, jz4740_gpio_readfn, jz4740_gpio_writefn, s);
1371 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
1372 return s;
1376 struct jz4740_rtc_s
1378 qemu_irq irq;
1379 target_phys_addr_t base;
1380 struct jz_state_s *soc;
1382 QEMUTimer *hz_tm;
1383 struct tm tm;
1384 //int sec_offset;
1385 int64_t next;
1387 uint32_t rtccr;
1388 uint32_t rtcsr;
1389 uint32_t rtcsar;
1390 uint32_t rtcgr;
1392 uint32_t hcr;
1393 uint32_t hwfcr;
1394 uint32_t hrcr;
1395 uint32_t hwcr;
1396 uint32_t hwrsr;
1397 uint32_t hspr;
1402 static void jz4740_rtc_update_interrupt(struct jz4740_rtc_s *s)
1404 if (!s->rtcsr&0x1)
1405 return;
1407 if (((s->rtccr & 0x40) && (s->rtccr & 0x20))
1408 || ((s->rtccr & 0x10) && (s->rtccr & 0x8)))
1410 debug_out(DEBUG_RTC,"s->rtccr %x \n",s->rtcsr);
1411 qemu_set_irq(s->irq, 1);
1417 static inline void jz4740_rtc_start(struct jz4740_rtc_s *s)
1419 s->next = +qemu_get_clock(rt_clock);
1420 qemu_mod_timer(s->hz_tm, s->next);
1423 static inline void jz4740_rtc_stop(struct jz4740_rtc_s *s)
1425 qemu_del_timer(s->hz_tm);
1426 s->next = -qemu_get_clock(rt_clock);
1427 if (s->next < 1)
1428 s->next = 1;
1431 static void jz4740_rtc_hz(void *opaque)
1433 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1435 s->next += 1000;
1436 qemu_mod_timer(s->hz_tm, s->next);
1437 if (s->rtccr & 0x1)
1439 s->rtcsr++;
1440 s->rtccr |= 0x40;
1441 if (s->rtcsr & 0x4)
1443 if (s->rtcsr == s->rtcsar)
1444 s->rtccr |= 0x10;
1446 jz4740_rtc_update_interrupt(s);
1450 static void jz4740_rtc_reset(struct jz4740_rtc_s *s)
1453 s->rtccr = 0x81;
1454 s->next = 1000;
1456 /*Maybe rtcsr need to be saved to file */
1457 s->rtcsr = time(NULL);
1458 jz4740_rtc_start(s);
1462 static uint32_t jz4740_rtc_read(void *opaque, target_phys_addr_t addr)
1464 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1466 debug_out(DEBUG_RTC, "jz4740_rtc_read addr %x\n", addr);
1467 switch (addr)
1469 case 0x0:
1470 return s->rtccr | 0x80;
1471 case 0x4:
1472 return s->rtcsr;
1473 case 0x8:
1474 return s->rtcsar;
1475 case 0xc:
1476 return s->rtcgr;
1477 case 0x20:
1478 return s->hcr;
1479 case 0x24:
1480 return s->hwfcr;
1481 case 0x28:
1482 return s->hrcr;
1483 case 0x2c:
1484 return s->hwcr;
1485 case 0x30:
1486 return s->hwrsr;
1487 case 0x34:
1488 return s->hspr;
1489 default:
1490 cpu_abort(s->soc->env,
1491 "jz4740_rtc_read undefined addr " JZ_FMT_plx "\n", addr);
1494 return (0);
1497 static void jz4740_rtc_write(void *opaque, target_phys_addr_t addr,
1498 uint32_t value)
1500 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1502 debug_out(DEBUG_RTC, "jz4740_rtc_write addr %x value %x\n", addr, value);
1504 switch (addr)
1506 case 0x0:
1507 s->rtccr = value & 0x7d;
1508 if (!value & 0x40)
1509 s->rtccr &= ~0x40;
1510 if (!value & 0x10)
1511 s->rtccr &= ~0x10;
1512 if (s->rtccr & 0x1)
1514 jz4740_rtc_start(s);
1516 else
1517 jz4740_rtc_stop(s);
1518 break;
1519 case 0x4:
1520 s->rtcsr = value;
1521 break;
1522 case 0x8:
1523 s->rtcsar = value;
1524 break;
1525 case 0xc:
1526 s->rtcgr = value & 0x13ffffff;
1527 break;
1528 case 0x20:
1529 s->hcr = value & 0x1;
1530 break;
1531 case 0x24:
1532 s->hwfcr = value & 0xffe0;
1533 break;
1534 case 0x28:
1535 s->hrcr = value & 0xfe0;
1536 break;
1537 case 0x2c:
1538 s->hwcr = value & 0x1;
1539 break;
1540 case 0x30:
1541 s->hwrsr = value & 0x33;
1542 break;
1543 case 0x34:
1544 s->hspr = value;
1545 break;
1546 default:
1547 cpu_abort(s->soc->env,
1548 "jz4740_rtc_write undefined addr " JZ_FMT_plx
1549 " value %x \n", addr, value);
1554 static CPUReadMemoryFunc *jz4740_rtc_readfn[] = {
1555 jz4740_badwidth_read32,
1556 jz4740_badwidth_read32,
1557 jz4740_rtc_read,
1560 static CPUWriteMemoryFunc *jz4740_rtc_writefn[] = {
1561 jz4740_badwidth_write32,
1562 jz4740_badwidth_write32,
1563 jz4740_rtc_write,
1566 static struct jz4740_rtc_s *jz4740_rtc_init(struct jz_state_s *soc,
1567 qemu_irq irq)
1569 int iomemtype;
1570 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) qemu_mallocz(sizeof(*s));
1571 s->base = JZ4740_PHYS_BASE(JZ4740_RTC_BASE);
1572 s->soc = soc;
1573 s->irq = irq;
1575 s->hz_tm = qemu_new_timer(rt_clock, jz4740_rtc_hz, s);
1577 jz4740_rtc_reset(s);
1579 iomemtype =
1580 cpu_register_io_memory(0, jz4740_rtc_readfn, jz4740_rtc_writefn, s);
1581 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
1582 return s;
1585 struct jz4740_tcu_s
1587 qemu_irq tcu_irq0;
1588 qemu_irq tcu_irq1;
1589 qemu_irq tcu_irq2;
1591 target_phys_addr_t base;
1592 struct jz_state_s *soc;
1595 QEMUTimer *half_timer[8];
1596 QEMUTimer *full_timer[8];
1597 int64_t time[8];
1599 uint32_t tsr;
1600 uint32_t ter;
1601 uint32_t tfr;
1602 uint32_t tmr;
1604 uint32_t tdfr[8];
1605 uint32_t tdhr[8];
1606 uint32_t tcnt[8];
1607 uint32_t tcsr[8];
1609 uint32_t prescale[8];
1610 uint32_t freq[8];
1613 static void jz4740_tcu_update_interrupt(struct jz4740_tcu_s *s)
1615 //printf("s->tfr %x s->tmr %x \n",s->tfr,s->tmr);
1616 if (((s->tfr & 0x1) & (~(s->tmr & 0x1)))
1617 || ((s->tfr & 0x10000) & (~(s->tmr & 0x10000))))
1619 qemu_set_irq(s->tcu_irq0, 1);
1621 else
1622 qemu_set_irq(s->tcu_irq0, 0);
1624 if (((s->tfr & 0x2) & (~(s->tmr & 0x2)))
1625 || ((s->tfr & 0x20000) & (~(s->tmr & 0x20000))))
1627 qemu_set_irq(s->tcu_irq1, 1);
1629 else
1630 qemu_set_irq(s->tcu_irq1, 0);
1632 if (((s->tfr & 0xfc) & (~(s->tmr & 0xfc)))
1633 || ((s->tfr & 0xfc0000) & (~(s->tmr & 0xfc0000))))
1635 qemu_set_irq(s->tcu_irq2, 1);
1637 else
1638 qemu_set_irq(s->tcu_irq2, 0);
1642 #undef TCU_INDEX
1643 #define TCU_INDEX 0
1644 #include "mips_jz_glue.h"
1645 #define TCU_INDEX 1
1646 #include "mips_jz_glue.h"
1647 #define TCU_INDEX 2
1648 #include "mips_jz_glue.h"
1649 #define TCU_INDEX 3
1650 #include "mips_jz_glue.h"
1651 #define TCU_INDEX 4
1652 #include "mips_jz_glue.h"
1653 #define TCU_INDEX 5
1654 #include "mips_jz_glue.h"
1655 #define TCU_INDEX 6
1656 #include "mips_jz_glue.h"
1657 #define TCU_INDEX 7
1658 #include "mips_jz_glue.h"
1659 #undef TCU_INDEX
1661 #define jz4740_tcu_start(s) do { \
1662 jz4740_tcu_start_half0(s); \
1663 jz4740_tcu_start_full0(s); \
1664 jz4740_tcu_start_half1(s); \
1665 jz4740_tcu_start_full1(s); \
1666 jz4740_tcu_start_half2(s); \
1667 jz4740_tcu_start_full2(s); \
1668 jz4740_tcu_start_half3(s); \
1669 jz4740_tcu_start_full3(s); \
1670 jz4740_tcu_start_half4(s); \
1671 jz4740_tcu_start_full4(s); \
1672 jz4740_tcu_start_half5(s); \
1673 jz4740_tcu_start_full5(s); \
1674 jz4740_tcu_start_half6(s); \
1675 jz4740_tcu_start_full6(s); \
1676 jz4740_tcu_start_half7(s); \
1677 jz4740_tcu_start_full7(s); \
1678 }while (0)
1680 static void jz4740_tcu_if_reset(struct jz4740_tcu_s *s)
1682 int i;
1684 s->tsr = 0x0;
1685 s->ter = 0x0;
1686 s->tfr = 0x0;
1687 s->tmr = 0x0;
1688 for (i = 0; i < 8; i++)
1690 s->tdfr[i] = 0xffff;
1691 s->tdhr[i] = 0x8000;
1692 s->tcnt[i] = 0x0;
1693 s->tcsr[i] = 0x0;
1694 s->half_timer[i] = NULL;
1695 s->full_timer[i] = NULL;
1699 static void jz4740_tcu_if_write8(void *opaque, target_phys_addr_t addr,
1700 uint32_t value)
1702 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1704 debug_out(DEBUG_TCU, "jz4740_tcu_if_write8 addr %x value %x\n", addr,
1705 value);
1707 switch (addr)
1709 case 0x14:
1710 s->ter |= (value & 0xff);
1711 jz4740_tcu_start(s);
1712 break;
1713 case 0x18:
1714 s->ter &= ~(value & 0xff);
1715 jz4740_tcu_start(s);
1716 break;
1717 default:
1718 cpu_abort(s->soc->env,
1719 "jz4740_tcu_if_write8 undefined addr " JZ_FMT_plx
1720 " value %x \n", addr, value);
1725 static void jz4740_tcu_if_write32(void *opaque, target_phys_addr_t addr,
1726 uint32_t value)
1728 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1730 debug_out(DEBUG_TCU, "jz4740_tcu_if_write32 addr %x value %x\n", addr,
1731 value);
1733 switch (addr)
1735 case 0x2c:
1736 s->tsr |= (value & 0x100ff);
1737 jz4740_tcu_start(s);
1738 break;
1739 case 0x3c:
1740 s->tsr &= ~(value & 0x100ff);
1741 jz4740_tcu_start(s);
1742 break;
1743 case 0x24:
1744 s->tfr |= (value & 0xff00ff);
1745 break;
1746 case 0x28:
1747 s->tfr &= ~(value & 0xff00ff);
1748 break;
1749 case 0x34:
1750 s->tmr |= (value & 0xff00ff);
1751 jz4740_tcu_update_interrupt(s);
1752 break;
1753 case 0x38:
1754 s->tmr &= ~(value & 0xff00ff);
1755 jz4740_tcu_update_interrupt(s);
1756 break;
1757 default:
1758 cpu_abort(s->soc->env,
1759 "jz4740_tcu_if_write32 undefined addr " JZ_FMT_plx
1760 " value %x \n", addr, value);
1765 static uint32_t jz4740_tcu_if_read8(void *opaque, target_phys_addr_t addr)
1767 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1769 debug_out(DEBUG_TCU, "jz4740_tcu_if_read8 addr %x\n", addr);
1771 switch (addr)
1773 case 0x10:
1774 return s->ter;
1775 default:
1776 cpu_abort(s->soc->env,
1777 "jz4740_tcu_if_read8 undefined addr " JZ_FMT_plx "\n", addr);
1779 return (0);
1782 static uint32_t jz4740_tcu_if_read32(void *opaque, target_phys_addr_t addr)
1784 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1786 debug_out(DEBUG_TCU, "jz4740_tcu_if_read32 addr %x\n", addr);
1788 switch (addr)
1790 case 0x1c:
1791 return s->tsr;
1792 case 0x20:
1793 return s->tfr;
1794 case 0x30:
1795 return s->tmr;
1796 default:
1797 cpu_abort(s->soc->env,
1798 "jz4740_tcu_if_read32 undefined addr " JZ_FMT_plx "\n", addr);
1801 return (0);
1805 static CPUReadMemoryFunc *jz4740_tcu_if_readfn[] = {
1806 jz4740_tcu_if_read8,
1807 jz4740_badwidth_read32,
1808 jz4740_tcu_if_read32,
1811 static CPUWriteMemoryFunc *jz4740_tcu_if_writefn[] = {
1812 jz4740_tcu_if_write8,
1813 jz4740_badwidth_write32,
1814 jz4740_tcu_if_write32,
1817 static struct jz4740_tcu_s *jz4740_tcu_if_init(struct jz_state_s *soc,
1818 qemu_irq tcu_irq0,
1819 qemu_irq tcu_irq1,
1820 qemu_irq tcu_irq2)
1822 int iomemtype;
1823 //int i;
1825 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) qemu_mallocz(sizeof(*s));
1826 s->base = JZ4740_PHYS_BASE(JZ4740_TCU_BASE);
1827 s->soc = soc;
1828 s->tcu_irq0 = tcu_irq0;
1829 s->tcu_irq1 = tcu_irq1;
1830 s->tcu_irq2 = tcu_irq2;
1832 jz4740_tcu_if_reset(s);
1834 iomemtype =
1835 cpu_register_io_memory(0, jz4740_tcu_if_readfn, jz4740_tcu_if_writefn,
1837 cpu_register_physical_memory(s->base, 0x00000040, iomemtype);
1838 return s;
1842 static void jz4740_tcu_init(struct jz_state_s *soc,
1843 struct jz4740_tcu_s *s, int timer_index)
1845 switch (timer_index)
1847 case 0x0:
1848 jz4740_tcu_init0(soc, s);
1849 break;
1850 case 0x1:
1851 jz4740_tcu_init1(soc, s);
1852 break;
1853 case 0x2:
1854 jz4740_tcu_init2(soc, s);
1855 break;
1856 case 0x3:
1857 jz4740_tcu_init3(soc, s);
1858 break;
1859 case 0x4:
1860 jz4740_tcu_init4(soc, s);
1861 break;
1862 case 0x5:
1863 jz4740_tcu_init5(soc, s);
1864 break;
1865 case 0x6:
1866 jz4740_tcu_init6(soc, s);
1867 break;
1868 case 0x7:
1869 jz4740_tcu_init7(soc, s);
1870 break;
1871 default:
1872 cpu_abort(s->soc->env,
1873 "jz4740_tcu_init undefined timer %x \n", timer_index);
1877 typedef void (*jz4740_lcd_fn_t) (uint8_t * d, const uint8_t * s, int width,
1878 const uint16_t * pal);
1879 struct jz_fb_descriptor
1881 uint32_t fdadr; /* Frame descriptor address register */
1882 uint32_t fsadr; /* Frame source address register */
1883 uint32_t fidr; /* Frame ID register */
1884 uint32_t ldcmd; /* Command register */
1887 struct jz4740_lcdc_s
1889 qemu_irq irq;
1891 target_phys_addr_t base;
1892 struct jz_state_s *soc;
1894 DisplayState *state;
1895 QEMUConsole *console;
1896 jz4740_lcd_fn_t *line_fn_tab;
1897 jz4740_lcd_fn_t line_fn;
1900 uint32_t lcdcfg;
1901 uint32_t lcdvsync;
1902 uint32_t lcdhsync;
1903 uint32_t lcdvat;
1904 uint32_t lcddah;
1905 uint32_t lcddav;
1906 uint32_t lcdps;
1907 uint32_t lcdcls;
1908 uint32_t lcdspl;
1909 uint32_t lcdrev;
1910 uint32_t lcdctrl;
1911 uint32_t lcdstate;
1912 uint32_t lcdiid;
1913 uint32_t lcdda0;
1914 uint32_t lcdsa0;
1915 uint32_t lcdfid0;
1916 uint32_t lcdcmd0;
1917 uint32_t lcdda1;
1918 uint32_t lcdsa1;
1919 uint32_t lcdfid1;
1920 uint32_t lcdcmd1;
1922 uint32_t ena;
1923 uint32_t dis;
1924 uint32_t width;
1925 uint32_t height;
1926 uint32_t bpp; /*bit per second */
1927 uint16_t palette[256];
1928 uint32_t invalidate;
1932 /*bit per pixel*/
1933 static const int jz4740_lcd_bpp[0x6] = {
1934 1, 2, 4, 8, 16, 32 /*4740 uses 32 bit for 24bpp */
1937 static void jz4740_lcdc_reset(struct jz4740_lcdc_s *s)
1942 static uint32_t jz4740_lcdc_read(void *opaque, target_phys_addr_t addr)
1944 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
1946 debug_out(DEBUG_LCDC, "jz4740_lcdc_read addr %x \n", addr);
1947 switch (addr)
1949 case 0x0:
1950 return s->lcdcfg;
1951 case 0x4:
1952 return s->lcdvsync;
1953 case 0x8:
1954 return s->lcdhsync;
1955 case 0xc:
1956 return s->lcdvat;
1957 case 0x10:
1958 return s->lcddah;
1959 case 0x14:
1960 return s->lcddav;
1961 case 0x18:
1962 return s->lcdps;
1963 case 0x1c:
1964 return s->lcdcls;
1965 case 0x20:
1966 return s->lcdspl;
1967 case 0x24:
1968 return s->lcdrev;
1969 case 0x30:
1970 return s->lcdctrl;
1971 case 0x34:
1972 return s->lcdstate;
1973 case 0x38:
1974 return s->lcdiid;
1975 case 0x40:
1976 return s->lcdda0;
1977 case 0x44:
1978 return s->lcdsa0;
1979 case 0x48:
1980 return s->lcdfid0;
1981 case 0x4c:
1982 return s->lcdcmd0;
1983 case 0x50:
1984 return s->lcdda1;
1985 case 0x54:
1986 return s->lcdsa1;
1987 case 0x58:
1988 return s->lcdfid1;
1989 case 0x5c:
1990 return s->lcdcmd1;
1991 default:
1992 cpu_abort(s->soc->env,
1993 "jz4740_lcdc_read undefined addr " JZ_FMT_plx " \n", addr);
1999 static void jz4740_lcdc_write(void *opaque, target_phys_addr_t addr,
2000 uint32_t value)
2002 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
2004 debug_out(DEBUG_LCDC, "jz4740_lcdc_write addr %x value %x\n", addr, value);
2006 switch (addr)
2008 case 0x44:
2009 case 0x48:
2010 case 0x4c:
2011 JZ4740_RO_REG(addr);
2012 break;
2013 case 0x0:
2014 s->lcdcfg = value & 0x80ffffbf;
2015 break;
2016 case 0x4:
2017 s->lcdvsync = value & 0x7ff07ff;
2018 break;
2019 case 0x8:
2020 s->lcdhsync = value & 0x7ff07ff;
2021 break;
2022 case 0xc:
2023 s->lcdvat = value & 0x7ff07ff;
2024 break;
2025 case 0x10:
2026 s->lcddah = value & 0x7ff07ff;
2027 s->width = (value & 0x7ff) - ((value >> 16) & 0x7ff);
2028 break;
2029 case 0x14:
2030 s->height = (value & 0x7ff) - ((value >> 16) & 0x7ff);
2031 s->lcddav = value & 0x7ff07ff;
2032 break;
2033 case 0x18:
2034 s->lcdps = value & 0x7ff07ff;
2035 break;
2036 case 0x1c:
2037 s->lcdcls = value & 0x7ff07ff;
2038 break;
2039 case 0x20:
2040 s->lcdspl = value & 0x7ff07ff;
2041 break;
2042 case 0x24:
2043 s->lcdrev = value & 0x7ff0000;
2044 break;
2045 case 0x30:
2046 s->lcdctrl = value & 0x3fff3fff;
2047 s->ena = (value & 0x8) >> 3;
2048 s->dis = (value & 0x10) >> 4;
2049 s->bpp = jz4740_lcd_bpp[value & 0x7];
2050 if ((s->bpp == 1))
2052 fprintf(stderr, "bpp =1 is not supported\n");
2053 exit(-1);
2055 s->line_fn = s->line_fn_tab[value & 0x7];
2056 break;
2057 case 0x34:
2058 s->lcdstate = value & 0xbf;
2059 break;
2060 case 0x38:
2061 s->lcdiid = value;
2062 break;
2063 case 0x40:
2064 s->lcdda0 = value;
2065 break;
2066 case 0x50:
2067 s->lcdda1 = value;
2068 break;
2069 default:
2070 cpu_abort(s->soc->env,
2071 "jz4740_lcdc_write undefined addr " JZ_FMT_plx " value %x \n",
2072 addr, value);
2077 static CPUReadMemoryFunc *jz4740_lcdc_readfn[] = {
2078 jz4740_badwidth_read32,
2079 jz4740_badwidth_read32,
2080 jz4740_lcdc_read,
2083 static CPUWriteMemoryFunc *jz4740_lcdc_writefn[] = {
2084 jz4740_badwidth_write32,
2085 jz4740_badwidth_write32,
2086 jz4740_lcdc_write,
2089 #include "pixel_ops.h"
2090 #define JZ4740_LCD_PANEL
2091 #define DEPTH 8
2092 #include "mips_jz_glue.h"
2093 #define DEPTH 15
2094 #include "mips_jz_glue.h"
2095 #define DEPTH 16
2096 #include "mips_jz_glue.h"
2097 #define DEPTH 24
2098 #include "mips_jz_glue.h"
2099 #define DEPTH 32
2100 #include "mips_jz_glue.h"
2101 #undef JZ4740_LCD_PANEL
2103 static void *jz4740_lcd_get_buffer(struct jz4740_lcdc_s *s,
2104 target_phys_addr_t addr)
2106 uint32_t pd;
2108 pd = cpu_get_physical_page_desc(addr);
2109 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2110 /* TODO */
2111 cpu_abort(cpu_single_env, "%s: framebuffer outside RAM!\n",
2112 __FUNCTION__);
2113 else
2114 return phys_ram_base +
2115 (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2118 static void jz4740_lcd_update_display(void *opaque)
2120 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
2122 uint8_t *src, *dest;
2123 struct jz_fb_descriptor *fb_des;
2125 int step, linesize;
2126 int y;
2129 if (!s->ena)
2130 return;
2131 if (s->dis)
2132 return;
2134 if (!s->lcdda0)
2135 return;
2137 fb_des = (struct jz_fb_descriptor *) jz4740_lcd_get_buffer(s, s->lcdda0);
2138 s->lcdda0 = fb_des->fdadr;
2139 s->lcdsa0 = fb_des->fsadr;
2140 s->lcdfid0 = fb_des->fidr;
2141 s->lcdcmd0 = fb_des->ldcmd;
2143 src = (uint8_t *) jz4740_lcd_get_buffer(s, fb_des->fsadr);
2144 if (s->lcdcmd0 & (0x1 << 28))
2146 /*palette */
2147 memcpy(s->palette, src, sizeof(s->palette));
2148 return;
2151 /*frame buffer */
2153 if (s->width != ds_get_width(s->state) ||
2154 s->height != ds_get_height(s->state))
2156 qemu_console_resize(s->console, s->width, s->height);
2157 s->invalidate = 1;
2160 step = (s->width * s->bpp) >> 3;
2161 dest = ds_get_data(s->state);
2162 linesize = ds_get_linesize(s->state);
2164 //printf("s->width %d s->height %d s->bpp %d linesize %d \n",s->width,s->height ,s->bpp,linesize);
2166 for (y = 0; y < s->height; y++)
2168 s->line_fn(dest, src, s->width, s->palette);
2169 //memcpy(dest,src,step);
2170 src += step;
2171 dest += linesize;
2175 dpy_update(s->state, 0, 0, s->width, s->height);
2176 s->lcdstate |= 0x20;
2177 if ((s->lcdcmd0 & 0x40000000) && (!(s->lcdctrl & 0x2000)))
2178 qemu_set_irq(s->irq, 1);
2181 static inline void jz4740_lcd_invalidate_display(void *opaque)
2183 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
2184 s->invalidate = 1;
2187 static struct jz4740_lcdc_s *jz4740_lcdc_init(struct jz_state_s *soc,
2188 qemu_irq irq, DisplayState * ds)
2190 int iomemtype;
2192 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) qemu_mallocz(sizeof(*s));
2193 s->base = JZ4740_PHYS_BASE(JZ4740_LCD_BASE);
2194 s->soc = soc;
2195 s->irq = irq;
2196 s->state = ds;
2199 jz4740_lcdc_reset(s);
2201 iomemtype =
2202 cpu_register_io_memory(0, jz4740_lcdc_readfn, jz4740_lcdc_writefn, s);
2203 cpu_register_physical_memory(s->base, 0x10000, iomemtype);
2205 s->console = graphic_console_init(s->state, jz4740_lcd_update_display,
2206 jz4740_lcd_invalidate_display,
2207 NULL, NULL, s);
2208 switch (ds_get_bits_per_pixel(s->state))
2210 case 0x0:
2211 s->line_fn_tab = qemu_mallocz(sizeof(jz4740_lcd_fn_t) * 6);
2212 break;
2213 case 8:
2214 s->line_fn_tab = jz4740_lcd_draw_fn_8;
2215 break;
2216 case 15:
2217 s->line_fn_tab = jz4740_lcd_draw_fn_15;
2218 break;
2219 case 16:
2220 s->line_fn_tab = jz4740_lcd_draw_fn_16;
2221 break;
2222 case 24:
2223 s->line_fn_tab = jz4740_lcd_draw_fn_24;
2224 break;
2225 case 32:
2226 s->line_fn_tab = jz4740_lcd_draw_fn_32;
2227 break;
2228 default:
2229 fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
2230 exit(1);
2233 return s;
2237 #define JZ4740_DMA_NUM 6
2238 struct jz4740_dma_s
2240 qemu_irq irq;
2242 target_phys_addr_t base;
2243 struct jz_state_s *soc;
2245 uint32_t dmac;
2246 uint32_t dirqp;
2247 uint32_t ddr;
2248 uint32_t ddrs;
2250 uint32_t dsa[JZ4740_DMA_NUM];
2251 uint32_t dta[JZ4740_DMA_NUM];
2252 uint32_t dtc[JZ4740_DMA_NUM];
2253 uint32_t drs[JZ4740_DMA_NUM];
2254 uint32_t dcs[JZ4740_DMA_NUM];
2255 uint32_t dcm[JZ4740_DMA_NUM];
2256 uint32_t dda[JZ4740_DMA_NUM];
2260 struct jz4740_desc_s
2262 uint32_t dcmd; /* DCMD value for the current transfer */
2263 uint32_t dsadr; /* DSAR value for the current transfer */
2264 uint32_t dtadr; /* DTAR value for the current transfer */
2265 uint32_t ddadr; /* Points to the next descriptor + transfer count */
2268 static inline void jz4740_dma_transfer(struct jz4740_dma_s *s,
2269 target_phys_addr_t src,
2270 target_phys_addr_t dest, uint32_t len)
2272 uint32_t pd_src, pd_dest;
2273 uint8_t *sr, *de;
2275 pd_src = cpu_get_physical_page_desc(src);
2276 if ((pd_src & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2277 /* TODO */
2278 cpu_abort(cpu_single_env, "%s: DMA source address %x outside RAM!\n",
2279 __FUNCTION__, src);
2280 else
2281 sr = phys_ram_base +
2282 (pd_src & TARGET_PAGE_MASK) + (src & ~TARGET_PAGE_MASK);
2284 pd_dest = cpu_get_physical_page_desc(dest);
2285 if ((pd_dest & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2286 /* TODO */
2287 cpu_abort(cpu_single_env,
2288 "%s: DMA destination address %x outside RAM!\n",
2289 __FUNCTION__, dest);
2290 else
2291 de = phys_ram_base +
2292 (pd_dest & TARGET_PAGE_MASK) + (dest & ~TARGET_PAGE_MASK);
2294 memcpy(de, sr, len);
2297 static inline uint32_t jz4740_dma_unit_size(struct jz4740_dma_s *s,
2298 uint32_t cmd)
2300 switch ((cmd & 0x700) >> 8)
2302 case 0x0:
2303 return 4;
2304 case 0x1:
2305 return 1;
2306 case 0x2:
2307 return 2;
2308 case 0x3:
2309 return 16;
2310 case 0x4:
2311 return 32;
2313 return (0);
2317 /*No-descriptor transfer*/
2318 static inline void jz4740_dma_ndrun(struct jz4740_dma_s *s, int channel)
2320 uint32_t len;
2322 len = jz4740_dma_unit_size(s, s->dcs[channel]) * s->dtc[channel];
2324 jz4740_dma_transfer(s, s->dsa[channel], s->dta[channel], len);
2326 /*finish dma transfer */
2327 s->dtc[channel] = 0;
2328 /*set DIR QP */
2329 s->dirqp |= 1 << channel;
2331 /*some cleanup work */
2332 /*clean AR TT GLOBAL AR */
2333 s->dcs[channel] &= 0xffffffe7;
2334 s->dmac &= 0xfffffffb;
2336 if (s->dcm[channel] & 0x2)
2337 qemu_set_irq(s->irq, 1);
2340 /*descriptor transfer */
2341 static inline void jz4740_dma_drun(struct jz4740_dma_s *s, int channel)
2343 struct jz4740_desc_s *desc;
2344 target_phys_addr_t desc_phy;
2345 uint32_t pd;
2347 desc_phy = s->dda[channel];
2348 if (desc_phy & 0xf)
2349 cpu_abort(s->soc->env,
2350 "jz4740_dma_drun descriptor address " JZ_FMT_plx
2351 " must be 4 bytes aligned \n", desc_phy);
2353 pd = cpu_get_physical_page_desc(desc_phy);
2354 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2355 cpu_abort(cpu_single_env,
2356 "%s: DMA descriptor address " JZ_FMT_plx " outside RAM!\n",
2357 __FUNCTION__, desc_phy);
2358 else
2359 desc = (struct jz4740_desc_s *) (phys_ram_base +
2360 (pd & TARGET_PAGE_MASK) +
2361 (desc_phy & ~TARGET_PAGE_MASK));
2363 if (!desc)
2364 cpu_abort(cpu_single_env,
2365 "%s: DMA descriptor " JZ_FMT_plx " is NULL!\n", __FUNCTION__,
2366 (uint32_t) desc);
2368 while (1)
2370 if ((desc->dcmd & 0x8) && (!(desc->dcmd & 0x10)))
2372 /*Stop DMA and set DCSN.INV=1 */
2373 s->dcs[channel] |= 1 << 6;
2374 return;
2376 jz4740_dma_transfer(s, desc->dtadr, desc->dsadr,
2377 (desc->ddadr & 0xffffff) *
2378 jz4740_dma_unit_size(s, desc->dcmd));
2380 if ((desc->dcmd) & (1 << 3))
2381 /*clear v */
2382 desc->dcmd &= ~(1 << 4);
2383 if (desc->dcmd & 0x1)
2384 /*set DCSN.CT=1 */
2385 s->dcs[channel] |= 0x2;
2386 else
2387 /*set DCSN.TT=1 */
2388 s->dcs[channel] |= 0x8;
2390 if (desc->dcmd & 0x2)
2391 qemu_set_irq(s->irq, 1);
2393 if ((desc->dcmd) & 0x1)
2395 /*fetch next descriptor */
2396 desc_phy = s->dda[channel] & 0xfffff000;
2397 desc_phy += (desc->dtadr & 0xff000000) >> 24;
2398 pd = cpu_get_physical_page_desc(desc_phy);
2399 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2400 cpu_abort(cpu_single_env,
2401 "%s: DMA descriptor address %x outside RAM!\n",
2402 __FUNCTION__, desc_phy);
2403 else
2404 desc = (struct jz4740_desc_s *) (phys_ram_base +
2405 (pd & TARGET_PAGE_MASK)
2407 (desc_phy &
2408 ~TARGET_PAGE_MASK));
2409 if (!desc)
2410 cpu_abort(cpu_single_env,
2411 "%s: DMA descriptor %x is NULL!\n",
2412 __FUNCTION__, (uint32_t) desc);
2414 else
2415 break;
2419 static void jz4740_dma_en_channel(struct jz4740_dma_s *s, int channel)
2421 if (s->dmac & 0x1)
2423 if (s->dcs[channel] & (1 << 31))
2425 /*NON DESCRIPTOR */
2426 jz4740_dma_ndrun(s, channel);
2431 static inline void jz4740_dma_en_global(struct jz4740_dma_s *s)
2433 int channel;
2434 for (channel = 0; channel < JZ4740_DMA_NUM; channel++)
2436 jz4740_dma_en_channel(s, channel);
2440 static inline void jz4740_dma_en_dbn(struct jz4740_dma_s *s, int channel)
2442 if ((s->dmac & 0x1) && (s->dcs[channel] & (1 << 31)))
2444 jz4740_dma_drun(s, channel);
2448 static void jz4740_dma_reset(struct jz4740_dma_s *s)
2453 static uint32_t jz4740_dma_read(void *opaque, target_phys_addr_t addr)
2455 struct jz4740_dma_s *s = (struct jz4740_dma_s *) opaque;
2456 int channel;
2458 debug_out(DEBUG_DMA, "jz4740_dma_read addr %x \n", addr);
2459 switch (addr)
2461 case 0x300:
2462 return s->dmac;
2463 case 0x304:
2464 return s->dirqp;
2465 case 0x308:
2466 return s->ddr;
2467 case 0x0:
2468 case 0x20:
2469 case 0x40:
2470 case 0x60:
2471 case 0x80:
2472 case 0xa0:
2473 channel = (addr - 0x0) / 0x20;
2474 return s->dsa[channel];
2475 case 0x4:
2476 case 0x24:
2477 case 0x44:
2478 case 0x64:
2479 case 0x84:
2480 case 0xa4:
2481 channel = (addr - 0x4) / 0x20;
2482 return s->dta[channel];
2483 case 0x8:
2484 case 0x28:
2485 case 0x48:
2486 case 0x68:
2487 case 0x88:
2488 case 0xa8:
2489 channel = (addr - 0x8) / 0x20;
2490 return s->dtc[channel];
2491 case 0xc:
2492 case 0x2c:
2493 case 0x4c:
2494 case 0x6c:
2495 case 0x8c:
2496 case 0xac:
2497 channel = (addr - 0xc) / 0x20;
2498 return s->drs[channel];
2499 case 0x10:
2500 case 0x30:
2501 case 0x50:
2502 case 0x70:
2503 case 0x90:
2504 case 0xb0:
2505 channel = (addr - 0x10) / 0x20;
2506 return s->dcs[channel];
2507 case 0x14:
2508 case 0x34:
2509 case 0x54:
2510 case 0x74:
2511 case 0x94:
2512 case 0xb4:
2513 channel = (addr - 0x14) / 0x20;
2514 return s->dcm[channel];
2515 case 0x18:
2516 case 0x38:
2517 case 0x58:
2518 case 0x78:
2519 case 0x98:
2520 case 0xb8:
2521 channel = (addr - 0x18) / 0x20;
2522 return s->dda[channel];
2523 default:
2524 cpu_abort(s->soc->env,
2525 "jz4740_dma_read undefined addr " JZ_FMT_plx " \n", addr);
2527 return (0);
2530 static void jz4740_dma_write(void *opaque, target_phys_addr_t addr,
2531 uint32_t value)
2533 struct jz4740_dma_s *s = (struct jz4740_dma_s *) opaque;
2534 int channel;
2536 debug_out(DEBUG_DMA, "jz4740_dma_write addr %x value %x \n", addr, value);
2537 switch (addr)
2539 case 0x304:
2540 JZ4740_RO_REG(addr);
2541 break;
2542 case 0x300:
2543 s->dmac = value & 0x30d;
2544 if (s->dmac & 0x1)
2545 jz4740_dma_en_global(s);
2546 break;
2547 case 0x308:
2548 case 0x30c:
2549 s->ddr = value & 0xff;
2550 for (channel = 0; channel < JZ4740_DMA_NUM; channel++)
2552 if (s->ddr & (1 << channel))
2554 jz4740_dma_en_dbn(s, channel);
2555 break;
2558 break;
2559 case 0x0:
2560 case 0x20:
2561 case 0x40:
2562 case 0x60:
2563 case 0x80:
2564 case 0xa0:
2565 channel = (addr - 0x0) / 0x20;
2566 s->dsa[channel] = value;
2567 break;
2568 case 0x4:
2569 case 0x24:
2570 case 0x44:
2571 case 0x64:
2572 case 0x84:
2573 case 0xa4:
2574 channel = (addr - 0x4) / 0x20;
2575 s->dta[channel] = value;
2576 break;
2577 case 0x8:
2578 case 0x28:
2579 case 0x48:
2580 case 0x68:
2581 case 0x88:
2582 case 0xa8:
2583 channel = (addr - 0x8) / 0x20;
2584 s->dtc[channel] = value;
2585 break;
2586 case 0xc:
2587 case 0x2c:
2588 case 0x4c:
2589 case 0x6c:
2590 case 0x8c:
2591 case 0xac:
2592 channel = (addr - 0xc) / 0x20;
2593 s->drs[channel] = value & 0x10;
2594 if (s->drs[channel] != 0x8)
2596 fprintf(stderr, "Only auto request is supproted \n");
2598 break;
2599 case 0x10:
2600 case 0x30:
2601 case 0x50:
2602 case 0x70:
2603 case 0x90:
2604 case 0xb0:
2605 channel = (addr - 0x10) / 0x20;
2606 s->dcs[channel] = value & 0x80ff005f;
2607 if (s->dcs[channel] & 0x1)
2608 jz4740_dma_en_channel(s, channel);
2609 break;
2610 case 0x14:
2611 case 0x34:
2612 case 0x54:
2613 case 0x74:
2614 case 0x94:
2615 case 0xb4:
2616 channel = (addr - 0x14) / 0x20;
2617 s->dcm[channel] = value & 0xcff79f;
2618 break;
2619 case 0x18:
2620 case 0x38:
2621 case 0x58:
2622 case 0x78:
2623 case 0x98:
2624 case 0xb8:
2625 channel = (addr - 0x18) / 0x20;
2626 s->dda[channel] = 0xfffffff0;
2627 break;
2628 default:
2629 cpu_abort(s->soc->env,
2630 "jz4740_dma_read undefined addr " JZ_FMT_plx " \n", addr);
2635 static CPUReadMemoryFunc *jz4740_dma_readfn[] = {
2636 jz4740_badwidth_read32,
2637 jz4740_badwidth_read32,
2638 jz4740_dma_read,
2641 static CPUWriteMemoryFunc *jz4740_dma_writefn[] = {
2642 jz4740_badwidth_write32,
2643 jz4740_badwidth_write32,
2644 jz4740_dma_write,
2648 static struct jz4740_dma_s *jz4740_dma_init(struct jz_state_s *soc,
2649 qemu_irq irq)
2651 int iomemtype;
2652 struct jz4740_dma_s *s = (struct jz4740_dma_s *) qemu_mallocz(sizeof(*s));
2653 s->base = JZ4740_PHYS_BASE(JZ4740_DMAC_BASE);
2654 s->soc = soc;
2655 s->irq = irq;
2657 jz4740_dma_reset(s);
2659 iomemtype =
2660 cpu_register_io_memory(0, jz4740_dma_readfn, jz4740_dma_writefn, s);
2661 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
2662 return s;
2666 #define PEN_DOWN 1
2667 #define PEN_UP 0
2668 struct jz4740_sadc_s
2670 qemu_irq irq;
2672 target_phys_addr_t base;
2673 struct jz_state_s *soc;
2675 uint32_t adena;
2676 uint32_t adcfg;
2677 uint32_t adctrl;
2678 uint32_t adstate;
2679 uint32_t adsame;
2680 uint32_t adwait;
2681 uint32_t adtch;
2682 uint32_t adbdat;
2683 uint32_t adsdat;
2684 uint32_t addpin;
2686 uint8_t tchen;
2687 uint8_t ex_in;
2688 uint8_t xyz;
2689 uint8_t snum;
2691 uint16_t x;
2692 uint16_t y;
2694 uint16_t pen_state;
2695 uint8_t read_index;
2700 static void jz4740_touchscreen_interrupt(struct jz4740_sadc_s *s)
2702 if (!s->tchen)
2703 return;
2705 if ((s->adctrl)&(s->adstate))
2707 debug_out(DEBUG_SADC,"irq s->adctrl %x s->adstate %x \n",s->adctrl,s->adstate);
2708 qemu_set_irq(s->irq,1);
2713 static void jz4740_touchscreen_event(void *opaque,
2714 int x, int y, int z, int buttons_state)
2716 struct jz4740_sadc_s *s = opaque;
2718 if (!s->tchen)
2719 return;
2721 s->x = (x*4096)/0x7FFF;
2722 s->y = (y*4096)/0x7FFF;
2724 if ((s->pen_state == PEN_UP)&&(buttons_state==PEN_DOWN))
2726 s->adstate |= 0x14;
2727 jz4740_touchscreen_interrupt(s);
2729 else if ((s->pen_state == PEN_DOWN)&&(buttons_state==PEN_UP))
2731 s->adstate |= 0xc;
2732 jz4740_touchscreen_interrupt(s);
2734 s->pen_state = buttons_state;
2738 static uint32_t jz4740_sadc_read8(void *opaque, target_phys_addr_t addr)
2740 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2742 switch (addr)
2744 case 0x0:
2745 return s->adena;
2746 case 0x8:
2747 return s->adctrl;
2748 case 0xc:
2749 return s->adstate;
2750 default:
2751 cpu_abort(s->soc->env,
2752 "jz4740_sadc_read8 undefined addr " JZ_FMT_plx " \n", addr);
2754 return (0);
2757 static uint32_t jz4740_sdac_read16(void *opaque, target_phys_addr_t addr)
2759 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2761 switch (addr)
2763 case 0x10:
2764 return s->adsame;
2765 case 0x14:
2766 return s->adwait;
2767 case 0x1c:
2768 return s->adbdat;
2769 case 0x20:
2770 return s->adsdat;
2771 default:
2772 cpu_abort(s->soc->env,
2773 "jz4740_sdac_read16 undefined addr " JZ_FMT_plx " \n", addr);
2775 return (0);
2778 static uint32_t jz4740_sdac_read32(void *opaque, target_phys_addr_t addr)
2780 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2781 switch (addr)
2783 case 0x4:
2784 return s->adcfg;
2785 case 0x18:
2786 /*TODO: Other type format*/
2787 if (s->read_index==0)
2789 s->read_index ++;
2790 return (((s->x) & 0x7fff) | ((s->y & 0x7ffff) << 16));
2792 else
2794 s->read_index = 0;
2795 return (0x3fff);
2797 default:
2798 cpu_abort(s->soc->env,
2799 "jz4740_sdac_read32 undefined addr " JZ_FMT_plx " \n", addr);
2801 return (0);
2804 static void jz4740_sadc_write8(void *opaque, target_phys_addr_t addr,
2805 uint32_t value)
2807 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2809 debug_out(DEBUG_SADC, "jz4740_sadc_write8 addr %x value %x\n", addr, value);
2811 switch (addr)
2813 case 0x0:
2814 s->adena = value & 0x7;
2815 s->tchen = value & 0x4;
2816 break;
2817 case 0x8:
2818 s->adctrl = value & 0x1f;
2819 break;
2820 case 0xc:
2821 s->adstate &= ~(value & 0x1f);
2822 break;
2823 default:
2824 cpu_abort(s->soc->env,
2825 "jz4740_sadc_write8 undefined addr " JZ_FMT_plx " value %x \n", addr,value);
2829 static void jz4740_sadc_write16(void *opaque, target_phys_addr_t addr,
2830 uint32_t value)
2832 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2834 debug_out(DEBUG_SADC, "jz4740_sadc_write16 addr %x value %x\n", addr, value);
2836 switch (addr)
2838 case 0x10:
2839 s->adsame = value & 0xffff;
2840 break;
2841 case 0x14:
2842 s->adsdat = value & 0xffff;
2843 break;
2844 case 0x1c:
2845 s->adbdat = 0x0;
2846 case 0x20:
2847 s->adsdat = 0x0;
2848 default:
2849 cpu_abort(s->soc->env,
2850 "jz4740_sadc_write16 undefined addr " JZ_FMT_plx " value %x \n", addr,value);
2854 static void jz4740_sadc_write32(void *opaque, target_phys_addr_t addr,
2855 uint32_t value)
2857 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2860 debug_out(DEBUG_SADC, "jz4740_sadc_write32 addr %x value %x\n", addr, value);
2862 switch (addr)
2864 case 0x4:
2865 s->adcfg = value & 0xc007ffff;
2866 s->ex_in = (value & 0x40000000)>>30;
2867 s->xyz = (value & 0x6fff)>>13;
2868 s->snum = ((value & 0x1cff)>>10)+1;
2869 break;
2870 case 18:
2871 s->adtch = value & 0x8fff8fff;
2872 break;
2873 default:
2874 cpu_abort(s->soc->env,
2875 "jz4740_sadc_write32 undefined addr " JZ_FMT_plx " value %x \n", addr,value);
2879 static void jz4740_sadc_reset(struct jz4740_sadc_s *s)
2881 s->adcfg = 0x0002002c;
2882 s->tchen = 0;
2883 s->snum = 1;
2884 s->xyz = 0;
2885 s->ex_in = 0;
2888 static CPUReadMemoryFunc *jz4740_sadc_readfn[] = {
2889 jz4740_sadc_read8,
2890 jz4740_sdac_read16,
2891 jz4740_sdac_read32,
2894 static CPUWriteMemoryFunc *jz4740_sadc_writefn[] = {
2895 jz4740_sadc_write8,
2896 jz4740_sadc_write16,
2897 jz4740_sadc_write32,
2900 static struct jz4740_sadc_s *jz4740_sadc_init(struct jz_state_s *soc,
2901 qemu_irq irq)
2903 int iomemtype;
2904 struct jz4740_sadc_s *s;
2906 s = (struct jz4740_sadc_s *)
2907 qemu_mallocz(sizeof(struct jz4740_sadc_s));
2908 s->base = JZ4740_PHYS_BASE(JZ4740_SADC_BASE);
2909 s->irq = irq;
2910 s->soc = soc;
2912 qemu_add_mouse_event_handler(jz4740_touchscreen_event, s, 1,
2913 "QEMU JZ4740 Touchscreen");
2915 jz4740_sadc_reset(s);
2917 iomemtype =
2918 cpu_register_io_memory(0, jz4740_sadc_readfn, jz4740_sadc_writefn, s);
2919 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
2920 return s;
2923 static void jz4740_cpu_reset(void *opaque)
2925 fprintf(stderr, "%s: UNIMPLEMENTED!", __FUNCTION__);
2928 struct jz_state_s *jz4740_init(unsigned long sdram_size,
2929 uint32_t osc_extal_freq, DisplayState * ds)
2931 struct jz_state_s *s = (struct jz_state_s *)
2932 qemu_mallocz(sizeof(struct jz_state_s));
2933 ram_addr_t sram_base, sdram_base;
2934 qemu_irq *intc;
2936 s->mpu_model = jz4740;
2937 s->env = cpu_init("jz4740");
2939 if (!s->env)
2941 fprintf(stderr, "Unable to find CPU definition\n");
2942 exit(1);
2945 debug_init();
2946 qemu_register_reset(jz4740_cpu_reset, s->env);
2948 s->sdram_size = sdram_size;
2949 s->sram_size = JZ4740_SRAM_SIZE;
2951 /* Clocks */
2952 jz_clk_init(s, osc_extal_freq);
2954 /*map sram to 0x80000000 and sdram to 0x80004000 */
2955 sram_base = qemu_ram_alloc(s->sram_size);
2956 cpu_register_physical_memory(0x0, s->sram_size, (sram_base | IO_MEM_RAM));
2957 sdram_base = qemu_ram_alloc(s->sdram_size);
2958 cpu_register_physical_memory(JZ4740_SRAM_SIZE, s->sdram_size,
2959 (sdram_base | IO_MEM_RAM));
2961 /* Init internal devices */
2962 cpu_mips_irq_init_cpu(s->env);
2963 cpu_mips_clock_init(s->env);
2966 /* Clocks */
2967 jz_clk_init(s, osc_extal_freq);
2969 intc = jz4740_intc_init(s, s->env->irq[2]);
2970 s->cpm = jz4740_cpm_init(s);
2971 s->emc = jz4740_emc_init(s, intc[2]);
2972 s->gpio = jz4740_gpio_init(s, intc[25]);
2973 s->rtc = jz4740_rtc_init(s, intc[15]);
2974 s->tcu = jz4740_tcu_if_init(s, intc[23], intc[22], intc[21]);
2975 jz4740_tcu_init(s, s->tcu, 0);
2976 s->lcdc = jz4740_lcdc_init(s, intc[30], ds);
2977 s->dma = jz4740_dma_init(s, intc[20]);
2978 s->sadc = jz4740_sadc_init(s,intc[12]);
2980 if (serial_hds[0])
2981 serial_mm_init(0x10030000, 2, intc[9], 57600, serial_hds[0], 1);
2983 return s;