1 /* 2 * i.MX processors GPIO emulation. 3 * 4 * Copyright (C) 2015 Jean-Christophe Dubois <jcd@tribudubois.net> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 or 9 * (at your option) version 3 of the License. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "hw/gpio/imx_gpio.h" 21 22 #ifndef DEBUG_IMX_GPIO 23 #define DEBUG_IMX_GPIO 0 24 #endif 25 26 typedef enum IMXGPIOLevel { 27 IMX_GPIO_LEVEL_LOW = 0, 28 IMX_GPIO_LEVEL_HIGH = 1, 29 } IMXGPIOLevel; 30 31 #define DPRINTF(fmt, args...) \ 32 do { \ 33 if (DEBUG_IMX_GPIO) { \ 34 fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_GPIO, \ 35 __func__, ##args); \ 36 } \ 37 } while (0) 38 39 static const char *imx_gpio_reg_name(uint32_t reg) 40 { 41 switch (reg) { 42 case DR_ADDR: 43 return "DR"; 44 case GDIR_ADDR: 45 return "GDIR"; 46 case PSR_ADDR: 47 return "PSR"; 48 case ICR1_ADDR: 49 return "ICR1"; 50 case ICR2_ADDR: 51 return "ICR2"; 52 case IMR_ADDR: 53 return "IMR"; 54 case ISR_ADDR: 55 return "ISR"; 56 case EDGE_SEL_ADDR: 57 return "EDGE_SEL"; 58 default: 59 return "[?]"; 60 } 61 } 62 63 static void imx_gpio_update_int(IMXGPIOState *s) 64 { 65 if (s->has_upper_pin_irq) { 66 qemu_set_irq(s->irq[0], (s->isr & s->imr & 0x0000FFFF) ? 1 : 0); 67 qemu_set_irq(s->irq[1], (s->isr & s->imr & 0xFFFF0000) ? 1 : 0); 68 } else { 69 qemu_set_irq(s->irq[0], (s->isr & s->imr) ? 1 : 0); 70 } 71 } 72 73 static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level) 74 { 75 /* if this signal isn't configured as an input signal, nothing to do */ 76 if (!extract32(s->gdir, line, 1)) { 77 return; 78 } 79 80 /* When set, EDGE_SEL overrides the ICR config */ 81 if (extract32(s->edge_sel, line, 1)) { 82 /* we detect interrupt on rising and falling edge */ 83 if (extract32(s->psr, line, 1) != level) { 84 /* level changed */ 85 s->isr = deposit32(s->isr, line, 1, 1); 86 } 87 } else if (extract64(s->icr, 2*line + 1, 1)) { 88 /* interrupt is edge sensitive */ 89 if (extract32(s->psr, line, 1) != level) { 90 /* level changed */ 91 if (extract64(s->icr, 2*line, 1) != level) { 92 s->isr = deposit32(s->isr, line, 1, 1); 93 } 94 } 95 } else { 96 /* interrupt is level sensitive */ 97 if (extract64(s->icr, 2*line, 1) == level) { 98 s->isr = deposit32(s->isr, line, 1, 1); 99 } 100 } 101 } 102 103 static void imx_gpio_set(void *opaque, int line, int level) 104 { 105 IMXGPIOState *s = IMX_GPIO(opaque); 106 IMXGPIOLevel imx_level = level ? IMX_GPIO_LEVEL_HIGH : IMX_GPIO_LEVEL_LOW; 107 108 imx_gpio_set_int_line(s, line, imx_level); 109 110 /* this is an input signal, so set PSR */ 111 s->psr = deposit32(s->psr, line, 1, imx_level); 112 113 imx_gpio_update_int(s); 114 } 115 116 static void imx_gpio_set_all_int_lines(IMXGPIOState *s) 117 { 118 int i; 119 120 for (i = 0; i < IMX_GPIO_PIN_COUNT; i++) { 121 IMXGPIOLevel imx_level = extract32(s->psr, i, 1); 122 imx_gpio_set_int_line(s, i, imx_level); 123 } 124 125 imx_gpio_update_int(s); 126 } 127 128 static inline void imx_gpio_set_all_output_lines(IMXGPIOState *s) 129 { 130 int i; 131 132 for (i = 0; i < IMX_GPIO_PIN_COUNT; i++) { 133 /* 134 * if the line is set as output, then forward the line 135 * level to its user. 136 */ 137 if (extract32(s->gdir, i, 1) && s->output[i]) { 138 qemu_set_irq(s->output[i], extract32(s->dr, i, 1)); 139 } 140 } 141 } 142 143 static uint64_t imx_gpio_read(void *opaque, hwaddr offset, unsigned size) 144 { 145 IMXGPIOState *s = IMX_GPIO(opaque); 146 uint32_t reg_value = 0; 147 148 switch (offset) { 149 case DR_ADDR: 150 /* 151 * depending on the "line" configuration, the bit values 152 * are coming either from DR or PSR 153 */ 154 reg_value = (s->dr & s->gdir) | (s->psr & ~s->gdir); 155 break; 156 157 case GDIR_ADDR: 158 reg_value = s->gdir; 159 break; 160 161 case PSR_ADDR: 162 reg_value = s->psr & ~s->gdir; 163 break; 164 165 case ICR1_ADDR: 166 reg_value = extract64(s->icr, 0, 32); 167 break; 168 169 case ICR2_ADDR: 170 reg_value = extract64(s->icr, 32, 32); 171 break; 172 173 case IMR_ADDR: 174 reg_value = s->imr; 175 break; 176 177 case ISR_ADDR: 178 reg_value = s->isr; 179 break; 180 181 case EDGE_SEL_ADDR: 182 if (s->has_edge_sel) { 183 reg_value = s->edge_sel; 184 } else { 185 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: EDGE_SEL register not " 186 "present on this version of GPIO device\n", 187 TYPE_IMX_GPIO, __func__); 188 } 189 break; 190 191 default: 192 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" 193 HWADDR_PRIx "\n", TYPE_IMX_GPIO, __func__, offset); 194 break; 195 } 196 197 DPRINTF("(%s) = 0x%" PRIx32 "\n", imx_gpio_reg_name(offset), reg_value); 198 199 return reg_value; 200 } 201 202 static void imx_gpio_write(void *opaque, hwaddr offset, uint64_t value, 203 unsigned size) 204 { 205 IMXGPIOState *s = IMX_GPIO(opaque); 206 207 DPRINTF("(%s, value = 0x%" PRIx32 ")\n", imx_gpio_reg_name(offset), 208 (uint32_t)value); 209 210 switch (offset) { 211 case DR_ADDR: 212 s->dr = value; 213 imx_gpio_set_all_output_lines(s); 214 break; 215 216 case GDIR_ADDR: 217 s->gdir = value; 218 imx_gpio_set_all_output_lines(s); 219 imx_gpio_set_all_int_lines(s); 220 break; 221 222 case ICR1_ADDR: 223 s->icr = deposit64(s->icr, 0, 32, value); 224 imx_gpio_set_all_int_lines(s); 225 break; 226 227 case ICR2_ADDR: 228 s->icr = deposit64(s->icr, 32, 32, value); 229 imx_gpio_set_all_int_lines(s); 230 break; 231 232 case IMR_ADDR: 233 s->imr = value; 234 imx_gpio_update_int(s); 235 break; 236 237 case ISR_ADDR: 238 s->isr |= ~value; 239 imx_gpio_set_all_int_lines(s); 240 break; 241 242 case EDGE_SEL_ADDR: 243 if (s->has_edge_sel) { 244 s->edge_sel = value; 245 imx_gpio_set_all_int_lines(s); 246 } else { 247 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: EDGE_SEL register not " 248 "present on this version of GPIO device\n", 249 TYPE_IMX_GPIO, __func__); 250 } 251 break; 252 253 default: 254 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" 255 HWADDR_PRIx "\n", TYPE_IMX_GPIO, __func__, offset); 256 break; 257 } 258 259 return; 260 } 261 262 static const MemoryRegionOps imx_gpio_ops = { 263 .read = imx_gpio_read, 264 .write = imx_gpio_write, 265 .valid.min_access_size = 4, 266 .valid.max_access_size = 4, 267 .endianness = DEVICE_NATIVE_ENDIAN, 268 }; 269 270 static const VMStateDescription vmstate_imx_gpio = { 271 .name = TYPE_IMX_GPIO, 272 .version_id = 1, 273 .minimum_version_id = 1, 274 .minimum_version_id_old = 1, 275 .fields = (VMStateField[]) { 276 VMSTATE_UINT32(dr, IMXGPIOState), 277 VMSTATE_UINT32(gdir, IMXGPIOState), 278 VMSTATE_UINT32(psr, IMXGPIOState), 279 VMSTATE_UINT64(icr, IMXGPIOState), 280 VMSTATE_UINT32(imr, IMXGPIOState), 281 VMSTATE_UINT32(isr, IMXGPIOState), 282 VMSTATE_BOOL(has_edge_sel, IMXGPIOState), 283 VMSTATE_UINT32(edge_sel, IMXGPIOState), 284 VMSTATE_END_OF_LIST() 285 } 286 }; 287 288 static Property imx_gpio_properties[] = { 289 DEFINE_PROP_BOOL("has-edge-sel", IMXGPIOState, has_edge_sel, true), 290 DEFINE_PROP_BOOL("has-upper-pin-irq", IMXGPIOState, has_upper_pin_irq, 291 false), 292 DEFINE_PROP_END_OF_LIST(), 293 }; 294 295 static void imx_gpio_reset(DeviceState *dev) 296 { 297 IMXGPIOState *s = IMX_GPIO(dev); 298 299 s->dr = 0; 300 s->gdir = 0; 301 s->psr = 0; 302 s->icr = 0; 303 s->imr = 0; 304 s->isr = 0; 305 s->edge_sel = 0; 306 307 imx_gpio_set_all_output_lines(s); 308 imx_gpio_update_int(s); 309 } 310 311 static void imx_gpio_realize(DeviceState *dev, Error **errp) 312 { 313 IMXGPIOState *s = IMX_GPIO(dev); 314 315 memory_region_init_io(&s->iomem, OBJECT(s), &imx_gpio_ops, s, 316 TYPE_IMX_GPIO, IMX_GPIO_MEM_SIZE); 317 318 qdev_init_gpio_in(DEVICE(s), imx_gpio_set, IMX_GPIO_PIN_COUNT); 319 qdev_init_gpio_out(DEVICE(s), s->output, IMX_GPIO_PIN_COUNT); 320 321 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[0]); 322 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[1]); 323 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); 324 } 325 326 static void imx_gpio_class_init(ObjectClass *klass, void *data) 327 { 328 DeviceClass *dc = DEVICE_CLASS(klass); 329 330 dc->realize = imx_gpio_realize; 331 dc->reset = imx_gpio_reset; 332 dc->props = imx_gpio_properties; 333 dc->vmsd = &vmstate_imx_gpio; 334 dc->desc = "i.MX GPIO controller"; 335 } 336 337 static const TypeInfo imx_gpio_info = { 338 .name = TYPE_IMX_GPIO, 339 .parent = TYPE_SYS_BUS_DEVICE, 340 .instance_size = sizeof(IMXGPIOState), 341 .class_init = imx_gpio_class_init, 342 }; 343 344 static void imx_gpio_register_types(void) 345 { 346 type_register_static(&imx_gpio_info); 347 } 348 349 type_init(imx_gpio_register_types) 350