Commit 88d2c950b002a3976cd5673b0214006e72cae191

Authored by balrog
1 parent c8256f9d

TC6393XB system features (Dmitry Baryshkov).

Add basic support for TC6393XB system features. No support for GPIO
input though.

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4702 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -585,7 +585,7 @@ OBJS+= arm-semi.o
585 585 OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
586 586 OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
587 587 OBJS+= pflash_cfi01.o gumstix.o
588   -OBJS+= zaurus.o ide.o serial.o nand.o ecc.o spitz.o tosa.o
  588 +OBJS+= zaurus.o ide.o serial.o nand.o ecc.o spitz.o tosa.o tc6393xb.o
589 589 OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
590 590 OBJS+= omap2.o omap_dss.o
591 591 OBJS+= palm.o tsc210x.o
... ...
hw/devices.h
... ... @@ -64,4 +64,11 @@ int tusb6010_sync_io(struct tusb_s *s);
64 64 int tusb6010_async_io(struct tusb_s *s);
65 65 void tusb6010_power(struct tusb_s *s, int on);
66 66  
  67 +/* tc6393xb.c */
  68 +struct tc6393xb_s;
  69 +struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq);
  70 +void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line,
  71 + qemu_irq handler);
  72 +qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s);
  73 +
67 74 #endif
... ...
hw/tc6393xb.c 0 → 100644
  1 +/* vim:set shiftwidth=4 ts=4 et: */
  2 +#include "hw.h"
  3 +#include "pxa.h"
  4 +#include "devices.h"
  5 +
  6 +#define TC6393XB_GPIOS 16
  7 +
  8 +#define SCR_REVID 0x08 /* b Revision ID */
  9 +#define SCR_ISR 0x50 /* b Interrupt Status */
  10 +#define SCR_IMR 0x52 /* b Interrupt Mask */
  11 +#define SCR_IRR 0x54 /* b Interrupt Routing */
  12 +#define SCR_GPER 0x60 /* w GP Enable */
  13 +#define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */
  14 +#define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */
  15 +#define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */
  16 +#define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */
  17 +#define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */
  18 +#define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */
  19 +#define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */
  20 +#define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */
  21 +#define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */
  22 +#define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */
  23 +#define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */
  24 +#define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */
  25 +#define SCR_CCR 0x98 /* w Clock Control */
  26 +#define SCR_PLL2CR 0x9a /* w PLL2 Control */
  27 +#define SCR_PLL1CR 0x9c /* l PLL1 Control */
  28 +#define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */
  29 +#define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */
  30 +#define SCR_FER 0xe0 /* b Function Enable */
  31 +#define SCR_MCR 0xe4 /* w Mode Control */
  32 +#define SCR_CONFIG 0xfc /* b Configuration Control */
  33 +#define SCR_DEBUG 0xff /* b Debug */
  34 +
  35 +struct tc6393xb_s {
  36 + target_phys_addr_t target_base;
  37 + struct {
  38 + uint8_t ISR;
  39 + uint8_t IMR;
  40 + uint8_t IRR;
  41 + uint16_t GPER;
  42 + uint8_t GPI_SR[3];
  43 + uint8_t GPI_IMR[3];
  44 + uint8_t GPI_EDER[3];
  45 + uint8_t GPI_LIR[3];
  46 + uint8_t GP_IARCR[3];
  47 + uint8_t GP_IARLCR[3];
  48 + uint8_t GPI_BCR[3];
  49 + uint16_t GPA_IARCR;
  50 + uint16_t GPA_IARLCR;
  51 + uint16_t CCR;
  52 + uint16_t PLL2CR;
  53 + uint32_t PLL1CR;
  54 + uint8_t DIARCR;
  55 + uint8_t DBOCR;
  56 + uint8_t FER;
  57 + uint16_t MCR;
  58 + uint8_t CONFIG;
  59 + uint8_t DEBUG;
  60 + } scr;
  61 + uint32_t gpio_dir;
  62 + uint32_t gpio_level;
  63 + uint32_t prev_level;
  64 + qemu_irq handler[TC6393XB_GPIOS];
  65 + qemu_irq *gpio_in;
  66 +};
  67 +
  68 +qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s)
  69 +{
  70 + return s->gpio_in;
  71 +}
  72 +
  73 +static void tc6393xb_gpio_set(void *opaque, int line, int level)
  74 +{
  75 +// struct tc6393xb_s *s = opaque;
  76 +
  77 + if (line > TC6393XB_GPIOS) {
  78 + printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
  79 + return;
  80 + }
  81 +
  82 + // FIXME: how does the chip reflect the GPIO input level change?
  83 +}
  84 +
  85 +void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line,
  86 + qemu_irq handler)
  87 +{
  88 + if (line >= TC6393XB_GPIOS) {
  89 + fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
  90 + return;
  91 + }
  92 +
  93 + s->handler[line] = handler;
  94 +}
  95 +
  96 +static void tc6393xb_gpio_handler_update(struct tc6393xb_s *s)
  97 +{
  98 + uint32_t level, diff;
  99 + int bit;
  100 +
  101 + level = s->gpio_level & s->gpio_dir;
  102 +
  103 + for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
  104 + bit = ffs(diff) - 1;
  105 + qemu_set_irq(s->handler[bit], (level >> bit) & 1);
  106 + }
  107 +
  108 + s->prev_level = level;
  109 +}
  110 +
  111 +#define SCR_REG_B(N) \
  112 + case SCR_ ##N: return s->scr.N
  113 +#define SCR_REG_W(N) \
  114 + case SCR_ ##N: return s->scr.N; \
  115 + case SCR_ ##N + 1: return s->scr.N >> 8;
  116 +#define SCR_REG_L(N) \
  117 + case SCR_ ##N: return s->scr.N; \
  118 + case SCR_ ##N + 1: return s->scr.N >> 8; \
  119 + case SCR_ ##N + 2: return s->scr.N >> 16; \
  120 + case SCR_ ##N + 3: return s->scr.N >> 24;
  121 +#define SCR_REG_A(N) \
  122 + case SCR_ ##N(0): return s->scr.N[0]; \
  123 + case SCR_ ##N(1): return s->scr.N[1]; \
  124 + case SCR_ ##N(2): return s->scr.N[2]
  125 +
  126 +static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr)
  127 +{
  128 + struct tc6393xb_s *s = opaque;
  129 + addr -= s->target_base;
  130 + switch (addr) {
  131 + case SCR_REVID:
  132 + return 3;
  133 + case SCR_REVID+1:
  134 + return 0;
  135 + SCR_REG_B(ISR);
  136 + SCR_REG_B(IMR);
  137 + SCR_REG_B(IRR);
  138 + SCR_REG_W(GPER);
  139 + SCR_REG_A(GPI_SR);
  140 + SCR_REG_A(GPI_IMR);
  141 + SCR_REG_A(GPI_EDER);
  142 + SCR_REG_A(GPI_LIR);
  143 + case SCR_GPO_DSR(0):
  144 + case SCR_GPO_DSR(1):
  145 + case SCR_GPO_DSR(2):
  146 + return (s->gpio_level >> ((addr - SCR_GPO_DSR(0)) * 8)) & 0xff;
  147 + case SCR_GPO_DOECR(0):
  148 + case SCR_GPO_DOECR(1):
  149 + case SCR_GPO_DOECR(2):
  150 + return (s->gpio_dir >> ((addr - SCR_GPO_DOECR(0)) * 8)) & 0xff;
  151 + SCR_REG_A(GP_IARCR);
  152 + SCR_REG_A(GP_IARLCR);
  153 + SCR_REG_A(GPI_BCR);
  154 + SCR_REG_W(GPA_IARCR);
  155 + SCR_REG_W(GPA_IARLCR);
  156 + SCR_REG_W(CCR);
  157 + SCR_REG_W(PLL2CR);
  158 + SCR_REG_L(PLL1CR);
  159 + SCR_REG_B(DIARCR);
  160 + SCR_REG_B(DBOCR);
  161 + SCR_REG_B(FER);
  162 + SCR_REG_W(MCR);
  163 + SCR_REG_B(CONFIG);
  164 + SCR_REG_B(DEBUG);
  165 + }
  166 + fprintf(stderr, "tc6393xb: unhandled read at %08x\n", (uint32_t) addr);
  167 + return 0;
  168 +}
  169 +#undef SCR_REG_B
  170 +#undef SCR_REG_W
  171 +#undef SCR_REG_L
  172 +#undef SCR_REG_A
  173 +
  174 +#define SCR_REG_B(N) \
  175 + case SCR_ ##N: s->scr.N = value; break;
  176 +#define SCR_REG_W(N) \
  177 + case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); break; \
  178 + case SCR_ ##N + 1: s->scr.N = (s->scr.N & 0xff) | (value << 8); break
  179 +#define SCR_REG_L(N) \
  180 + case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); break; \
  181 + case SCR_ ##N + 1: s->scr.N = (s->scr.N & ~(0xff << 8)) | (value & (0xff << 8)); break; \
  182 + case SCR_ ##N + 2: s->scr.N = (s->scr.N & ~(0xff << 16)) | (value & (0xff << 16)); break; \
  183 + case SCR_ ##N + 3: s->scr.N = (s->scr.N & ~(0xff << 24)) | (value & (0xff << 24)); break;
  184 +#define SCR_REG_A(N) \
  185 + case SCR_ ##N(0): s->scr.N[0] = value; break; \
  186 + case SCR_ ##N(1): s->scr.N[1] = value; break; \
  187 + case SCR_ ##N(2): s->scr.N[2] = value; break
  188 +
  189 +static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
  190 +{
  191 + struct tc6393xb_s *s = opaque;
  192 + addr -= s->target_base;
  193 + switch (addr) {
  194 + SCR_REG_B(ISR);
  195 + SCR_REG_B(IMR);
  196 + SCR_REG_B(IRR);
  197 + SCR_REG_W(GPER);
  198 + SCR_REG_A(GPI_SR);
  199 + SCR_REG_A(GPI_IMR);
  200 + SCR_REG_A(GPI_EDER);
  201 + SCR_REG_A(GPI_LIR);
  202 + case SCR_GPO_DSR(0):
  203 + case SCR_GPO_DSR(1):
  204 + case SCR_GPO_DSR(2):
  205 + s->gpio_level = (s->gpio_level & ~(0xff << ((addr - SCR_GPO_DSR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DSR(0))*8));
  206 + tc6393xb_gpio_handler_update(s);
  207 + break;
  208 + case SCR_GPO_DOECR(0):
  209 + case SCR_GPO_DOECR(1):
  210 + case SCR_GPO_DOECR(2):
  211 + s->gpio_dir = (s->gpio_dir & ~(0xff << ((addr - SCR_GPO_DOECR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DOECR(0))*8));
  212 + tc6393xb_gpio_handler_update(s);
  213 + break;
  214 + SCR_REG_A(GP_IARCR);
  215 + SCR_REG_A(GP_IARLCR);
  216 + SCR_REG_A(GPI_BCR);
  217 + SCR_REG_W(GPA_IARCR);
  218 + SCR_REG_W(GPA_IARLCR);
  219 + SCR_REG_W(CCR);
  220 + SCR_REG_W(PLL2CR);
  221 + SCR_REG_L(PLL1CR);
  222 + SCR_REG_B(DIARCR);
  223 + SCR_REG_B(DBOCR);
  224 + SCR_REG_B(FER);
  225 + SCR_REG_W(MCR);
  226 + SCR_REG_B(CONFIG);
  227 + SCR_REG_B(DEBUG);
  228 + default:
  229 + fprintf(stderr, "tc6393xb: unhandled write at %08x: %02x\n",
  230 + (uint32_t) addr, value & 0xff);
  231 + break;
  232 + }
  233 +}
  234 +#undef SCR_REG_B
  235 +#undef SCR_REG_W
  236 +#undef SCR_REG_L
  237 +#undef SCR_REG_A
  238 +
  239 +static uint32_t tc6393xb_readw(void *opaque, target_phys_addr_t addr)
  240 +{
  241 + return (tc6393xb_readb(opaque, addr) & 0xff) |
  242 + (tc6393xb_readb(opaque, addr + 1) << 8);
  243 +}
  244 +
  245 +static uint32_t tc6393xb_readl(void *opaque, target_phys_addr_t addr)
  246 +{
  247 + return (tc6393xb_readb(opaque, addr) & 0xff) |
  248 + ((tc6393xb_readb(opaque, addr + 1) & 0xff) << 8) |
  249 + ((tc6393xb_readb(opaque, addr + 2) & 0xff) << 16) |
  250 + ((tc6393xb_readb(opaque, addr + 3) & 0xff) << 24);
  251 +}
  252 +
  253 +static void tc6393xb_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
  254 +{
  255 + tc6393xb_writeb(opaque, addr, value);
  256 + tc6393xb_writeb(opaque, addr + 1, value >> 8);
  257 +}
  258 +
  259 +static void tc6393xb_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
  260 +{
  261 + tc6393xb_writeb(opaque, addr, value);
  262 + tc6393xb_writeb(opaque, addr + 1, value >> 8);
  263 + tc6393xb_writeb(opaque, addr + 2, value >> 16);
  264 + tc6393xb_writeb(opaque, addr + 3, value >> 24);
  265 +}
  266 +
  267 +struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq)
  268 +{
  269 + int iomemtype;
  270 + struct tc6393xb_s *s;
  271 + CPUReadMemoryFunc *tc6393xb_readfn[] = {
  272 + tc6393xb_readb,
  273 + tc6393xb_readw,
  274 + tc6393xb_readl,
  275 + };
  276 + CPUWriteMemoryFunc *tc6393xb_writefn[] = {
  277 + tc6393xb_writeb,
  278 + tc6393xb_writew,
  279 + tc6393xb_writel,
  280 + };
  281 +
  282 + s = (struct tc6393xb_s *) qemu_mallocz(sizeof(struct tc6393xb_s));
  283 + s->target_base = base;
  284 + s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS);
  285 +
  286 + iomemtype = cpu_register_io_memory(0, tc6393xb_readfn,
  287 + tc6393xb_writefn, s);
  288 + cpu_register_physical_memory(s->target_base, 0x200000, iomemtype);
  289 +
  290 + return s;
  291 +}
