Statistics
| Branch: | Revision:

root / hw / mst_fpga.c @ 46115ac4

History | View | Annotate | Download (5.7 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 b651fc6f Dmitry Eremin-Solenikov
#define MST_PCMCIAx_READY        (1 << 10)
30 b651fc6f Dmitry Eremin-Solenikov
#define MST_PCMCIAx_nCD                (1 << 5)
31 b651fc6f Dmitry Eremin-Solenikov
32 b651fc6f Dmitry Eremin-Solenikov
#define MST_PCMCIA_CD0_IRQ        9
33 b651fc6f Dmitry Eremin-Solenikov
#define MST_PCMCIA_CD1_IRQ        13
34 b651fc6f Dmitry Eremin-Solenikov
35 7233b355 ths
typedef struct mst_irq_state{
36 cb380f61 Dmitry Eremin-Solenikov
        SysBusDevice busdev;
37 cb380f61 Dmitry Eremin-Solenikov
38 bb70651e Dmitry Eremin-Solenikov
        qemu_irq parent;
39 7233b355 ths
40 7233b355 ths
        uint32_t prev_level;
41 7233b355 ths
        uint32_t leddat1;
42 7233b355 ths
        uint32_t leddat2;
43 7233b355 ths
        uint32_t ledctrl;
44 7233b355 ths
        uint32_t gpswr;
45 7233b355 ths
        uint32_t mscwr1;
46 7233b355 ths
        uint32_t mscwr2;
47 7233b355 ths
        uint32_t mscwr3;
48 7233b355 ths
        uint32_t mscrd;
49 7233b355 ths
        uint32_t intmskena;
50 7233b355 ths
        uint32_t intsetclr;
51 7233b355 ths
        uint32_t pcmcia0;
52 7233b355 ths
        uint32_t pcmcia1;
53 7233b355 ths
}mst_irq_state;
54 7233b355 ths
55 7233b355 ths
static void
56 7233b355 ths
mst_fpga_set_irq(void *opaque, int irq, int level)
57 7233b355 ths
{
58 7233b355 ths
        mst_irq_state *s = (mst_irq_state *)opaque;
59 3e1dbc3b Dmitry Eremin-Solenikov
        uint32_t oldint = s->intsetclr & s->intmskena;
60 7233b355 ths
61 7233b355 ths
        if (level)
62 7233b355 ths
                s->prev_level |= 1u << irq;
63 7233b355 ths
        else
64 7233b355 ths
                s->prev_level &= ~(1u << irq);
65 7233b355 ths
66 b651fc6f Dmitry Eremin-Solenikov
        switch(irq) {
67 b651fc6f Dmitry Eremin-Solenikov
        case MST_PCMCIA_CD0_IRQ:
68 b651fc6f Dmitry Eremin-Solenikov
                if (level)
69 b651fc6f Dmitry Eremin-Solenikov
                        s->pcmcia0 &= ~MST_PCMCIAx_nCD;
70 b651fc6f Dmitry Eremin-Solenikov
                else
71 b651fc6f Dmitry Eremin-Solenikov
                        s->pcmcia0 |=  MST_PCMCIAx_nCD;
72 b651fc6f Dmitry Eremin-Solenikov
                break;
73 b651fc6f Dmitry Eremin-Solenikov
        case MST_PCMCIA_CD1_IRQ:
74 b651fc6f Dmitry Eremin-Solenikov
                if (level)
75 b651fc6f Dmitry Eremin-Solenikov
                        s->pcmcia1 &= ~MST_PCMCIAx_nCD;
76 b651fc6f Dmitry Eremin-Solenikov
                else
77 b651fc6f Dmitry Eremin-Solenikov
                        s->pcmcia1 |=  MST_PCMCIAx_nCD;
78 b651fc6f Dmitry Eremin-Solenikov
                break;
79 b651fc6f Dmitry Eremin-Solenikov
        }
80 b651fc6f Dmitry Eremin-Solenikov
81 43d91709 Dmitry Eremin-Solenikov
        if ((s->intmskena & (1u << irq)) && level)
82 43d91709 Dmitry Eremin-Solenikov
                s->intsetclr |= 1u << irq;
83 43d91709 Dmitry Eremin-Solenikov
84 43d91709 Dmitry Eremin-Solenikov
        if (oldint != (s->intsetclr & s->intmskena))
85 43d91709 Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
86 7233b355 ths
}
87 7233b355 ths
88 7233b355 ths
89 7233b355 ths
static uint32_t
90 c227f099 Anthony Liguori
mst_fpga_readb(void *opaque, target_phys_addr_t addr)
91 7233b355 ths
{
92 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
93 7233b355 ths
94 7233b355 ths
        switch (addr) {
95 7233b355 ths
        case MST_LEDDAT1:
96 7233b355 ths
                return s->leddat1;
97 7233b355 ths
        case MST_LEDDAT2:
98 7233b355 ths
                return s->leddat2;
99 7233b355 ths
        case MST_LEDCTRL:
100 7233b355 ths
                return s->ledctrl;
101 7233b355 ths
        case MST_GPSWR:
102 7233b355 ths
                return s->gpswr;
103 7233b355 ths
        case MST_MSCWR1:
104 7233b355 ths
                return s->mscwr1;
105 7233b355 ths
        case MST_MSCWR2:
106 7233b355 ths
                return s->mscwr2;
107 7233b355 ths
        case MST_MSCWR3:
108 7233b355 ths
                return s->mscwr3;
109 7233b355 ths
        case MST_MSCRD:
110 7233b355 ths
                return s->mscrd;
111 7233b355 ths
        case MST_INTMSKENA:
112 7233b355 ths
                return s->intmskena;
113 7233b355 ths
        case MST_INTSETCLR:
114 7233b355 ths
                return s->intsetclr;
115 7233b355 ths
        case MST_PCMCIA0:
116 7233b355 ths
                return s->pcmcia0;
117 7233b355 ths
        case MST_PCMCIA1:
118 7233b355 ths
                return s->pcmcia1;
119 7233b355 ths
        default:
120 7233b355 ths
                printf("Mainstone - mst_fpga_readb: Bad register offset "
121 bb70651e Dmitry Eremin-Solenikov
                        "0x" TARGET_FMT_plx " \n", addr);
122 7233b355 ths
        }
123 7233b355 ths
        return 0;
124 7233b355 ths
}
125 7233b355 ths
126 7233b355 ths
static void
127 c227f099 Anthony Liguori
mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
128 7233b355 ths
{
129 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
130 7233b355 ths
        value &= 0xffffffff;
131 7233b355 ths
132 7233b355 ths
        switch (addr) {
133 7233b355 ths
        case MST_LEDDAT1:
134 7233b355 ths
                s->leddat1 = value;
135 7233b355 ths
                break;
136 7233b355 ths
        case MST_LEDDAT2:
137 7233b355 ths
                s->leddat2 = value;
138 7233b355 ths
                break;
139 7233b355 ths
        case MST_LEDCTRL:
140 7233b355 ths
                s->ledctrl = value;
141 7233b355 ths
                break;
142 7233b355 ths
        case MST_GPSWR:
143 7233b355 ths
                s->gpswr = value;
144 7233b355 ths
                break;
145 7233b355 ths
        case MST_MSCWR1:
146 7233b355 ths
                s->mscwr1 = value;
147 7233b355 ths
                break;
148 7233b355 ths
        case MST_MSCWR2:
149 7233b355 ths
                s->mscwr2 = value;
150 7233b355 ths
                break;
151 7233b355 ths
        case MST_MSCWR3:
152 7233b355 ths
                s->mscwr3 = value;
153 7233b355 ths
                break;
154 7233b355 ths
        case MST_MSCRD:
155 7233b355 ths
                s->mscrd =  value;
156 7233b355 ths
                break;
157 ff2712ba Stefan Weil
        case MST_INTMSKENA:        /* Mask interrupt */
158 7233b355 ths
                s->intmskena = (value & 0xFEEFF);
159 43d91709 Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
160 7233b355 ths
                break;
161 7233b355 ths
        case MST_INTSETCLR:        /* clear or set interrupt */
162 7233b355 ths
                s->intsetclr = (value & 0xFEEFF);
163 3e1dbc3b Dmitry Eremin-Solenikov
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
164 7233b355 ths
                break;
165 b651fc6f Dmitry Eremin-Solenikov
                /* For PCMCIAx allow the to change only power and reset */
166 7233b355 ths
        case MST_PCMCIA0:
167 b651fc6f Dmitry Eremin-Solenikov
                s->pcmcia0 = (value & 0x1f) | (s->pcmcia0 & ~0x1f);
168 7233b355 ths
                break;
169 7233b355 ths
        case MST_PCMCIA1:
170 b651fc6f Dmitry Eremin-Solenikov
                s->pcmcia1 = (value & 0x1f) | (s->pcmcia1 & ~0x1f);
171 7233b355 ths
                break;
172 7233b355 ths
        default:
173 7233b355 ths
                printf("Mainstone - mst_fpga_writeb: Bad register offset "
174 bb70651e Dmitry Eremin-Solenikov
                        "0x" TARGET_FMT_plx " \n", addr);
175 7233b355 ths
        }
176 7233b355 ths
}
177 7233b355 ths
178 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const mst_fpga_readfn[] = {
179 7233b355 ths
        mst_fpga_readb,
180 7233b355 ths
        mst_fpga_readb,
181 7233b355 ths
        mst_fpga_readb,
182 7233b355 ths
};
183 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const mst_fpga_writefn[] = {
184 7233b355 ths
        mst_fpga_writeb,
185 7233b355 ths
        mst_fpga_writeb,
186 7233b355 ths
        mst_fpga_writeb,
187 7233b355 ths
};
188 7233b355 ths
189 7233b355 ths
190 cb380f61 Dmitry Eremin-Solenikov
static int mst_fpga_post_load(void *opaque, int version_id)
191 7233b355 ths
{
192 7233b355 ths
        mst_irq_state *s = (mst_irq_state *) opaque;
193 7233b355 ths
194 43d91709 Dmitry Eremin-Solenikov
        qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
195 7233b355 ths
        return 0;
196 7233b355 ths
}
197 7233b355 ths
198 cb380f61 Dmitry Eremin-Solenikov
static int mst_fpga_init(SysBusDevice *dev)
199 7233b355 ths
{
200 7233b355 ths
        mst_irq_state *s;
201 7233b355 ths
        int iomemtype;
202 7233b355 ths
203 cb380f61 Dmitry Eremin-Solenikov
        s = FROM_SYSBUS(mst_irq_state, dev);
204 7233b355 ths
205 b651fc6f Dmitry Eremin-Solenikov
        s->pcmcia0 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
206 b651fc6f Dmitry Eremin-Solenikov
        s->pcmcia1 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
207 b651fc6f Dmitry Eremin-Solenikov
208 cb380f61 Dmitry Eremin-Solenikov
        sysbus_init_irq(dev, &s->parent);
209 7233b355 ths
210 7233b355 ths
        /* alloc the external 16 irqs */
211 cb380f61 Dmitry Eremin-Solenikov
        qdev_init_gpio_in(&dev->qdev, mst_fpga_set_irq, MST_NUM_IRQS);
212 7233b355 ths
213 1eed09cb Avi Kivity
        iomemtype = cpu_register_io_memory(mst_fpga_readfn,
214 2507c12a Alexander Graf
                mst_fpga_writefn, s, DEVICE_NATIVE_ENDIAN);
215 cb380f61 Dmitry Eremin-Solenikov
        sysbus_init_mmio(dev, 0x00100000, iomemtype);
216 cb380f61 Dmitry Eremin-Solenikov
        return 0;
217 cb380f61 Dmitry Eremin-Solenikov
}
218 cb380f61 Dmitry Eremin-Solenikov
219 cb380f61 Dmitry Eremin-Solenikov
static VMStateDescription vmstate_mst_fpga_regs = {
220 cb380f61 Dmitry Eremin-Solenikov
        .name = "mainstone_fpga",
221 cb380f61 Dmitry Eremin-Solenikov
        .version_id = 0,
222 cb380f61 Dmitry Eremin-Solenikov
        .minimum_version_id = 0,
223 cb380f61 Dmitry Eremin-Solenikov
        .minimum_version_id_old = 0,
224 cb380f61 Dmitry Eremin-Solenikov
        .post_load = mst_fpga_post_load,
225 cb380f61 Dmitry Eremin-Solenikov
        .fields = (VMStateField []) {
226 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(prev_level, mst_irq_state),
227 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(leddat1, mst_irq_state),
228 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(leddat2, mst_irq_state),
229 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(ledctrl, mst_irq_state),
230 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(gpswr, mst_irq_state),
231 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr1, mst_irq_state),
232 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr2, mst_irq_state),
233 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscwr3, mst_irq_state),
234 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(mscrd, mst_irq_state),
235 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(intmskena, mst_irq_state),
236 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(intsetclr, mst_irq_state),
237 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(pcmcia0, mst_irq_state),
238 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_UINT32(pcmcia1, mst_irq_state),
239 cb380f61 Dmitry Eremin-Solenikov
                VMSTATE_END_OF_LIST(),
