Statistics
| Branch: | Revision:

root / hw / pxa2xx_gpio.c @ 7ffa4767

History | View | Annotate | Download (9.6 kB)

1 c1713132 balrog
/*
2 c1713132 balrog
 * Intel XScale PXA255/270 GPIO controller emulation.
3 c1713132 balrog
 *
4 c1713132 balrog
 * Copyright (c) 2006 Openedhand Ltd.
5 c1713132 balrog
 * Written by Andrzej Zaborowski <balrog@zabor.org>
6 c1713132 balrog
 *
7 c1713132 balrog
 * This code is licensed under the GPL.
8 c1713132 balrog
 */
9 c1713132 balrog
10 87ecb68b pbrook
#include "hw.h"
11 87ecb68b pbrook
#include "pxa.h"
12 c1713132 balrog
13 c1713132 balrog
#define PXA2XX_GPIO_BANKS        4
14 c1713132 balrog
15 c1713132 balrog
struct pxa2xx_gpio_info_s {
16 c1713132 balrog
    qemu_irq *pic;
17 c1713132 balrog
    int lines;
18 c1713132 balrog
    CPUState *cpu_env;
19 38641a52 balrog
    qemu_irq *in;
20 c1713132 balrog
21 c1713132 balrog
    /* XXX: GNU C vectors are more suitable */
22 c1713132 balrog
    uint32_t ilevel[PXA2XX_GPIO_BANKS];
23 c1713132 balrog
    uint32_t olevel[PXA2XX_GPIO_BANKS];
24 c1713132 balrog
    uint32_t dir[PXA2XX_GPIO_BANKS];
25 c1713132 balrog
    uint32_t rising[PXA2XX_GPIO_BANKS];
26 c1713132 balrog
    uint32_t falling[PXA2XX_GPIO_BANKS];
27 c1713132 balrog
    uint32_t status[PXA2XX_GPIO_BANKS];
28 2b76bdc9 balrog
    uint32_t gpsr[PXA2XX_GPIO_BANKS];
29 c1713132 balrog
    uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
30 c1713132 balrog
31 c1713132 balrog
    uint32_t prev_level[PXA2XX_GPIO_BANKS];
32 38641a52 balrog
    qemu_irq handler[PXA2XX_GPIO_BANKS * 32];
33 38641a52 balrog
    qemu_irq read_notify;
34 c1713132 balrog
};
35 c1713132 balrog
36 c1713132 balrog
static struct {
37 c1713132 balrog
    enum {
38 c1713132 balrog
        GPIO_NONE,
39 c1713132 balrog
        GPLR,
40 c1713132 balrog
        GPSR,
41 c1713132 balrog
        GPCR,
42 c1713132 balrog
        GPDR,
43 c1713132 balrog
        GRER,
44 c1713132 balrog
        GFER,
45 c1713132 balrog
        GEDR,
46 c1713132 balrog
        GAFR_L,
47 c1713132 balrog
        GAFR_U,
48 c1713132 balrog
    } reg;
49 c1713132 balrog
    int bank;
50 c1713132 balrog
} pxa2xx_gpio_regs[0x200] = {
51 c1713132 balrog
    [0 ... 0x1ff] = { GPIO_NONE, 0 },
52 c1713132 balrog
#define PXA2XX_REG(reg, a0, a1, a2, a3)        \
53 5fafdf24 ths
    [a0] = { reg, 0 }, [a1] = { reg, 1 }, [a2] = { reg, 2 }, [a3] = { reg, 3 },
54 c1713132 balrog
55 c1713132 balrog
    PXA2XX_REG(GPLR, 0x000, 0x004, 0x008, 0x100)
56 c1713132 balrog
    PXA2XX_REG(GPSR, 0x018, 0x01c, 0x020, 0x118)
57 c1713132 balrog
    PXA2XX_REG(GPCR, 0x024, 0x028, 0x02c, 0x124)
58 c1713132 balrog
    PXA2XX_REG(GPDR, 0x00c, 0x010, 0x014, 0x10c)
59 c1713132 balrog
    PXA2XX_REG(GRER, 0x030, 0x034, 0x038, 0x130)
60 c1713132 balrog
    PXA2XX_REG(GFER, 0x03c, 0x040, 0x044, 0x13c)
61 c1713132 balrog
    PXA2XX_REG(GEDR, 0x048, 0x04c, 0x050, 0x148)
62 c1713132 balrog
    PXA2XX_REG(GAFR_L, 0x054, 0x05c, 0x064, 0x06c)
63 c1713132 balrog
    PXA2XX_REG(GAFR_U, 0x058, 0x060, 0x068, 0x070)
64 c1713132 balrog
};
65 c1713132 balrog
66 c1713132 balrog
static void pxa2xx_gpio_irq_update(struct pxa2xx_gpio_info_s *s)
67 c1713132 balrog
{
68 c1713132 balrog
    if (s->status[0] & (1 << 0))
69 c1713132 balrog
        qemu_irq_raise(s->pic[PXA2XX_PIC_GPIO_0]);
70 c1713132 balrog
    else
71 c1713132 balrog
        qemu_irq_lower(s->pic[PXA2XX_PIC_GPIO_0]);
72 c1713132 balrog
73 c1713132 balrog
    if (s->status[0] & (1 << 1))
74 c1713132 balrog
        qemu_irq_raise(s->pic[PXA2XX_PIC_GPIO_1]);
75 c1713132 balrog
    else
76 c1713132 balrog
        qemu_irq_lower(s->pic[PXA2XX_PIC_GPIO_1]);
77 c1713132 balrog
78 c1713132 balrog
    if ((s->status[0] & ~3) | s->status[1] | s->status[2] | s->status[3])
79 c1713132 balrog
        qemu_irq_raise(s->pic[PXA2XX_PIC_GPIO_X]);
80 c1713132 balrog
    else
81 c1713132 balrog
        qemu_irq_lower(s->pic[PXA2XX_PIC_GPIO_X]);
82 c1713132 balrog
}
83 c1713132 balrog
84 c1713132 balrog
/* Bitmap of pins used as standby and sleep wake-up sources.  */
85 38641a52 balrog
static const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = {
86 c1713132 balrog
    0x8003fe1b, 0x002001fc, 0xec080000, 0x0012007f,
87 c1713132 balrog
};
88 c1713132 balrog
89 38641a52 balrog
static void pxa2xx_gpio_set(void *opaque, int line, int level)
90 c1713132 balrog
{
91 38641a52 balrog
    struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
92 c1713132 balrog
    int bank;
93 c1713132 balrog
    uint32_t mask;
94 c1713132 balrog
95 c1713132 balrog
    if (line >= s->lines) {
96 c1713132 balrog
        printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
97 c1713132 balrog
        return;
98 c1713132 balrog
    }
99 c1713132 balrog
100 c1713132 balrog
    bank = line >> 5;
101 c1713132 balrog
    mask = 1 << (line & 31);
102 c1713132 balrog
103 c1713132 balrog
    if (level) {
104 c1713132 balrog
        s->status[bank] |= s->rising[bank] & mask &
105 c1713132 balrog
                ~s->ilevel[bank] & ~s->dir[bank];
106 c1713132 balrog
        s->ilevel[bank] |= mask;
107 c1713132 balrog
    } else {
108 c1713132 balrog
        s->status[bank] |= s->falling[bank] & mask &
109 c1713132 balrog
                s->ilevel[bank] & ~s->dir[bank];
110 c1713132 balrog
        s->ilevel[bank] &= ~mask;
111 c1713132 balrog
    }
112 c1713132 balrog
113 c1713132 balrog
    if (s->status[bank] & mask)
114 c1713132 balrog
        pxa2xx_gpio_irq_update(s);
115 c1713132 balrog
116 c1713132 balrog
    /* Wake-up GPIOs */
117 c1713132 balrog
    if (s->cpu_env->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank]))
