Statistics
| Branch: | Revision:

root / hw / mst_fpga.c @ cb380f61

History | View | Annotate | Download (5 kB)

1 7233b355 ths
/*
2 7233b355 ths
 * PXA270-based Intel Mainstone platforms.
3 7233b355 ths
 * FPGA driver
4 7233b355 ths
 *
5 7233b355 ths
 * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
6 7233b355 ths
 *                                    <akuster@mvista.com>
7 7233b355 ths
 *
8 7233b355 ths
 * This code is licensed under the GNU GPL v2.
9 7233b355 ths
 */
10 7233b355 ths
#include "hw.h"
11 cb380f61 Dmitry Eremin-Solenikov
#include "sysbus.h"
12 7233b355 ths
13 7233b355 ths
/* Mainstone FPGA for extern irqs */
14 7233b355 ths
#define FPGA_GPIO_PIN        0
15 7233b355 ths
#define MST_NUM_IRQS        16
16 7233b355 ths
#define MST_LEDDAT1                0x10
17 7233b355 ths
#define MST_LEDDAT2                0x14
18 7233b355 ths
#define MST_LEDCTRL                0x40
19 7233b355 ths
#define MST_GPSWR                0x60
20 7233b355 ths
#define MST_MSCWR1                0x80
21 7233b355 ths
#define MST_MSCWR2                0x84
22 7233b355 ths
#define MST_MSCWR3                0x88
23 7233b355 ths
#define MST_MSCRD                0x90
24 7233b355 ths
#define MST_INTMSKENA        0xc0
25 7233b355 ths
#define MST_INTSETCLR        0xd0
26 7233b355 ths
#define MST_PCMCIA0                0xe0
27 7233b355 ths
#define MST_PCMCIA1                0xe4
28 7233b355 ths
29 7233b355 ths
typedef struct mst_irq_state{
30 cb380f61 Dmitry Eremin-Solenikov
        SysBusDevice busdev;
31 cb380f61 Dmitry Eremin-Solenikov
32 bb70651e Dmitry Eremin-Solenikov
        qemu_irq parent;
33 7233b355 ths
34 7233b355 ths
        uint32_t prev_level;
35 7233b355 ths
        uint32_t leddat1;
36 7233b355 ths
        uint32_t leddat2;
37 7233b355 ths
        uint32_t ledctrl;
38 7233b355 ths
        uint32_t gpswr;
39 7233b355 ths
        uint32_t mscwr1;
40 7233b355 ths
        uint32_t mscwr2;
41 7233b355 ths
        uint32_t mscwr3;
42 7233b355 ths
        uint32_t mscrd;
43 7233b355 ths
        uint32_t intmskena;
44 7233b355 ths
        uint32_t intsetclr;
45 7233b355 ths
        uint32_t pcmcia0;
46 7233b355 ths
        uint32_t pcmcia1;
47 7233b355 ths
}mst_irq_state;
48 7233b355 ths
49 7233b355 ths
static void
50 7233b355 ths
mst_fpga_set_irq(void *opaque, int irq, int level)
51 7233b355 ths
{
52 7233b355 ths
        mst_irq_state *s = (mst_irq_state *)opaque;
53 43d91709 Dmitry Eremin-Solenikov
        uint32_t oldint = s->intsetclr;
54 7233b355 ths
55 7233b355 ths
        if (level)
56 7233b355 ths
                s->prev_level |= 1u << irq;
57 7233b355 ths
        else
58 7233b355 ths
                s->prev_level &= ~(1u << irq);
59 7233b355 ths
60 43d91709 Dmitry Eremin-Solenikov
        if ((s->intmskena & (1u << irq)) && level)
61 43d91709 Dmitry Eremin-Solenikov
                s->intsetclr |= 1u << irq;
62 43d91709 Dmitry Eremin-Solenikov
63 43d91709 Dmitry Eremin-Solenikov
        if (oldint != (s->intsetclr & s->intmskena))
64 43d91709 Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
65 7233b355 ths
}
66 7233b355 ths
67 7233b355 ths
68 7233b355 ths
static uint32_t
69 c227f099 Anthony Liguori
mst_fpga_readb(void *opaque, target_phys_addr_t addr)
70 7233b355 ths
{
71 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
72 7233b355 ths
73 7233b355 ths
        switch (addr) {
74 7233b355 ths
        case MST_LEDDAT1:
75 7233b355 ths
                return s->leddat1;
76 7233b355 ths
        case MST_LEDDAT2:
77 7233b355 ths
                return s->leddat2;
78 7233b355 ths
        case MST_LEDCTRL:
79 7233b355 ths
                return s->ledctrl;
80 7233b355 ths
        case MST_GPSWR:
81 7233b355 ths
                return s->gpswr;
82 7233b355 ths
        case MST_MSCWR1:
83 7233b355 ths
                return s->mscwr1;
84 7233b355 ths
        case MST_MSCWR2:
85 7233b355 ths
                return s->mscwr2;
86 7233b355 ths
        case MST_MSCWR3:
87 7233b355 ths
                return s->mscwr3;
88 7233b355 ths
        case MST_MSCRD:
89 7233b355 ths
                return s->mscrd;
90 7233b355 ths
        case MST_INTMSKENA:
91 7233b355 ths
                return s->intmskena;
92 7233b355 ths
        case MST_INTSETCLR:
93 7233b355 ths
                return s->intsetclr;
94 7233b355 ths
        case MST_PCMCIA0:
95 7233b355 ths
                return s->pcmcia0;
96 7233b355 ths
        case MST_PCMCIA1:
97 7233b355 ths
                return s->pcmcia1;
98 7233b355 ths
        default:
99 7233b355 ths
                printf("Mainstone - mst_fpga_readb: Bad register offset "
100 bb70651e Dmitry Eremin-Solenikov
                        "0x" TARGET_FMT_plx " \n", addr);
101 7233b355 ths
        }
102 7233b355 ths
        return 0;
103 7233b355 ths
}
104 7233b355 ths
105 7233b355 ths
static void
106 c227f099 Anthony Liguori
mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
107 7233b355 ths
{
108 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
109 7233b355 ths
        value &= 0xffffffff;
110 7233b355 ths
111 7233b355 ths
        switch (addr) {
112 7233b355 ths
        case MST_LEDDAT1:
113 7233b355 ths
                s->leddat1 = value;
114 7233b355 ths
                break;
115 7233b355 ths
        case MST_LEDDAT2:
116 7233b355 ths
                s->leddat2 = value;
117 7233b355 ths
                break;
118 7233b355 ths
        case MST_LEDCTRL:
119 7233b355 ths
                s->ledctrl = value;
120 7233b355 ths
                break;
121 7233b355 ths
        case MST_GPSWR:
122 7233b355 ths
                s->gpswr = value;
123 7233b355 ths
                break;
124 7233b355 ths
        case MST_MSCWR1:
125 7233b355 ths
                s->mscwr1 = value;
126 7233b355 ths
                break;
127 7233b355 ths
        case MST_MSCWR2:
128 7233b355 ths
                s->mscwr2 = value;
129 7233b355 ths
                break;
130 7233b355 ths
        case MST_MSCWR3:
131 7233b355 ths
                s->mscwr3 = value;
132 7233b355 ths
                break;
133 7233b355 ths
        case MST_MSCRD:
134 7233b355 ths
                s->mscrd =  value;
135 7233b355 ths
                break;
136 7233b355 ths
        case MST_INTMSKENA:        /* Mask interupt */
137 7233b355 ths
                s->intmskena = (value & 0xFEEFF);
138 43d91709 Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
139 7233b355 ths
                break;
140 7233b355 ths
        case MST_INTSETCLR:        /* clear or set interrupt */
141 7233b355 ths
                s->intsetclr = (value & 0xFEEFF);
142 43d91709 Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr);
143 7233b355 ths
                break;
144 7233b355 ths
        case MST_PCMCIA0:
145 7233b355 ths
                s->pcmcia0 = value;
146 7233b355 ths
                break;
147 7233b355 ths
        case MST_PCMCIA1:
148 7233b355 ths
                s->pcmcia1 = value;
149 7233b355 ths
                break;
150 7233b355 ths
        default:
151 7233b355 ths
                printf("Mainstone - mst_fpga_writeb: Bad register offset "
152 bb70651e Dmitry Eremin-Solenikov
                        "0x" TARGET_FMT_plx " \n", addr);
153 7233b355 ths
        }
