Statistics
| Branch: | Revision:

root / hw / pxa2xx_gpio.c @ aa941b94

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