118 c1713132 balrog
        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_EXITTB);
119 c1713132 balrog
}
120 c1713132 balrog
121 c1713132 balrog
static void pxa2xx_gpio_handler_update(struct pxa2xx_gpio_info_s *s) {
122 c1713132 balrog
    uint32_t level, diff;
123 c1713132 balrog
    int i, bit, line;
124 c1713132 balrog
    for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
125 c1713132 balrog
        level = s->olevel[i] & s->dir[i];
126 c1713132 balrog
127 c1713132 balrog
        for (diff = s->prev_level[i] ^ level; diff; diff ^= 1 << bit) {
128 c1713132 balrog
            bit = ffs(diff) - 1;
129 c1713132 balrog
            line = bit + 32 * i;
130 38641a52 balrog
            qemu_set_irq(s->handler[line], (level >> bit) & 1);
131 c1713132 balrog
        }
132 c1713132 balrog
133 c1713132 balrog
        s->prev_level[i] = level;
134 c1713132 balrog
    }
135 c1713132 balrog
}
136 c1713132 balrog
137 c1713132 balrog
static uint32_t pxa2xx_gpio_read(void *opaque, target_phys_addr_t offset)
138 c1713132 balrog
{
139 c1713132 balrog
    struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
140 c1713132 balrog
    uint32_t ret;
141 c1713132 balrog
    int bank;
142 c1713132 balrog
    if (offset >= 0x200)
143 c1713132 balrog
        return 0;
144 c1713132 balrog
145 c1713132 balrog
    bank = pxa2xx_gpio_regs[offset].bank;
146 c1713132 balrog
    switch (pxa2xx_gpio_regs[offset].reg) {
147 c1713132 balrog
    case GPDR:                /* GPIO Pin-Direction registers */
148 c1713132 balrog
        return s->dir[bank];
149 c1713132 balrog
150 2b76bdc9 balrog
    case GPSR:                /* GPIO Pin-Output Set registers */
151 2b76bdc9 balrog
        printf("%s: Read from a write-only register " REG_FMT "\n",
152 2b76bdc9 balrog
                        __FUNCTION__, offset);
153 2b76bdc9 balrog
        return s->gpsr[bank];        /* Return last written value.  */
154 2b76bdc9 balrog
155 e1dad5a6 balrog
    case GPCR:                /* GPIO Pin-Output Clear registers */
156 e1dad5a6 balrog
        printf("%s: Read from a write-only register " REG_FMT "\n",
157 e1dad5a6 balrog
                        __FUNCTION__, offset);
158 e1dad5a6 balrog
        return 31337;                /* Specified as unpredictable in the docs.  */
159 e1dad5a6 balrog
160 c1713132 balrog
    case GRER:                /* GPIO Rising-Edge Detect Enable registers */
161 c1713132 balrog
        return s->rising[bank];
162 c1713132 balrog
163 c1713132 balrog
    case GFER:                /* GPIO Falling-Edge Detect Enable registers */
164 c1713132 balrog
        return s->falling[bank];
165 c1713132 balrog
166 c1713132 balrog
    case GAFR_L:        /* GPIO Alternate Function registers */
167 c1713132 balrog
        return s->gafr[bank * 2];
168 c1713132 balrog
169 c1713132 balrog
    case GAFR_U:        /* GPIO Alternate Function registers */
170 c1713132 balrog
        return s->gafr[bank * 2 + 1];
171 c1713132 balrog
172 c1713132 balrog
    case GPLR:                /* GPIO Pin-Level registers */
173 c1713132 balrog
        ret = (s->olevel[bank] & s->dir[bank]) |
174 c1713132 balrog
                (s->ilevel[bank] & ~s->dir[bank]);
175 38641a52 balrog
        qemu_irq_raise(s->read_notify);
176 c1713132 balrog
        return ret;
177 c1713132 balrog
178 c1713132 balrog
    case GEDR:                /* GPIO Edge Detect Status registers */
179 c1713132 balrog
        return s->status[bank];
180 c1713132 balrog
181 c1713132 balrog
    default:
182 c1713132 balrog
        cpu_abort(cpu_single_env,
183 c1713132 balrog
                "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
184 c1713132 balrog
    }
185 c1713132 balrog
186 c1713132 balrog
    return 0;
187 c1713132 balrog
}
188 c1713132 balrog
189 c1713132 balrog
static void pxa2xx_gpio_write(void *opaque,
190 c1713132 balrog
                target_phys_addr_t offset, uint32_t value)
191 c1713132 balrog
{
192 c1713132 balrog
    struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
193 c1713132 balrog
    int bank;
194 c1713132 balrog
    if (offset >= 0x200)
195 c1713132 balrog
        return;
196 c1713132 balrog
197 c1713132 balrog
    bank = pxa2xx_gpio_regs[offset].bank;
198 c1713132 balrog
    switch (pxa2xx_gpio_regs[offset].reg) {
199 c1713132 balrog
    case GPDR:                /* GPIO Pin-Direction registers */
200 c1713132 balrog
        s->dir[bank] = value;
201 c1713132 balrog
        pxa2xx_gpio_handler_update(s);
202 c1713132 balrog
        break;
203 c1713132 balrog
204 c1713132 balrog
    case GPSR:                /* GPIO Pin-Output Set registers */
205 c1713132 balrog
        s->olevel[bank] |= value;
206 c1713132 balrog
        pxa2xx_gpio_handler_update(s);
207 2b76bdc9 balrog
        s->gpsr[bank] = value;
208 c1713132 balrog
        break;
209 c1713132 balrog
210 c1713132 balrog
    case GPCR:                /* GPIO Pin-Output Clear registers */
211 c1713132 balrog
        s->olevel[bank] &= ~value;
212 c1713132 balrog
        pxa2xx_gpio_handler_update(s);
213 c1713132 balrog
        break;
214 c1713132 balrog
215 c1713132 balrog
    case GRER:                /* GPIO Rising-Edge Detect Enable registers */
216 c1713132 balrog
        s->rising[bank] = value;
217 c1713132 balrog
        break;
218 c1713132 balrog
219 c1713132 balrog
    case GFER:                /* GPIO Falling-Edge Detect Enable registers */
220 c1713132 balrog
        s->falling[bank] = value;
221 c1713132 balrog
        break;
222 c1713132 balrog
223 c1713132 balrog
    case GAFR_L:        /* GPIO Alternate Function registers */
224 c1713132 balrog
        s->gafr[bank * 2] = value;
225 c1713132 balrog
        break;
226 c1713132 balrog
227 c1713132 balrog
    case GAFR_U:        /* GPIO Alternate Function registers */
228 c1713132 balrog
        s->gafr[bank * 2 + 1] = value;
229 c1713132 balrog
        break;
230 c1713132 balrog
231 c1713132 balrog
    case GEDR:                /* GPIO Edge Detect Status registers */
232 c1713132 balrog
        s->status[bank] &= ~value;
233 c1713132 balrog
        pxa2xx_gpio_irq_update(s);
234 c1713132 balrog
        break;
235 c1713132 balrog
236 c1713132 balrog
    default:
237 c1713132 balrog
        cpu_abort(cpu_single_env,
238 c1713132 balrog
                "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
239 c1713132 balrog
    }
240 c1713132 balrog
}
241 c1713132 balrog
242 c1713132 balrog
static CPUReadMemoryFunc *pxa2xx_gpio_readfn[] = {
243 c1713132 balrog
    pxa2xx_gpio_read,
244 c1713132 balrog
    pxa2xx_gpio_read,
245 c1713132 balrog
    pxa2xx_gpio_read
246 c1713132 balrog
};
247 c1713132 balrog
248 c1713132 balrog
static CPUWriteMemoryFunc *pxa2xx_gpio_writefn[] = {
249 c1713132 balrog
    pxa2xx_gpio_write,
250 c1713132 balrog
    pxa2xx_gpio_write,
251 c1713132 balrog
    pxa2xx_gpio_write
252 c1713132 balrog
};
253 c1713132 balrog
254 aa941b94 balrog
static void pxa2xx_gpio_save(QEMUFile *f, void *opaque)
255 aa941b94 balrog
{
256 aa941b94 balrog
    struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
257 aa941b94 balrog
    int i;
258 aa941b94 balrog
259 aa941b94 balrog
    qemu_put_be32(f, s->lines);
260 aa941b94 balrog
261 aa941b94 balrog
    for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
262 aa941b94 balrog
        qemu_put_be32s(f, &s->ilevel[i]);
263 aa941b94 balrog
        qemu_put_be32s(f, &s->olevel[i]);
264 aa941b94 balrog
        qemu_put_be32s(f, &s->dir[i]);
265 aa941b94 balrog
        qemu_put_be32s(f, &s->rising[i]);
266 aa941b94 balrog
        qemu_put_be32s(f, &s->falling[i]);
267 aa941b94 balrog
        qemu_put_be32s(f, &s->status[i]);
268 aa941b94 balrog
        qemu_put_be32s(f, &s->gafr[i * 2 + 0]);
269 aa941b94 balrog
        qemu_put_be32s(f, &s->gafr[i * 2 + 1]);
270 aa941b94 balrog
271 aa941b94 balrog
        qemu_put_be32s(f, &s->prev_level[i]);
272 aa941b94 balrog
    }
273 aa941b94 balrog
}
274 aa941b94 balrog
275 aa941b94 balrog
static int pxa2xx_gpio_load(QEMUFile *f, void *opaque, int version_id)
276 aa941b94 balrog
{
277 aa941b94 balrog
    struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
278 aa941b94 balrog
    int i;
279 aa941b94 balrog
280 aa941b94 balrog
    if (qemu_get_be32(f) != s->lines)
281 aa941b94 balrog
        return -EINVAL;
282 aa941b94 balrog
283 aa941b94 balrog
    for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
284 aa941b94 balrog
        qemu_get_be32s(f, &s->ilevel[i]);
285 aa941b94 balrog
        qemu_get_be32s(f, &s->olevel[i]);
286 aa941b94 balrog
        qemu_get_be32s(f, &s->dir[i]);
287 aa941b94 balrog
        qemu_get_be32s(f, &s->rising[i]);
288 aa941b94 balrog
        qemu_get_be32s(f, &s->falling[i]);
289 aa941b94 balrog
        qemu_get_be32s(f, &s->status[i]);
290 aa941b94 balrog
        qemu_get_be32s(f, &s->gafr[i * 2 + 0]);
291 aa941b94 balrog
        qemu_get_be32s(f, &s->gafr[i * 2 + 1]);
292 aa941b94 balrog
293 aa941b94 balrog
        qemu_get_be32s(f, &s->prev_level[i]);
294 aa941b94 balrog
    }
295 aa941b94 balrog
296 aa941b94 balrog
    return 0;
297 aa941b94 balrog
}
298 aa941b94 balrog
299 c1713132 balrog
struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base,
300 c1713132 balrog
                CPUState *env, qemu_irq *pic, int lines)