240 cb380f61 Dmitry Eremin-Solenikov
        },
241 cb380f61 Dmitry Eremin-Solenikov
};
242 cb380f61 Dmitry Eremin-Solenikov
243 cb380f61 Dmitry Eremin-Solenikov
static SysBusDeviceInfo mst_fpga_info = {
244 cb380f61 Dmitry Eremin-Solenikov
        .init = mst_fpga_init,
245 cb380f61 Dmitry Eremin-Solenikov
        .qdev.name = "mainstone-fpga",
246 cb380f61 Dmitry Eremin-Solenikov
        .qdev.desc = "Mainstone II FPGA",
247 cb380f61 Dmitry Eremin-Solenikov
        .qdev.size = sizeof(mst_irq_state),
248 cb380f61 Dmitry Eremin-Solenikov
        .qdev.vmsd = &vmstate_mst_fpga_regs,
249 cb380f61 Dmitry Eremin-Solenikov
};
250 cb380f61 Dmitry Eremin-Solenikov
251 cb380f61 Dmitry Eremin-Solenikov
static void mst_fpga_register(void)
252 cb380f61 Dmitry Eremin-Solenikov
{
253 cb380f61 Dmitry Eremin-Solenikov
        sysbus_register_withprop(&mst_fpga_info);
254 7233b355 ths
}
255 cb380f61 Dmitry Eremin-Solenikov
device_init(mst_fpga_register);