1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2022 Microchip 4 * 5 * Driver for AT91 PIOBU 6 */ 7 8 #include <assert.h> 9 #include <drivers/atmel_rtc.h> 10 #include <drivers/gpio.h> 11 #include <dt-bindings/gpio/atmel,piobu.h> 12 #include <io.h> 13 #include <kernel/boot.h> 14 #include <kernel/dt.h> 15 #include <kernel/dt_driver.h> 16 #include <kernel/interrupt.h> 17 #include <kernel/pm.h> 18 #include <libfdt.h> 19 #include <mm/core_memprot.h> 20 21 #define SECUMOD_MAX_PINS 8 22 #define SECUMOD_PIN_MASK (BIT(SECUMOD_MAX_PINS) - 1) 23 #define SECUMOD_PIN_SHIFT 16 24 #define SECUMOD_PIN_VAL(pin) BIT(SECUMOD_PIN_SHIFT + (pin)) 25 26 #define DT_GPIO_CELLS 2 27 28 #define SECUMOD_CR 0x0 29 #define SECUMOD_CR_KEY_SHIFT 16 30 #define SECUMOD_CR_KEY SHIFT_U32(0x89CA, SECUMOD_CR_KEY_SHIFT) 31 #define SECUMOD_CR_BACKUP BIT(0) 32 #define SECUMOD_CR_NORMAL BIT(1) 33 34 #define SECUMOD_SR 0x8 35 #define SECUMOD_SR_JTAG BIT(3) 36 #define SECUMOD_SR_TST_PIN BIT(2) 37 38 #define SECUMOD_SCR 0x10 39 40 #define SECUMOD_PIOBU(x) (0x18 + (x) * 0x4) 41 #define SECUMOD_PIOBU_AFV_MASK GENMASK_32(3, 0) 42 #define SECUMOD_PIOBU_RFV_SHIFT 4 43 #define SECUMOD_PIOBU_OUTPUT BIT(8) 44 #define SECUMOD_PIOBU_SOD BIT(9) 45 #define SECUMOD_PIOBU_PDS BIT(10) 46 #define SECUMOD_PIOBU_PULLUP_SHIFT 12 47 #define SECUMOD_PIOBU_SWITCH_SHIFT 15 48 49 #define SECUMOD_JTAGCR 0x68 50 #define SECUMOD_JTAGCR_FNTRST 0x1 51 52 #define SECUMOD_BMPR 0x7C 53 #define SECUMOD_NMPR 0x80 54 #define SECUMOD_NIEPR 0x84 55 #define SECUMOD_NIDPR 0x88 56 #define SECUMOD_NIMPR 0x8C 57 #define SECUMOD_WKPR 0x90 58 59 static vaddr_t secumod_base; 60 static uint32_t gpio_protected; 61 static struct gpio_chip secumod_chip; 62 63 /* 64 * Get value from GPIO controller 65 * chip: pointer to GPIO controller chip instance 66 * gpio_pin: pin from which value needs to be read 67 * Return target GPIO pin level. 68 */ 69 static enum gpio_level secumod_gpio_get_value(struct gpio_chip *chip __unused, 70 unsigned int gpio_pin) 71 { 72 vaddr_t piobu_addr = 0; 73 uint32_t piobu = 0; 74 75 assert(gpio_pin < SECUMOD_MAX_PINS && 76 !(gpio_protected & BIT32(gpio_pin))); 77 78 piobu_addr = secumod_base + SECUMOD_PIOBU(gpio_pin); 79 piobu = io_read32(piobu_addr); 80 81 if (piobu & SECUMOD_PIOBU_PDS) 82 return GPIO_LEVEL_HIGH; 83 else 84 return GPIO_LEVEL_LOW; 85 } 86 87 /* 88 * Set value for GPIO controller 89 * chip: pointer to GPIO controller chip instance 90 * gpio_pin: pin to which value needs to be written 91 * value: Level state for the target pin 92 */ 93 static void secumod_gpio_set_value(struct gpio_chip *chip __unused, 94 unsigned int gpio_pin, enum gpio_level value) 95 { 96 vaddr_t piobu_addr = 0; 97 98 assert(gpio_pin < SECUMOD_MAX_PINS && 99 !(gpio_protected & BIT32(gpio_pin))); 100 101 piobu_addr = secumod_base + SECUMOD_PIOBU(gpio_pin); 102 103 if (value == GPIO_LEVEL_HIGH) 104 io_setbits32(piobu_addr, SECUMOD_PIOBU_SOD); 105 else 106 io_clrbits32(piobu_addr, SECUMOD_PIOBU_SOD); 107 } 108 109 /* 110 * Get direction from GPIO controller 111 * chip: pointer to GPIO controller chip instance 112 * gpio_pin: pin from which direction needs to be read 113 */ 114 static enum gpio_dir secumod_gpio_get_direction(struct gpio_chip *chip __unused, 115 unsigned int gpio_pin) 116 { 117 vaddr_t piobu_addr = 0; 118 uint32_t piobu = 0; 119 120 assert(gpio_pin < SECUMOD_MAX_PINS && 121 !(gpio_protected & BIT32(gpio_pin))); 122 123 piobu_addr = secumod_base + SECUMOD_PIOBU(gpio_pin); 124 piobu = io_read32(piobu_addr); 125 126 if (piobu & SECUMOD_PIOBU_OUTPUT) 127 return GPIO_DIR_OUT; 128 else 129 return GPIO_DIR_IN; 130 } 131 132 /* 133 * Set direction for GPIO controller 134 * chip: pointer to GPIO controller chip instance 135 * gpio_pin: pin on which direction needs to be set 136 * direction: direction which needs to be set on pin 137 */ 138 static void secumod_gpio_set_direction(struct gpio_chip *chip __unused, 139 unsigned int gpio_pin, 140 enum gpio_dir direction) 141 { 142 vaddr_t piobu_addr = 0; 143 144 assert(gpio_pin < SECUMOD_MAX_PINS && 145 !(gpio_protected & BIT32(gpio_pin))); 146 147 piobu_addr = secumod_base + SECUMOD_PIOBU(gpio_pin); 148 149 if (direction == GPIO_DIR_OUT) 150 io_setbits32(piobu_addr, SECUMOD_PIOBU_OUTPUT); 151 else 152 io_clrbits32(piobu_addr, SECUMOD_PIOBU_OUTPUT); 153 } 154 155 /* 156 * Get interrupt from GPIO controller 157 * chip: pointer to GPIO controller chip instance 158 * gpio_pin: pin from which interrupt value needs to be read 159 */ 160 static enum gpio_interrupt 161 secumod_gpio_get_interrupt(struct gpio_chip *chip __unused, 162 unsigned int gpio_pin) 163 { 164 vaddr_t nimpr_addr = secumod_base + SECUMOD_NIMPR; 165 uint32_t data = 0; 166 167 assert(gpio_pin < SECUMOD_MAX_PINS && 168 !(gpio_protected & BIT32(gpio_pin))); 169 170 data = io_read32(nimpr_addr); 171 172 if (data & SECUMOD_PIN_VAL(gpio_pin)) 173 return GPIO_INTERRUPT_ENABLE; 174 else 175 return GPIO_INTERRUPT_DISABLE; 176 } 177 178 /* 179 * Set interrupt event for GPIO controller 180 * chip: pointer to GPIO controller chip instance 181 * gpio_pin: pin on which interrupt value needs to be set 182 * interrupt: interrupt value which needs to be set on pin 183 */ 184 static void secumod_gpio_set_interrupt(struct gpio_chip *chip __unused, 185 unsigned int gpio_pin, 186 enum gpio_interrupt interrupt) 187 { 188 vaddr_t niepr_addr = secumod_base + SECUMOD_NIEPR; 189 190 assert(gpio_pin < SECUMOD_MAX_PINS && 191 !(gpio_protected & BIT32(gpio_pin))); 192 193 if (interrupt == GPIO_INTERRUPT_ENABLE) 194 io_setbits32(niepr_addr, SECUMOD_PIN_VAL(gpio_pin)); 195 else 196 io_clrbits32(niepr_addr, SECUMOD_PIN_VAL(gpio_pin)); 197 } 198 199 static const struct gpio_ops atmel_piobu_ops = { 200 .get_direction = secumod_gpio_get_direction, 201 .set_direction = secumod_gpio_set_direction, 202 .get_value = secumod_gpio_get_value, 203 .set_value = secumod_gpio_set_value, 204 .get_interrupt = secumod_gpio_get_interrupt, 205 .set_interrupt = secumod_gpio_set_interrupt, 206 }; 207 208 static TEE_Result secumod_dt_get(struct dt_pargs *pargs, void *data, 209 struct gpio **out_gpio) 210 { 211 TEE_Result res = TEE_ERROR_GENERIC; 212 struct gpio *gpio = NULL; 213 struct gpio_chip *chip = data; 214 215 res = gpio_dt_alloc_pin(pargs, &gpio); 216 if (res) 217 return res; 218 219 if (gpio_protected & BIT32(gpio->pin)) { 220 free(gpio); 221 return TEE_ERROR_GENERIC; 222 } 223 224 gpio->chip = chip; 225 *out_gpio = gpio; 226 227 return TEE_SUCCESS; 228 } 229 230 static enum itr_return secumod_it_handler(struct itr_handler *handler __unused) 231 { 232 int i = 0; 233 struct optee_rtc_time tm = { }; 234 TEE_Result res = TEE_ERROR_GENERIC; 235 uint32_t sr = io_read32(secumod_base + SECUMOD_SR); 236 237 for (i = 0; i < SECUMOD_MAX_PINS; i++) { 238 if (sr & SECUMOD_PIN_VAL(i)) 239 EMSG("Detected tampering on pin %d", i); 240 } 241 242 if (sr & SECUMOD_SR_JTAG) 243 EMSG("JTAG tampering attempt"); 244 245 if (sr & SECUMOD_SR_TST_PIN) 246 EMSG("Test pin tampering attempt"); 247 248 res = atmel_rtc_get_tamper_timestamp(&tm); 249 if (!res) { 250 EMSG("Date of tampering: %02"PRIu32"/%02"PRIu32"/%02"PRIu32"", 251 tm.tm_mday, tm.tm_mon, tm.tm_year); 252 EMSG("Time of tampering: %02"PRIu32":%02"PRIu32":%02"PRIu32"", 253 tm.tm_hour, tm.tm_min, tm.tm_sec); 254 } 255 256 io_write32(secumod_base + SECUMOD_SCR, 257 SECUMOD_PIN_MASK << SECUMOD_PIN_SHIFT); 258 259 panic("Tampering detected, system halted"); 260 261 return ITRR_HANDLED; 262 } 263 264 static struct itr_handler secumod_itr_handler = { 265 .it = AT91C_ID_SECUMOD, 266 .handler = secumod_it_handler, 267 }; 268 269 static void secumod_interrupt_init(void) 270 { 271 TEE_Result res = TEE_ERROR_GENERIC; 272 273 secumod_itr_handler.chip = interrupt_get_main_chip(); 274 275 res = interrupt_add_configure_handler(&secumod_itr_handler, 276 IRQ_TYPE_LEVEL_HIGH, 7); 277 if (res) 278 panic(); 279 280 interrupt_enable(secumod_itr_handler.chip, secumod_itr_handler.it); 281 } 282 283 static void secumod_cfg_input_pio(uint8_t gpio_pin, uint32_t config) 284 { 285 vaddr_t piobu_addr = 0; 286 uint8_t afv = 0; 287 uint8_t rfv = 0; 288 uint8_t pull_mode = PIOBU_PIN_PULL_NONE; 289 uint8_t def_level = PIOBU_PIN_DEF_LEVEL_LOW; 290 291 assert(gpio_pin < SECUMOD_MAX_PINS); 292 293 piobu_addr = secumod_base + SECUMOD_PIOBU(gpio_pin); 294 295 /* Set GPIO as input */ 296 io_clrbits32(piobu_addr, SECUMOD_PIOBU_OUTPUT); 297 298 afv = PIOBU_PIN_AFV(config); 299 rfv = PIOBU_PIN_RFV(config); 300 pull_mode = PIOBU_PIN_PULL_MODE(config); 301 def_level = PIOBU_PIN_DEF_LEVEL(config); 302 303 io_write32(piobu_addr, afv | rfv << SECUMOD_PIOBU_RFV_SHIFT | 304 pull_mode << SECUMOD_PIOBU_PULLUP_SHIFT | 305 def_level << SECUMOD_PIOBU_SWITCH_SHIFT); 306 307 /* Enable Tampering Interrupt */ 308 secumod_gpio_set_interrupt(&secumod_chip, gpio_pin, 309 GPIO_INTERRUPT_ENABLE); 310 311 /* Enable Intrusion Detection */ 312 io_setbits32(secumod_base + SECUMOD_NMPR, SECUMOD_PIN_VAL(gpio_pin)); 313 314 /* Enable Wakeup */ 315 if (PIOBU_PIN_WAKEUP(config)) 316 io_setbits32(secumod_base + SECUMOD_WKPR, 317 SECUMOD_PIN_VAL(gpio_pin)); 318 319 gpio_protected |= BIT32(gpio_pin); 320 } 321 322 static void secumod_hw_init(const void *fdt, int node) 323 { 324 int i = 0; 325 int len = 0; 326 uint8_t gpio_pin = 0; 327 uint32_t config = 0; 328 const uint32_t *prop = NULL; 329 330 /* Disable JTAG Reset and Debug */ 331 io_write32(secumod_base + SECUMOD_JTAGCR, SECUMOD_JTAGCR_FNTRST); 332 333 /* Switch IOs to normal mode */ 334 io_write32(secumod_base + SECUMOD_CR, SECUMOD_CR_KEY | 335 SECUMOD_CR_NORMAL); 336 337 /* Clear all detection intrusion in normal mode */ 338 io_write32(secumod_base + SECUMOD_NMPR, 0); 339 340 /* Clear Alarms */ 341 io_write32(secumod_base + SECUMOD_SCR, 342 SECUMOD_PIN_MASK << SECUMOD_PIN_SHIFT); 343 344 /* Configure each IOs */ 345 prop = fdt_getprop(fdt, node, "gpios", &len); 346 if (!prop) 347 return; 348 349 len /= sizeof(uint32_t); 350 for (i = 0; i < len; i += DT_GPIO_CELLS) { 351 gpio_pin = fdt32_to_cpu(prop[i]); 352 config = fdt32_to_cpu(prop[i + 1]); 353 354 secumod_cfg_input_pio(gpio_pin, config); 355 } 356 } 357 358 #ifdef CFG_PM_ARM32 359 static TEE_Result piobu_pm(enum pm_op op, uint32_t pm_hint __unused, 360 const struct pm_callback_handle *hdl __unused) 361 { 362 switch (op) { 363 case PM_OP_RESUME: 364 io_write32(secumod_base + SECUMOD_CR, SECUMOD_CR_KEY | 365 SECUMOD_CR_NORMAL); 366 break; 367 case PM_OP_SUSPEND: 368 /* Enter backup mode before suspending */ 369 io_write32(secumod_base + SECUMOD_CR, SECUMOD_CR_KEY | 370 SECUMOD_CR_BACKUP); 371 break; 372 default: 373 panic("Invalid PM operation"); 374 } 375 376 return TEE_SUCCESS; 377 } 378 379 static void piobu_register_pm(void) 380 { 381 register_pm_driver_cb(piobu_pm, NULL, "piobu"); 382 } 383 #else 384 static void piobu_register_pm(void) {} 385 #endif 386 387 static TEE_Result atmel_secumod_probe(const void *fdt, int node, 388 const void *compat_data __unused) 389 { 390 size_t size = 0; 391 392 if (secumod_base) 393 return TEE_ERROR_GENERIC; 394 395 if (dt_map_dev(fdt, node, &secumod_base, &size, DT_MAP_AUTO) < 0) 396 return TEE_ERROR_GENERIC; 397 398 secumod_hw_init(fdt, node); 399 secumod_interrupt_init(); 400 401 secumod_chip.ops = &atmel_piobu_ops; 402 403 piobu_register_pm(); 404 405 assert(gpio_ops_is_valid(&atmel_piobu_ops)); 406 407 return gpio_register_provider(fdt, node, secumod_dt_get, &secumod_chip); 408 } 409 410 static const struct dt_device_match atmel_secumod_match_table[] = { 411 { .compatible = "atmel,sama5d2-secumod" }, 412 { } 413 }; 414 415 DEFINE_DT_DRIVER(atmel_secumod_dt_driver) = { 416 .name = "atmel_secumod", 417 .type = DT_DRIVER_NOTYPE, 418 .match_table = atmel_secumod_match_table, 419 .probe = atmel_secumod_probe, 420 }; 421