301 c1713132 balrog
{
302 c1713132 balrog
    int iomemtype;
303 c1713132 balrog
    struct pxa2xx_gpio_info_s *s;
304 c1713132 balrog
305 c1713132 balrog
    s = (struct pxa2xx_gpio_info_s *)
306 c1713132 balrog
            qemu_mallocz(sizeof(struct pxa2xx_gpio_info_s));
307 c1713132 balrog
    memset(s, 0, sizeof(struct pxa2xx_gpio_info_s));
308 c1713132 balrog
    s->pic = pic;
309 c1713132 balrog
    s->lines = lines;
310 c1713132 balrog
    s->cpu_env = env;
311 38641a52 balrog
    s->in = qemu_allocate_irqs(pxa2xx_gpio_set, s, lines);
312 c1713132 balrog
313 c1713132 balrog
    iomemtype = cpu_register_io_memory(0, pxa2xx_gpio_readfn,
314 c1713132 balrog
                    pxa2xx_gpio_writefn, s);
315 187337f8 pbrook
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
316 c1713132 balrog
317 aa941b94 balrog
    register_savevm("pxa2xx_gpio", 0, 0,
318 aa941b94 balrog
                    pxa2xx_gpio_save, pxa2xx_gpio_load, s);
319 aa941b94 balrog
320 c1713132 balrog
    return s;
321 c1713132 balrog
}
322 c1713132 balrog
323 38641a52 balrog
qemu_irq *pxa2xx_gpio_in_get(struct pxa2xx_gpio_info_s *s)
324 38641a52 balrog
{
325 38641a52 balrog
    return s->in;
326 38641a52 balrog
}
327 38641a52 balrog
328 38641a52 balrog
void pxa2xx_gpio_out_set(struct pxa2xx_gpio_info_s *s,
329 38641a52 balrog
                int line, qemu_irq handler)
330 38641a52 balrog
{
331 c1713132 balrog
    if (line >= s->lines) {
332 c1713132 balrog
        printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
333 c1713132 balrog
        return;
334 c1713132 balrog
    }
335 c1713132 balrog
336 38641a52 balrog
    s->handler[line] = handler;
337 c1713132 balrog
}
338 c1713132 balrog
339 c1713132 balrog
/*
340 c1713132 balrog
 * Registers a callback to notify on GPLR reads.  This normally
341 c1713132 balrog
 * shouldn't be needed but it is used for the hack on Spitz machines.
342 c1713132 balrog
 */
343 38641a52 balrog
void pxa2xx_gpio_read_notifier(struct pxa2xx_gpio_info_s *s, qemu_irq handler)
344 38641a52 balrog
{
345 c1713132 balrog
    s->read_notify = handler;
346 c1713132 balrog
}