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