Statistics
| Branch: | Revision:

root / hw / misc / mst_fpga.c @ e3914e3a

History | View | Annotate | Download (6 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 6b620ca3 Paolo Bonzini
 *
10 6b620ca3 Paolo Bonzini
 * Contributions after 2012-01-13 are licensed under the terms of the
11 6b620ca3 Paolo Bonzini
 * GNU GPL, version 2 or (at your option) any later version.
12 7233b355 ths
 */
13 83c9f4ca Paolo Bonzini
#include "hw/hw.h"
14 83c9f4ca Paolo Bonzini
#include "hw/sysbus.h"
15 7233b355 ths
16 7233b355 ths
/* Mainstone FPGA for extern irqs */
17 7233b355 ths
#define FPGA_GPIO_PIN        0
18 7233b355 ths
#define MST_NUM_IRQS        16
19 7233b355 ths
#define MST_LEDDAT1                0x10
20 7233b355 ths
#define MST_LEDDAT2                0x14
21 7233b355 ths
#define MST_LEDCTRL                0x40
22 7233b355 ths
#define MST_GPSWR                0x60
23 7233b355 ths
#define MST_MSCWR1                0x80
24 7233b355 ths
#define MST_MSCWR2                0x84
25 7233b355 ths
#define MST_MSCWR3                0x88
26 7233b355 ths
#define MST_MSCRD                0x90
27 7233b355 ths
#define MST_INTMSKENA        0xc0
28 7233b355 ths
#define MST_INTSETCLR        0xd0
29 7233b355 ths
#define MST_PCMCIA0                0xe0
30 7233b355 ths
#define MST_PCMCIA1                0xe4
31 7233b355 ths
32 b651fc6f Dmitry Eremin-Solenikov
#define MST_PCMCIAx_READY        (1 << 10)
33 b651fc6f Dmitry Eremin-Solenikov
#define MST_PCMCIAx_nCD                (1 << 5)
34 b651fc6f Dmitry Eremin-Solenikov
35 b651fc6f Dmitry Eremin-Solenikov
#define MST_PCMCIA_CD0_IRQ        9
36 b651fc6f Dmitry Eremin-Solenikov
#define MST_PCMCIA_CD1_IRQ        13
37 b651fc6f Dmitry Eremin-Solenikov
38 7233b355 ths
typedef struct mst_irq_state{
39 cb380f61 Dmitry Eremin-Solenikov
        SysBusDevice busdev;
40 b9441ebb Benoît Canet
        MemoryRegion iomem;
41 cb380f61 Dmitry Eremin-Solenikov
42 bb70651e Dmitry Eremin-Solenikov
        qemu_irq parent;
43 7233b355 ths
44 7233b355 ths
        uint32_t prev_level;
45 7233b355 ths
        uint32_t leddat1;
46 7233b355 ths
        uint32_t leddat2;
47 7233b355 ths
        uint32_t ledctrl;
48 7233b355 ths
        uint32_t gpswr;
49 7233b355 ths
        uint32_t mscwr1;
50 7233b355 ths
        uint32_t mscwr2;
51 7233b355 ths
        uint32_t mscwr3;
52 7233b355 ths
        uint32_t mscrd;
53 7233b355 ths
        uint32_t intmskena;
54 7233b355 ths
        uint32_t intsetclr;
55 7233b355 ths
        uint32_t pcmcia0;
56 7233b355 ths
        uint32_t pcmcia1;
57 7233b355 ths
}mst_irq_state;
58 7233b355 ths
59 7233b355 ths
static void
60 7233b355 ths
mst_fpga_set_irq(void *opaque, int irq, int level)
61 7233b355 ths
{
62 7233b355 ths
        mst_irq_state *s = (mst_irq_state *)opaque;
63 3e1dbc3b Dmitry Eremin-Solenikov
        uint32_t oldint = s->intsetclr & s->intmskena;
64 7233b355 ths
65 7233b355 ths
        if (level)
66 7233b355 ths
                s->prev_level |= 1u << irq;
67 7233b355 ths
        else
68 7233b355 ths
                s->prev_level &= ~(1u << irq);
69 7233b355 ths
70 b651fc6f Dmitry Eremin-Solenikov
        switch(irq) {
71 b651fc6f Dmitry Eremin-Solenikov
        case MST_PCMCIA_CD0_IRQ:
72 b651fc6f Dmitry Eremin-Solenikov
                if (level)
73 b651fc6f Dmitry Eremin-Solenikov
                        s->pcmcia0 &= ~MST_PCMCIAx_nCD;
74 b651fc6f Dmitry Eremin-Solenikov
                else
75 b651fc6f Dmitry Eremin-Solenikov
                        s->pcmcia0 |=  MST_PCMCIAx_nCD;
76 b651fc6f Dmitry Eremin-Solenikov
                break;
77 b651fc6f Dmitry Eremin-Solenikov
        case MST_PCMCIA_CD1_IRQ:
78 b651fc6f Dmitry Eremin-Solenikov
                if (level)
79 b651fc6f Dmitry Eremin-Solenikov
                        s->pcmcia1 &= ~MST_PCMCIAx_nCD;
80 b651fc6f Dmitry Eremin-Solenikov
                else
81 b651fc6f Dmitry Eremin-Solenikov
                        s->pcmcia1 |=  MST_PCMCIAx_nCD;
82 b651fc6f Dmitry Eremin-Solenikov
                break;
83 b651fc6f Dmitry Eremin-Solenikov
        }
84 b651fc6f Dmitry Eremin-Solenikov
85 43d91709 Dmitry Eremin-Solenikov
        if ((s->intmskena & (1u << irq)) && level)
86 43d91709 Dmitry Eremin-Solenikov
                s->intsetclr |= 1u << irq;
87 43d91709 Dmitry Eremin-Solenikov
88 43d91709 Dmitry Eremin-Solenikov
        if (oldint != (s->intsetclr & s->intmskena))
89 43d91709 Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
90 7233b355 ths
}
91 7233b355 ths
92 7233b355 ths
93 b9441ebb Benoît Canet
static uint64_t
94 a8170e5e Avi Kivity
mst_fpga_readb(void *opaque, hwaddr addr, unsigned size)
95 7233b355 ths
{
96 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
97 7233b355 ths
98 7233b355 ths
        switch (addr) {
99 7233b355 ths
        case MST_LEDDAT1:
100 7233b355 ths
                return s->leddat1;
101 7233b355 ths
        case MST_LEDDAT2:
102 7233b355 ths
                return s->leddat2;
103 7233b355 ths
        case MST_LEDCTRL:
104 7233b355 ths
                return s->ledctrl;
105 7233b355 ths
        case MST_GPSWR:
106 7233b355 ths
                return s->gpswr;
107 7233b355 ths
        case MST_MSCWR1:
108 7233b355 ths
                return s->mscwr1;
109 7233b355 ths
        case MST_MSCWR2:
110 7233b355 ths
                return s->mscwr2;
111 7233b355 ths
        case MST_MSCWR3:
112 7233b355 ths
                return s->mscwr3;
113 7233b355 ths
        case MST_MSCRD:
114 7233b355 ths
                return s->mscrd;
115 7233b355 ths
        case MST_INTMSKENA:
116 7233b355 ths
                return s->intmskena;
117 7233b355 ths
        case MST_INTSETCLR:
118 7233b355 ths
                return s->intsetclr;
119 7233b355 ths
        case MST_PCMCIA0:
120 7233b355 ths
                return s->pcmcia0;
121 7233b355 ths
        case MST_PCMCIA1:
122 7233b355 ths
                return s->pcmcia1;
123 7233b355 ths
        default:
124 7233b355 ths
                printf("Mainstone - mst_fpga_readb: Bad register offset "
125 b2bedb21 Stefan Weil
                        "0x" TARGET_FMT_plx "\n", addr);
126 7233b355 ths
        }
127 7233b355 ths
        return 0;
128 7233b355 ths
}
129 7233b355 ths
130 7233b355 ths
static void
131 a8170e5e Avi Kivity
mst_fpga_writeb(void *opaque, hwaddr addr, uint64_t value,
132 b9441ebb Benoît Canet
                unsigned size)
133 7233b355 ths
{
134 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
135 7233b355 ths
        value &= 0xffffffff;
136 7233b355 ths
137 7233b355 ths
        switch (addr) {
138 7233b355 ths
        case MST_LEDDAT1:
139 7233b355 ths
                s->leddat1 = value;
140 7233b355 ths
                break;
141 7233b355 ths
        case MST_LEDDAT2:
142 7233b355 ths
                s->leddat2 = value;
143 7233b355 ths
                break;
144 7233b355 ths
        case MST_LEDCTRL:
145 7233b355 ths
                s->ledctrl = value;
146 7233b355 ths
                break;
147 7233b355 ths
        case MST_GPSWR:
148 7233b355 ths
                s->gpswr = value;
149 7233b355 ths
                break;
150 7233b355 ths
        case MST_MSCWR1:
151 7233b355 ths
                s->mscwr1 = value;
152 7233b355 ths
                break;
153 7233b355 ths
        case MST_MSCWR2:
154 7233b355 ths
                s->mscwr2 = value;
155 7233b355 ths
                break;
156 7233b355 ths
        case MST_MSCWR3:
157 7233b355 ths
                s->mscwr3 = value;
158 7233b355 ths
                break;
159 7233b355 ths
        case MST_MSCRD:
160 7233b355 ths
                s->mscrd =  value;
161 7233b355 ths
                break;
162 ff2712ba Stefan Weil
        case MST_INTMSKENA:        /* Mask interrupt */
163 7233b355 ths
                s->intmskena = (value & 0xFEEFF);
164 43d91709 Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
165 7233b355 ths
                break;
166 7233b355 ths
        case MST_INTSETCLR:        /* clear or set interrupt */
167 7233b355 ths
                s->intsetclr = (value & 0xFEEFF);
168 3e1dbc3b Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
169 7233b355 ths
                break;
170 b651fc6f Dmitry Eremin-Solenikov
                /* For PCMCIAx allow the to change only power and reset */
171 7233b355 ths
        case MST_PCMCIA0:
172 b651fc6f Dmitry Eremin-Solenikov
                s->pcmcia0 = (value & 0x1f) | (s->pcmcia0 & ~0x1f);
173 7233b355 ths
                break;
174 7233b355 ths
        case MST_PCMCIA1:
175 b651fc6f Dmitry Eremin-Solenikov
                s->pcmcia1 = (value & 0x1f) | (s->pcmcia1 & ~0x1f);
176 7233b355 ths
                break;
177 7233b355 ths
        default:
178 7233b355 ths
                printf("Mainstone - mst_fpga_writeb: Bad register offset "
179 b2bedb21 Stefan Weil
                        "0x" TARGET_FMT_plx "\n", addr);
180 7233b355 ths
        }
181 7233b355 ths
}
182 7233b355 ths
183 b9441ebb Benoît Canet
static const MemoryRegionOps mst_fpga_ops = {
184 b9441ebb Benoît Canet
        .read = mst_fpga_readb,
185 b9441ebb Benoît Canet
        .write = mst_fpga_writeb,
186 b9441ebb Benoît Canet
        .endianness = DEVICE_NATIVE_ENDIAN,
187 7233b355 ths
};
188 7233b355 ths
189 cb380f61 Dmitry Eremin-Solenikov
static int mst_fpga_post_load(void *opaque, int version_id)
190 7233b355 ths
{
191 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
192 7233b355 ths
193 43d91709 Dmitry Eremin-Solenikov
        qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
194 7233b355 ths
        return 0;
195 7233b355 ths
}
196 7233b355 ths
197 cb380f61 Dmitry Eremin-Solenikov
static int mst_fpga_init(SysBusDevice *dev)
198 7233b355 ths
{
199 7233b355 ths
        mst_irq_state *s;
200 7233b355 ths
201 cb380f61 Dmitry Eremin-Solenikov
        s = FROM_SYSBUS(mst_irq_state, dev);
202 7233b355 ths
203 b651fc6f Dmitry Eremin-Solenikov
        s->pcmcia0 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
204 b651fc6f Dmitry Eremin-Solenikov
        s->pcmcia1 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
205 b651fc6f Dmitry Eremin-Solenikov
206 cb380f61 Dmitry Eremin-Solenikov
        sysbus_init_irq(dev, &s->parent);
207 7233b355 ths
208 7233b355 ths
        /* alloc the external 16 irqs */
209 cb380f61 Dmitry Eremin-Solenikov
        qdev_init_gpio_in(&dev->qdev, mst_fpga_set_irq, MST_NUM_IRQS);
210 7233b355 ths
211 b9441ebb Benoît Canet
        memory_region_init_io(&s->iomem, &mst_fpga_ops, s,
212 b9441ebb Benoît Canet
                            "fpga", 0x00100000);
213 750ecd44 Avi Kivity
        sysbus_init_mmio(dev, &s->iomem);
214 cb380f61 Dmitry Eremin-Solenikov
        return 0;
215 cb380f61 Dmitry Eremin-Solenikov
}
216 cb380f61 Dmitry Eremin-Solenikov
217 cb380f61 Dmitry Eremin-Solenikov
static VMStateDescription vmstate_mst_fpga_regs = {
218 cb380f61 Dmitry Eremin-Solenikov
        .name = "mainstone_fpga",
219 cb380f61 Dmitry Eremin-Solenikov
        .version_id = 0,
220 cb380f61 Dmitry Eremin-Solenikov
        .minimum_version_id = 0,
221 cb380f61 Dmitry Eremin-Solenikov
        .minimum_version_id_old = 0,
222 cb380f61 Dmitry Eremin-Solenikov
        .post_load = mst_fpga_post_load,
223 cb380f61 Dmitry Eremin-Solenikov
        .fields = (VMStateField []) {
224 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(prev_level, mst_irq_state),
225 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(leddat1, mst_irq_state),
226 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(leddat2, mst_irq_state),
227 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(ledctrl, mst_irq_state),
228 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(gpswr, mst_irq_state),
229 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr1, mst_irq_state),
230 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr2, mst_irq_state),
231 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr3, mst_irq_state),
232 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscrd, mst_irq_state),
233 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(intmskena, mst_irq_state),
234 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(intsetclr, mst_irq_state),
235 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(pcmcia0, mst_irq_state),
236 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(pcmcia1, mst_irq_state),
237 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_END_OF_LIST(),
238 cb380f61 Dmitry Eremin-Solenikov
        },
