symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/mst_fpga.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * PXA270-based Intel Mainstone platforms.
       
     3  * FPGA driver
       
     4  *
       
     5  * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
       
     6  *                                    <akuster@mvista.com>
       
     7  *
       
     8  * This code is licensed under the GNU GPL v2.
       
     9  */
       
    10 #include "hw.h"
       
    11 #include "pxa.h"
       
    12 #include "mainstone.h"
       
    13 
       
    14 /* Mainstone FPGA for extern irqs */
       
    15 #define FPGA_GPIO_PIN	0
       
    16 #define MST_NUM_IRQS	16
       
    17 #define MST_LEDDAT1		0x10
       
    18 #define MST_LEDDAT2		0x14
       
    19 #define MST_LEDCTRL		0x40
       
    20 #define MST_GPSWR		0x60
       
    21 #define MST_MSCWR1		0x80
       
    22 #define MST_MSCWR2		0x84
       
    23 #define MST_MSCWR3		0x88
       
    24 #define MST_MSCRD		0x90
       
    25 #define MST_INTMSKENA	0xc0
       
    26 #define MST_INTSETCLR	0xd0
       
    27 #define MST_PCMCIA0		0xe0
       
    28 #define MST_PCMCIA1		0xe4
       
    29 
       
    30 typedef struct mst_irq_state{
       
    31 	qemu_irq *parent;
       
    32 	qemu_irq *pins;
       
    33 
       
    34 	uint32_t prev_level;
       
    35 	uint32_t leddat1;
       
    36 	uint32_t leddat2;
       
    37 	uint32_t ledctrl;
       
    38 	uint32_t gpswr;
       
    39 	uint32_t mscwr1;
       
    40 	uint32_t mscwr2;
       
    41 	uint32_t mscwr3;
       
    42 	uint32_t mscrd;
       
    43 	uint32_t intmskena;
       
    44 	uint32_t intsetclr;
       
    45 	uint32_t pcmcia0;
       
    46 	uint32_t pcmcia1;
       
    47 }mst_irq_state;
       
    48 
       
    49 static void
       
    50 mst_fpga_update_gpio(mst_irq_state *s)
       
    51 {
       
    52 	uint32_t level, diff;
       
    53 	int bit;
       
    54 	level = s->prev_level ^ s->intsetclr;
       
    55 
       
    56 	for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
       
    57 		bit = ffs(diff) - 1;
       
    58 		qemu_set_irq(s->pins[bit], (level >> bit) & 1 );
       
    59 	}
       
    60 	s->prev_level = level;
       
    61 }
       
    62 
       
    63 static void
       
    64 mst_fpga_set_irq(void *opaque, int irq, int level)
       
    65 {
       
    66 	mst_irq_state *s = (mst_irq_state *)opaque;
       
    67 
       
    68 	if (level)
       
    69 		s->prev_level |= 1u << irq;
       
    70 	else
       
    71 		s->prev_level &= ~(1u << irq);
       
    72 
       
    73 	if(s->intmskena & (1u << irq)) {
       
    74 		s->intsetclr = 1u << irq;
       
    75 		qemu_set_irq(s->parent[0], level);
       
    76 	}
       
    77 }
       
    78 
       
    79 
       
    80 static uint32_t
       
    81 mst_fpga_readb(void *opaque, target_phys_addr_t addr)
       
    82 {
       
    83 	mst_irq_state *s = (mst_irq_state *) opaque;
       
    84 
       
    85 	switch (addr) {
       
    86 	case MST_LEDDAT1:
       
    87 		return s->leddat1;
       
    88 	case MST_LEDDAT2:
       
    89 		return s->leddat2;
       
    90 	case MST_LEDCTRL:
       
    91 		return s->ledctrl;
       
    92 	case MST_GPSWR:
       
    93 		return s->gpswr;
       
    94 	case MST_MSCWR1:
       
    95 		return s->mscwr1;
       
    96 	case MST_MSCWR2:
       
    97 		return s->mscwr2;
       
    98 	case MST_MSCWR3:
       
    99 		return s->mscwr3;
       
   100 	case MST_MSCRD:
       
   101 		return s->mscrd;
       
   102 	case MST_INTMSKENA:
       
   103 		return s->intmskena;
       
   104 	case MST_INTSETCLR:
       
   105 		return s->intsetclr;
       
   106 	case MST_PCMCIA0:
       
   107 		return s->pcmcia0;
       
   108 	case MST_PCMCIA1:
       
   109 		return s->pcmcia1;
       
   110 	default:
       
   111 		printf("Mainstone - mst_fpga_readb: Bad register offset "
       
   112 			REG_FMT " \n", addr);
       
   113 	}
       
   114 	return 0;
       
   115 }
       
   116 
       
   117 static void
       
   118 mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
       
   119 {
       
   120 	mst_irq_state *s = (mst_irq_state *) opaque;
       
   121 	value &= 0xffffffff;
       
   122 
       
   123 	switch (addr) {
       
   124 	case MST_LEDDAT1:
       
   125 		s->leddat1 = value;
       
   126 		break;
       
   127 	case MST_LEDDAT2:
       
   128 		s->leddat2 = value;
       
   129 		break;
       
   130 	case MST_LEDCTRL:
       
   131 		s->ledctrl = value;
       
   132 		break;
       
   133 	case MST_GPSWR:
       
   134 		s->gpswr = value;
       
   135 		break;
       
   136 	case MST_MSCWR1:
       
   137 		s->mscwr1 = value;
       
   138 		break;
       
   139 	case MST_MSCWR2:
       
   140 		s->mscwr2 = value;
       
   141 		break;
       
   142 	case MST_MSCWR3:
       
   143 		s->mscwr3 = value;
       
   144 		break;
       
   145 	case MST_MSCRD:
       
   146 		s->mscrd =  value;
       
   147 		break;
       
   148 	case MST_INTMSKENA:	/* Mask interupt */
       
   149 		s->intmskena = (value & 0xFEEFF);
       
   150 		mst_fpga_update_gpio(s);
       
   151 		break;
       
   152 	case MST_INTSETCLR:	/* clear or set interrupt */
       
   153 		s->intsetclr = (value & 0xFEEFF);
       
   154 		break;
       
   155 	case MST_PCMCIA0:
       
   156 		s->pcmcia0 = value;
       
   157 		break;
       
   158 	case MST_PCMCIA1:
       
   159 		s->pcmcia1 = value;
       
   160 		break;
       
   161 	default:
       
   162 		printf("Mainstone - mst_fpga_writeb: Bad register offset "
       
   163 			REG_FMT " \n", addr);
       
   164 	}
       
   165 }
       
   166 
       
   167 static CPUReadMemoryFunc *mst_fpga_readfn[] = {
       
   168 	mst_fpga_readb,
       
   169 	mst_fpga_readb,
       
   170 	mst_fpga_readb,
       
   171 };
       
   172 static CPUWriteMemoryFunc *mst_fpga_writefn[] = {
       
   173 	mst_fpga_writeb,
       
   174 	mst_fpga_writeb,
       
   175 	mst_fpga_writeb,
       
   176 };
       
   177 
       
   178 static void
       
   179 mst_fpga_save(QEMUFile *f, void *opaque)
       
   180 {
       
   181 	struct mst_irq_state *s = (mst_irq_state *) opaque;
       
   182 
       
   183 	qemu_put_be32s(f, &s->prev_level);
       
   184 	qemu_put_be32s(f, &s->leddat1);
       
   185 	qemu_put_be32s(f, &s->leddat2);
       
   186 	qemu_put_be32s(f, &s->ledctrl);
       
   187 	qemu_put_be32s(f, &s->gpswr);
       
   188 	qemu_put_be32s(f, &s->mscwr1);
       
   189 	qemu_put_be32s(f, &s->mscwr2);
       
   190 	qemu_put_be32s(f, &s->mscwr3);
       
   191 	qemu_put_be32s(f, &s->mscrd);
       
   192 	qemu_put_be32s(f, &s->intmskena);
       
   193 	qemu_put_be32s(f, &s->intsetclr);
       
   194 	qemu_put_be32s(f, &s->pcmcia0);
       
   195 	qemu_put_be32s(f, &s->pcmcia1);
       
   196 }
       
   197 
       
   198 static int
       
   199 mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
       
   200 {
       
   201 	mst_irq_state *s = (mst_irq_state *) opaque;
       
   202 
       
   203 	qemu_get_be32s(f, &s->prev_level);
       
   204 	qemu_get_be32s(f, &s->leddat1);
       
   205 	qemu_get_be32s(f, &s->leddat2);
       
   206 	qemu_get_be32s(f, &s->ledctrl);
       
   207 	qemu_get_be32s(f, &s->gpswr);
       
   208 	qemu_get_be32s(f, &s->mscwr1);
       
   209 	qemu_get_be32s(f, &s->mscwr2);
       
   210 	qemu_get_be32s(f, &s->mscwr3);
       
   211 	qemu_get_be32s(f, &s->mscrd);
       
   212 	qemu_get_be32s(f, &s->intmskena);
       
   213 	qemu_get_be32s(f, &s->intsetclr);
       
   214 	qemu_get_be32s(f, &s->pcmcia0);
       
   215 	qemu_get_be32s(f, &s->pcmcia1);
       
   216 	return 0;
       
   217 }
       
   218 
       
   219 qemu_irq *mst_irq_init(struct pxa2xx_state_s *cpu, uint32_t base, int irq)
       
   220 {
       
   221 	mst_irq_state *s;
       
   222 	int iomemtype;
       
   223 	qemu_irq *qi;
       
   224 
       
   225 	s = (mst_irq_state  *)
       
   226 		qemu_mallocz(sizeof(mst_irq_state));
       
   227 
       
   228 	if (!s)
       
   229 		return NULL;
       
   230 	s->parent = &cpu->pic[irq];
       
   231 
       
   232 	/* alloc the external 16 irqs */
       
   233 	qi  = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
       
   234 	s->pins = qi;
       
   235 
       
   236 	iomemtype = cpu_register_io_memory(0, mst_fpga_readfn,
       
   237 		mst_fpga_writefn, s);
       
   238 	cpu_register_physical_memory(base, 0x00100000, iomemtype);
       
   239 	register_savevm("mainstone_fpga", 0, 0, mst_fpga_save, mst_fpga_load, s);
       
   240 	return qi;
       
   241 }