1 /* $NetBSD: imxgpio.c,v 1.4 2014/03/22 05:19:18 hkenken Exp $ */ 2 3 /*- 4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Matt Thomas 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v 1.4 2014/03/22 05:19:18 hkenken Exp $"); 33 34 #define _INTR_PRIVATE 35 36 #include "locators.h" 37 #include "gpio.h" 38 #include "opt_imxgpio.h" 39 40 #include <sys/param.h> 41 #include <sys/evcnt.h> 42 #include <sys/atomic.h> 43 44 #include <uvm/uvm_extern.h> 45 46 #include <machine/intr.h> 47 48 #include <arm/cpu.h> 49 #include <arm/armreg.h> 50 #include <arm/cpufunc.h> 51 52 #include <sys/bus.h> 53 54 #include <arm/imx/imx31reg.h> 55 #include <arm/imx/imx31var.h> 56 #include <arm/imx/imxgpioreg.h> 57 #include <arm/pic/picvar.h> 58 59 #include <arm/imx/imxgpioreg.h> 60 #include <arm/imx/imxgpiovar.h> 61 62 #if NGPIO > 0 63 /* GPIO access from userland */ 64 #include <sys/gpio.h> 65 #include <dev/gpio/gpiovar.h> 66 #endif 67 68 #define MAX_NGROUP 4 69 70 static void gpio_pic_block_irqs(struct pic_softc *, size_t, uint32_t); 71 static void gpio_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t); 72 static int gpio_pic_find_pending_irqs(struct pic_softc *); 73 static void gpio_pic_establish_irq(struct pic_softc *, struct intrsource *); 74 75 const struct pic_ops gpio_pic_ops = { 76 .pic_unblock_irqs = gpio_pic_unblock_irqs, 77 .pic_block_irqs = gpio_pic_block_irqs, 78 .pic_find_pending_irqs = gpio_pic_find_pending_irqs, 79 .pic_establish_irq = gpio_pic_establish_irq, 80 .pic_source_name = NULL 81 }; 82 83 struct gpio_softc { 84 device_t gpio_dev; 85 struct pic_softc gpio_pic; 86 #if defined(IMX_GPIO_INTR_SPLIT) 87 struct intrsource *gpio_is_0_15; 88 struct intrsource *gpio_is_16_31; 89 #else 90 struct intrsource *gpio_is; 91 #endif 92 bus_space_tag_t gpio_memt; 93 bus_space_handle_t gpio_memh; 94 uint32_t gpio_enable_mask; 95 uint32_t gpio_edge_mask; 96 uint32_t gpio_level_mask; 97 #if NGPIO > 0 98 struct gpio_chipset_tag gpio_chipset; 99 gpio_pin_t gpio_pins[32]; 100 #endif 101 }; 102 103 static struct { 104 bus_space_tag_t iot; 105 struct { 106 bus_space_handle_t ioh; 107 struct gpio_softc *softc; 108 } unit[MAX_NGROUP]; 109 } gpio_handles; 110 111 extern struct cfdriver imxgpio_cd; 112 113 CFATTACH_DECL_NEW(imxgpio, 114 sizeof(struct gpio_softc), 115 imxgpio_match, imxgpio_attach, 116 NULL, NULL); 117 118 119 #define PIC_TO_SOFTC(pic) \ 120 ((struct gpio_softc *)((char *)(pic) - \ 121 offsetof(struct gpio_softc, gpio_pic))) 122 123 #define GPIO_READ(gpio, reg) \ 124 bus_space_read_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg)) 125 #define GPIO_WRITE(gpio, reg, val) \ 126 bus_space_write_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg), (val)) 127 128 void 129 gpio_pic_unblock_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) 130 { 131 struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); 132 KASSERT(irq_base == 0); 133 134 gpio->gpio_enable_mask |= irq_mask; 135 136 GPIO_WRITE(gpio, GPIO_ISR, irq_mask); 137 GPIO_WRITE(gpio, GPIO_IMR, gpio->gpio_enable_mask); 138 } 139 140 void 141 gpio_pic_block_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) 142 { 143 struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); 144 KASSERT(irq_base == 0); 145 146 gpio->gpio_enable_mask &= ~irq_mask; 147 GPIO_WRITE(gpio, GPIO_IMR, gpio->gpio_enable_mask); 148 } 149 150 int 151 gpio_pic_find_pending_irqs(struct pic_softc *pic) 152 { 153 struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); 154 uint32_t v; 155 uint32_t pending; 156 157 v = GPIO_READ(gpio, GPIO_ISR); 158 pending = (v & gpio->gpio_enable_mask); 159 if (pending == 0) 160 return 0; 161 162 /* 163 * Disable the pending interrupts. 164 */ 165 gpio->gpio_enable_mask &= ~pending; 166 GPIO_WRITE(gpio, GPIO_IMR, gpio->gpio_enable_mask); 167 168 /* 169 * If any of the sources are edge triggered, ack them now so 170 * we won't lose them. 171 */ 172 if (v & gpio->gpio_edge_mask) 173 GPIO_WRITE(gpio, GPIO_ISR, v & gpio->gpio_edge_mask); 174 175 /* 176 * Now find all the pending bits and mark them as pending. 177 */ 178 do { 179 int irq; 180 KASSERT(pending != 0); 181 irq = 31 - __builtin_clz(pending); 182 pending &= ~__BIT(irq); 183 184 const struct intrsource *is = pic->pic_sources[irq]; 185 if (is->is_type == IST_EDGE_BOTH) { 186 /* 187 * for both edge 188 */ 189 uint32_t icr_reg = GPIO_ICR1 + ((is->is_irq & 0x10) >> 2); 190 v = GPIO_READ(gpio, icr_reg); 191 uint32_t icr_shift = (is->is_irq & 0x0f) << 1; 192 uint32_t mask = (3 << icr_shift); 193 int gtype = __SHIFTOUT(v, mask); 194 if (gtype == GPIO_ICR_EDGE_RISING) 195 gtype = GPIO_ICR_EDGE_FALLING; 196 else if (gtype == GPIO_ICR_EDGE_FALLING) 197 gtype = GPIO_ICR_EDGE_RISING; 198 v &= ~mask; 199 v |= __SHIFTIN(gtype, mask); 200 GPIO_WRITE(gpio, icr_reg, v); 201 } 202 pic_mark_pending(&gpio->gpio_pic, irq); 203 } while (pending != 0); 204 205 return 1; 206 } 207 208 #define GPIO_TYPEMAP \ 209 ((GPIO_ICR_LEVEL_LOW << (2*IST_LEVEL_LOW)) | \ 210 (GPIO_ICR_LEVEL_HIGH << (2*IST_LEVEL_HIGH)) | \ 211 (GPIO_ICR_EDGE_RISING << (2*IST_EDGE_RISING)) | \ 212 (GPIO_ICR_EDGE_FALLING << (2*IST_EDGE_FALLING)) | \ 213 (GPIO_ICR_EDGE_RISING << (2*IST_EDGE_BOTH))) 214 215 void 216 gpio_pic_establish_irq(struct pic_softc *pic, struct intrsource *is) 217 { 218 struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); 219 KASSERT(is->is_irq < 32); 220 uint32_t irq_mask = __BIT(is->is_irq); 221 uint32_t v; 222 unsigned int icr_shift, icr_reg; 223 unsigned int gtype; 224 225 /* 226 * Make sure the irq isn't enabled and not asserting. 227 */ 228 gpio->gpio_enable_mask &= ~irq_mask; 229 GPIO_WRITE(gpio, GPIO_ISR, irq_mask); 230 GPIO_WRITE(gpio, GPIO_IMR, gpio->gpio_enable_mask); 231 /* 232 * Convert the type to a gpio type and figure out which bits in what 233 * register we have to tweak. 234 */ 235 gtype = (GPIO_TYPEMAP >> (2 * is->is_type)) & 3; 236 icr_shift = (is->is_irq & 0x0f) << 1; 237 icr_reg = GPIO_ICR1 + ((is->is_irq & 0x10) >> 2); 238 239 /* 240 * Set the interrupt type. 241 */ 242 v = GPIO_READ(gpio, icr_reg); 243 v &= ~(3 << icr_shift); 244 v |= gtype << icr_shift; 245 GPIO_WRITE(gpio, icr_reg, v); 246 247 /* 248 * Mark it as input. 249 */ 250 v = GPIO_READ(gpio, GPIO_DIR); 251 v &= ~irq_mask; 252 GPIO_WRITE(gpio, GPIO_DIR, v); 253 254 /* 255 * Now record the type of interrupt. 256 */ 257 if (gtype == GPIO_ICR_EDGE_RISING || gtype == GPIO_ICR_EDGE_FALLING) { 258 gpio->gpio_edge_mask |= irq_mask; 259 gpio->gpio_level_mask &= ~irq_mask; 260 } else { 261 gpio->gpio_edge_mask &= ~irq_mask; 262 gpio->gpio_level_mask |= irq_mask; 263 } 264 } 265 266 #if NGPIO > 0 267 268 static int 269 imxgpio_pin_read(void *arg, int pin) 270 { 271 struct gpio_softc * const gpio = arg; 272 273 return (GPIO_READ(gpio, GPIO_DR) >> pin) & 1; 274 } 275 276 static void 277 imxgpio_pin_write(void *arg, int pin, int value) 278 { 279 struct gpio_softc * const gpio = arg; 280 uint32_t mask = 1 << pin; 281 uint32_t old, new; 282 283 old = GPIO_READ(gpio, GPIO_DR); 284 if (value) 285 new = old | mask; 286 else 287 new = old & ~mask; 288 289 if (old != new) 290 GPIO_WRITE(gpio, GPIO_DR, new); 291 } 292 293 static void 294 imxgpio_pin_ctl(void *arg, int pin, int flags) 295 { 296 struct gpio_softc * const gpio = arg; 297 uint32_t mask = 1 << pin; 298 uint32_t old, new; 299 300 old = GPIO_READ(gpio, GPIO_DIR); 301 new = old; 302 switch (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { 303 case GPIO_PIN_INPUT: new &= ~mask; break; 304 case GPIO_PIN_OUTPUT: new |= mask; break; 305 default: return; 306 } 307 if (old != new) 308 GPIO_WRITE(gpio, GPIO_DIR, new); 309 } 310 311 static void 312 gpio_defer(device_t self) 313 { 314 struct gpio_softc * const gpio = device_private(self); 315 struct gpio_chipset_tag * const gp = &gpio->gpio_chipset; 316 struct gpiobus_attach_args gba; 317 gpio_pin_t *pins; 318 uint32_t mask, dir, value; 319 int pin; 320 321 gp->gp_cookie = gpio; 322 gp->gp_pin_read = imxgpio_pin_read; 323 gp->gp_pin_write = imxgpio_pin_write; 324 gp->gp_pin_ctl = imxgpio_pin_ctl; 325 326 gba.gba_gc = gp; 327 gba.gba_pins = gpio->gpio_pins; 328 gba.gba_npins = __arraycount(gpio->gpio_pins); 329 330 dir = GPIO_READ(gpio, GPIO_DIR); 331 value = GPIO_READ(gpio, GPIO_DR); 332 for (pin = 0, mask = 1, pins = gpio->gpio_pins; 333 pin < 32; pin++, mask <<= 1, pins++) { 334 pins->pin_num = pin; 335 if ((gpio->gpio_edge_mask|gpio->gpio_level_mask) & mask) 336 pins->pin_caps = GPIO_PIN_INPUT; 337 else 338 pins->pin_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT; 339 pins->pin_flags = 340 (dir & mask) ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT; 341 pins->pin_state = 342 (value & mask) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; 343 } 344 345 config_found_ia(self, "gpiobus", &gba, gpiobus_print); 346 } 347 #endif /* NGPIO > 0 */ 348 349 void 350 imxgpio_attach_common(device_t self, bus_space_tag_t iot, 351 bus_space_handle_t ioh, int index, int intr, int irqbase) 352 { 353 struct gpio_softc * const gpio = device_private(self); 354 355 gpio->gpio_dev = self; 356 gpio->gpio_memt = iot; 357 gpio->gpio_memh = ioh; 358 359 if (irqbase > 0) { 360 gpio->gpio_pic.pic_ops = &gpio_pic_ops; 361 strlcpy(gpio->gpio_pic.pic_name, device_xname(self), 362 sizeof(gpio->gpio_pic.pic_name)); 363 gpio->gpio_pic.pic_maxsources = 32; 364 365 pic_add(&gpio->gpio_pic, irqbase); 366 367 aprint_normal(": interrupts %d..%d", 368 irqbase, irqbase + GPIO_NPINS - 1); 369 370 #if defined(IMX_GPIO_INTR_SPLIT) 371 gpio->gpio_is_0_15 = intr_establish(intr, 372 IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); 373 KASSERT( gpio->gpio_is_0_15 != NULL ); 374 gpio->gpio_is_16_31 = intr_establish(intr + 1, 375 IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); 376 KASSERT( gpio->gpio_is_16_31 != NULL ); 377 #else 378 gpio->gpio_is = intr_establish(intr, 379 IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); 380 KASSERT( gpio->gpio_is != NULL ); 381 #endif 382 } 383 aprint_normal("\n"); 384 385 386 gpio_handles.iot = iot; 387 gpio_handles.unit[index].softc = gpio; 388 gpio_handles.unit[index].ioh = ioh; 389 390 #if NGPIO > 0 391 config_interrupts(self, gpio_defer); 392 #endif 393 } 394 395 #define GPIO_GROUP_READ(index,offset) \ 396 bus_space_read_4(gpio_handles.iot, gpio_handles.unit[index].ioh, \ 397 (offset)) 398 #define GPIO_GROUP_WRITE(index,offset,value) \ 399 bus_space_write_4(gpio_handles.iot, gpio_handles.unit[index].ioh, \ 400 (offset), (value)) 401 402 void 403 gpio_set_direction(u_int gpio, u_int dir) 404 { 405 int index = gpio / GPIO_NPINS; 406 int bit = gpio % GPIO_NPINS; 407 uint32_t reg; 408 409 KDASSERT(index < imxgpio_ngroups); 410 411 /* XXX lock */ 412 413 414 reg = GPIO_GROUP_READ(index, GPIO_DIR); 415 if (dir == GPIO_DIR_OUT) 416 reg |= __BIT(bit); 417 else 418 reg &= ~__BIT(bit); 419 GPIO_GROUP_WRITE(index, GPIO_DIR, reg); 420 421 /* XXX unlock */ 422 } 423 424 425 void 426 gpio_data_write(u_int gpio, u_int value) 427 { 428 int index = gpio / GPIO_NPINS; 429 int bit = gpio % GPIO_NPINS; 430 uint32_t reg; 431 432 KDASSERT(index < imxgpio_ngroups); 433 434 /* XXX lock */ 435 reg = GPIO_GROUP_READ(index, GPIO_DR); 436 if (value) 437 reg |= __BIT(bit); 438 else 439 reg &= ~__BIT(bit); 440 GPIO_GROUP_WRITE(index, GPIO_DR, reg); 441 442 /* XXX unlock */ 443 } 444 445 bool 446 gpio_data_read(u_int gpio) 447 { 448 int index = gpio / GPIO_NPINS; 449 int bit = gpio % GPIO_NPINS; 450 uint32_t reg; 451 452 KDASSERT(index < imxgpio_ngroups); 453 454 reg = GPIO_GROUP_READ(index, GPIO_DR); 455 456 return reg & __BIT(bit) ? true : false; 457 } 458