Statistics
| Branch: | Revision:

root / hw / mst_fpga.c @ 43d91709

History | View | Annotate | Download (5 kB)

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 "mainstone.h"
12

    
13
/* Mainstone FPGA for extern irqs */
14
#define FPGA_GPIO_PIN        0
15
#define MST_NUM_IRQS        16
16
#define MST_LEDDAT1                0x10
17
#define MST_LEDDAT2                0x14
18
#define MST_LEDCTRL                0x40
19
#define MST_GPSWR                0x60
20
#define MST_MSCWR1                0x80
21
#define MST_MSCWR2                0x84
22
#define MST_MSCWR3                0x88
23
#define MST_MSCRD                0x90
24
#define MST_INTMSKENA        0xc0
25
#define MST_INTSETCLR        0xd0
26
#define MST_PCMCIA0                0xe0
27
#define MST_PCMCIA1                0xe4
28

    
29
typedef struct mst_irq_state{
30
        qemu_irq parent;
31
        qemu_irq *pins;
32

    
33
        uint32_t prev_level;
34
        uint32_t leddat1;
35
        uint32_t leddat2;
36
        uint32_t ledctrl;
37
        uint32_t gpswr;
38
        uint32_t mscwr1;
39
        uint32_t mscwr2;
40
        uint32_t mscwr3;
41
        uint32_t mscrd;
42
        uint32_t intmskena;
43
        uint32_t intsetclr;
44
        uint32_t pcmcia0;
45
        uint32_t pcmcia1;
46
}mst_irq_state;
47

    
48
static void
49
mst_fpga_set_irq(void *opaque, int irq, int level)
50
{
51
        mst_irq_state *s = (mst_irq_state *)opaque;
52
        uint32_t oldint = s->intsetclr;
53

    
54
        if (level)
55
                s->prev_level |= 1u << irq;
56
        else
57
                s->prev_level &= ~(1u << irq);
58

    
59
        if ((s->intmskena & (1u << irq)) && level)
60
                s->intsetclr |= 1u << irq;
61

    
62
        if (oldint != (s->intsetclr & s->intmskena))
63
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
64
}
65

    
66

    
67
static uint32_t
68
mst_fpga_readb(void *opaque, target_phys_addr_t addr)
69
{
70
        mst_irq_state *s = (mst_irq_state *) opaque;
71

    
72
        switch (addr) {
73
        case MST_LEDDAT1:
74
                return s->leddat1;
75
        case MST_LEDDAT2:
76
                return s->leddat2;
77
        case MST_LEDCTRL:
78
                return s->ledctrl;
79
        case MST_GPSWR:
80
                return s->gpswr;
81
        case MST_MSCWR1:
82
                return s->mscwr1;
83
        case MST_MSCWR2:
84
                return s->mscwr2;
85
        case MST_MSCWR3:
86
                return s->mscwr3;
87
        case MST_MSCRD:
88
                return s->mscrd;
89
        case MST_INTMSKENA:
90
                return s->intmskena;
91
        case MST_INTSETCLR:
92
                return s->intsetclr;
93
        case MST_PCMCIA0:
94
                return s->pcmcia0;
95
        case MST_PCMCIA1:
96
                return s->pcmcia1;
97
        default:
98
                printf("Mainstone - mst_fpga_readb: Bad register offset "
99
                        "0x" TARGET_FMT_plx " \n", addr);
100
        }
101
        return 0;
102
}
103

    
104
static void
105
mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
106
{
107
        mst_irq_state *s = (mst_irq_state *) opaque;
108
        value &= 0xffffffff;
109

    
110
        switch (addr) {
111
        case MST_LEDDAT1:
112
                s->leddat1 = value;
113
                break;
114
        case MST_LEDDAT2:
115
                s->leddat2 = value;
116
                break;
117
        case MST_LEDCTRL:
118
                s->ledctrl = value;
119
                break;
120
        case MST_GPSWR:
121
                s->gpswr = value;
122
                break;
123
        case MST_MSCWR1:
124
                s->mscwr1 = value;
125
                break;
126
        case MST_MSCWR2:
127
                s->mscwr2 = value;
128
                break;
129
        case MST_MSCWR3:
130
                s->mscwr3 = value;
131
                break;
132
        case MST_MSCRD:
133
                s->mscrd =  value;
134
                break;
135
        case MST_INTMSKENA:        /* Mask interupt */
136
                s->intmskena = (value & 0xFEEFF);
137
                qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
138
                break;
139
        case MST_INTSETCLR:        /* clear or set interrupt */
140
                s->intsetclr = (value & 0xFEEFF);
141
                qemu_set_irq(s->parent, s->intsetclr);
142
                break;
143
        case MST_PCMCIA0:
144
                s->pcmcia0 = value;
145
                break;
146
        case MST_PCMCIA1:
147
                s->pcmcia1 = value;
148
                break;
149
        default:
150
                printf("Mainstone - mst_fpga_writeb: Bad register offset "
151
                        "0x" TARGET_FMT_plx " \n", addr);
152
        }
153
}
154

    
155
static CPUReadMemoryFunc * const mst_fpga_readfn[] = {
156
        mst_fpga_readb,
157
        mst_fpga_readb,
158
        mst_fpga_readb,
159
};
160
static CPUWriteMemoryFunc * const mst_fpga_writefn[] = {
161
        mst_fpga_writeb,
162
        mst_fpga_writeb,
163
        mst_fpga_writeb,
164
};
165

    
166
static void
167
mst_fpga_save(QEMUFile *f, void *opaque)
168
{
169
        struct mst_irq_state *s = (mst_irq_state *) opaque;
170

    
171
        qemu_put_be32s(f, &s->prev_level);
172
        qemu_put_be32s(f, &s->leddat1);
173
        qemu_put_be32s(f, &s->leddat2);
174
        qemu_put_be32s(f, &s->ledctrl);
175
        qemu_put_be32s(f, &s->gpswr);
176
        qemu_put_be32s(f, &s->mscwr1);
177
        qemu_put_be32s(f, &s->mscwr2);
178
        qemu_put_be32s(f, &s->mscwr3);
179
        qemu_put_be32s(f, &s->mscrd);
180
        qemu_put_be32s(f, &s->intmskena);
181
        qemu_put_be32s(f, &s->intsetclr);
182
        qemu_put_be32s(f, &s->pcmcia0);
183
        qemu_put_be32s(f, &s->pcmcia1);
184
}
185

    
186
static int
187
mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
188
{
189
        mst_irq_state *s = (mst_irq_state *) opaque;
190

    
191
        qemu_get_be32s(f, &s->prev_level);
192
        qemu_get_be32s(f, &s->leddat1);
193
        qemu_get_be32s(f, &s->leddat2);
194
        qemu_get_be32s(f, &s->ledctrl);
195
        qemu_get_be32s(f, &s->gpswr);
196
        qemu_get_be32s(f, &s->mscwr1);
197
        qemu_get_be32s(f, &s->mscwr2);
198
        qemu_get_be32s(f, &s->mscwr3);
199
        qemu_get_be32s(f, &s->mscrd);
200
        qemu_get_be32s(f, &s->intmskena);
201
        qemu_get_be32s(f, &s->intsetclr);
202
        qemu_get_be32s(f, &s->pcmcia0);
203
        qemu_get_be32s(f, &s->pcmcia1);
204

    
205
        qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
206
        return 0;
207
}
208

    
209
qemu_irq *mst_irq_init(uint32_t base, qemu_irq irq)
210
{
211
        mst_irq_state *s;
212
        int iomemtype;
213
        qemu_irq *qi;
214

    
215
        s = (mst_irq_state  *)
216
                qemu_mallocz(sizeof(mst_irq_state));
217

    
218
        s->parent = irq;
219

    
220
        /* alloc the external 16 irqs */
221
        qi  = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
222
        s->pins = qi;
223

    
224
        iomemtype = cpu_register_io_memory(mst_fpga_readfn,
225
                mst_fpga_writefn, s, DEVICE_NATIVE_ENDIAN);
226
        cpu_register_physical_memory(base, 0x00100000, iomemtype);
227
        register_savevm(NULL, "mainstone_fpga", 0, 0, mst_fpga_save,
228
                        mst_fpga_load, s);
229
        return qi;
230
}