... ...
hw/tosa.c
... ... @@ -12,6 +12,7 @@
12 12 #include "pxa.h"
13 13 #include "arm-misc.h"
14 14 #include "sysemu.h"
  15 +#include "devices.h"
15 16 #include "sharpsl.h"
16 17 #include "pcmcia.h"
17 18 #include "block.h"
... ... @@ -31,41 +32,6 @@
31 32 #define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3)
32 33 #define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4)
33 34  
34   -struct tc6393xb_s {
35   - target_phys_addr_t target_base;
36   -};
37   -
38   -static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr)
39   -{
40   - return 3;
41   -}
42   -static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr,
43   - uint32_t value)
44   -{
45   -}
46   -static void tosa_tc6393xb_register(struct pxa2xx_state_s *cpu)
47   -{
48   - int iomemtype;
49   - struct tc6393xb_s *s;
50   - CPUReadMemoryFunc *tc6393xb_readfn[] = {
51   - tc6393xb_readb,
52   - tc6393xb_readb,
53   - tc6393xb_readb,
54   - };
55   - CPUWriteMemoryFunc *tc6393xb_writefn[] = {
56   - tc6393xb_writeb,
57   - tc6393xb_writeb,
58   - tc6393xb_writeb,
59   - };
60   -
61   - s = (struct tc6393xb_s *) qemu_mallocz(sizeof(struct tc6393xb_s));
62   - s->target_base = 0x10000000;
63   -
64   - iomemtype = cpu_register_io_memory(0, tc6393xb_readfn,
65   - tc6393xb_writefn, s);
66   - cpu_register_physical_memory(s->target_base, 0x200000, iomemtype);
67   -}
68   -
69 35 static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu)
70 36 {
71 37 struct pcmcia_card_s *md;
... ... @@ -132,7 +98,7 @@ static void tosa_init(ram_addr_t ram_size, int vga_ram_size,
132 98 cpu_register_physical_memory(0, TOSA_ROM,
133 99 qemu_ram_alloc(TOSA_ROM) | IO_MEM_ROM);
134 100  
135   - tosa_tc6393xb_register(cpu);
  101 + tc6393xb_init(0x10000000, NULL);
136 102  
137 103 scp0 = scoop_init(cpu, 0, 0x08800000);
138 104 scp1 = scoop_init(cpu, 1, 0x14800040);
... ...