154 7233b355 ths
}
155 7233b355 ths
156 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const mst_fpga_readfn[] = {
157 7233b355 ths
        mst_fpga_readb,
158 7233b355 ths
        mst_fpga_readb,
159 7233b355 ths
        mst_fpga_readb,
160 7233b355 ths
};
161 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const mst_fpga_writefn[] = {
162 7233b355 ths
        mst_fpga_writeb,
163 7233b355 ths
        mst_fpga_writeb,
164 7233b355 ths
        mst_fpga_writeb,
165 7233b355 ths
};
166 7233b355 ths
167 7233b355 ths
168 cb380f61 Dmitry Eremin-Solenikov
static int mst_fpga_post_load(void *opaque, int version_id)
169 7233b355 ths
{
170 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
171 7233b355 ths
172 43d91709 Dmitry Eremin-Solenikov
        qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
173 7233b355 ths
        return 0;
174 7233b355 ths
}
175 7233b355 ths
176 cb380f61 Dmitry Eremin-Solenikov
static int mst_fpga_init(SysBusDevice *dev)
177 7233b355 ths
{
178 7233b355 ths
        mst_irq_state *s;
179 7233b355 ths
        int iomemtype;
180 7233b355 ths
181 cb380f61 Dmitry Eremin-Solenikov
        s = FROM_SYSBUS(mst_irq_state, dev);
182 7233b355 ths
183 cb380f61 Dmitry Eremin-Solenikov
        sysbus_init_irq(dev, &s->parent);
184 7233b355 ths
185 7233b355 ths
        /* alloc the external 16 irqs */
186 cb380f61 Dmitry Eremin-Solenikov
        qdev_init_gpio_in(&dev->qdev, mst_fpga_set_irq, MST_NUM_IRQS);
187 7233b355 ths
188 1eed09cb Avi Kivity
        iomemtype = cpu_register_io_memory(mst_fpga_readfn,
189 2507c12a Alexander Graf
                mst_fpga_writefn, s, DEVICE_NATIVE_ENDIAN);
190 cb380f61 Dmitry Eremin-Solenikov
        sysbus_init_mmio(dev, 0x00100000, iomemtype);
191 cb380f61 Dmitry Eremin-Solenikov
        return 0;
192 cb380f61 Dmitry Eremin-Solenikov
}
193 cb380f61 Dmitry Eremin-Solenikov
194 cb380f61 Dmitry Eremin-Solenikov
static VMStateDescription vmstate_mst_fpga_regs = {
195 cb380f61 Dmitry Eremin-Solenikov
        .name = "mainstone_fpga",
196 cb380f61 Dmitry Eremin-Solenikov
        .version_id = 0,
197 cb380f61 Dmitry Eremin-Solenikov
        .minimum_version_id = 0,
198 cb380f61 Dmitry Eremin-Solenikov
        .minimum_version_id_old = 0,
199 cb380f61 Dmitry Eremin-Solenikov
        .post_load = mst_fpga_post_load,
200 cb380f61 Dmitry Eremin-Solenikov
        .fields = (VMStateField []) {
201 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(prev_level, mst_irq_state),
202 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(leddat1, mst_irq_state),
203 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(leddat2, mst_irq_state),
204 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(ledctrl, mst_irq_state),
205 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(gpswr, mst_irq_state),
206 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr1, mst_irq_state),
207 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr2, mst_irq_state),
208 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr3, mst_irq_state),
209 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscrd, mst_irq_state),
210 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(intmskena, mst_irq_state),
211 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(intsetclr, mst_irq_state),
212 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(pcmcia0, mst_irq_state),
213 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(pcmcia1, mst_irq_state),
214 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_END_OF_LIST(),
215 cb380f61 Dmitry Eremin-Solenikov
        },