239 cb380f61 Dmitry Eremin-Solenikov
};
240 cb380f61 Dmitry Eremin-Solenikov
241 999e12bb Anthony Liguori
static void mst_fpga_class_init(ObjectClass *klass, void *data)
242 999e12bb Anthony Liguori
{
243 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
244 999e12bb Anthony Liguori
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
245 999e12bb Anthony Liguori
246 999e12bb Anthony Liguori
    k->init = mst_fpga_init;
247 39bffca2 Anthony Liguori
    dc->desc = "Mainstone II FPGA";
248 39bffca2 Anthony Liguori
    dc->vmsd = &vmstate_mst_fpga_regs;
249 999e12bb Anthony Liguori
}
250 999e12bb Anthony Liguori
251 8c43a6f0 Andreas Färber
static const TypeInfo mst_fpga_info = {
252 39bffca2 Anthony Liguori
    .name          = "mainstone-fpga",
253 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
254 39bffca2 Anthony Liguori
    .instance_size = sizeof(mst_irq_state),
255 39bffca2 Anthony Liguori
    .class_init    = mst_fpga_class_init,
256 cb380f61 Dmitry Eremin-Solenikov
};
257 cb380f61 Dmitry Eremin-Solenikov
258 83f7d43a Andreas Färber
static void mst_fpga_register_types(void)
259 cb380f61 Dmitry Eremin-Solenikov
{
260 39bffca2 Anthony Liguori
    type_register_static(&mst_fpga_info);
261 7233b355 ths
}
262 83f7d43a Andreas Färber
263 83f7d43a Andreas Färber
type_init(mst_fpga_register_types)