216 cb380f61 Dmitry Eremin-Solenikov
};
217 cb380f61 Dmitry Eremin-Solenikov
218 cb380f61 Dmitry Eremin-Solenikov
static SysBusDeviceInfo mst_fpga_info = {
219 cb380f61 Dmitry Eremin-Solenikov
        .init = mst_fpga_init,
220 cb380f61 Dmitry Eremin-Solenikov
        .qdev.name = "mainstone-fpga",
221 cb380f61 Dmitry Eremin-Solenikov
        .qdev.desc = "Mainstone II FPGA",
222 cb380f61 Dmitry Eremin-Solenikov
        .qdev.size = sizeof(mst_irq_state),
223 cb380f61 Dmitry Eremin-Solenikov
        .qdev.vmsd = &vmstate_mst_fpga_regs,
224 cb380f61 Dmitry Eremin-Solenikov
};
225 cb380f61 Dmitry Eremin-Solenikov
226 cb380f61 Dmitry Eremin-Solenikov
static void mst_fpga_register(void)
227 cb380f61 Dmitry Eremin-Solenikov
{
228 cb380f61 Dmitry Eremin-Solenikov
        sysbus_register_withprop(&mst_fpga_info);
229 7233b355 ths
}
230 cb380f61 Dmitry Eremin-Solenikov
device_init(mst_fpga_register);