static void __dead2 hikey_system_off(void) { NOTICE("%s: off system\n", __func__); /* Pull down GPIO_0_0 to trigger PMIC shutdown */ mmio_write_32(0xF8001810, 0x2); /* Pinmux */ mmio_write_8(0xF8011400, 1); /* Pin direction */ mmio_write_8(0xF8011004, 0); /* Pin output value */ /* Wait for 2s to power off system by PMIC */ sp804_timer_init(SP804_TIMER0_BASE, 10, 192); mdelay(2000); /* * PMIC shutdown depends on two conditions: GPIO_0_0 (PWR_HOLD) low, * and VBUS_DET < 3.6V. For HiKey, VBUS_DET is connected to VDD_4V2 * through Jumper 1-2. So, to complete shutdown, user needs to manually * remove Jumper 1-2. */ NOTICE("+------------------------------------------+\n"); NOTICE("| IMPORTANT: Remove Jumper 1-2 to shutdown |\n"); NOTICE("| DANGER: SoC is still burning. DANGER! |\n"); NOTICE("| Board will be reboot to avoid overheat |\n"); NOTICE("+------------------------------------------+\n"); /* Send the system reset request */ mmio_write_32(AO_SC_SYS_STAT0, 0x48698284); wfi(); panic(); }
static int uniphier_emmc_load_image(uintptr_t host_base, uint32_t dev_addr, unsigned long load_addr, uint32_t block_cnt) { struct uniphier_mmc_cmd cmd = {0}; uint8_t tmp; assert((load_addr >> 32) == 0); mmio_write_32(host_base + SDHCI_DMA_ADDRESS, load_addr); mmio_write_16(host_base + SDHCI_BLOCK_SIZE, SDHCI_MAKE_BLKSZ(7, 512)); mmio_write_16(host_base + SDHCI_BLOCK_COUNT, block_cnt); tmp = mmio_read_8(host_base + SDHCI_HOST_CONTROL); tmp &= ~SDHCI_CTRL_DMA_MASK; tmp |= SDHCI_CTRL_SDMA; mmio_write_8(host_base + SDHCI_HOST_CONTROL, tmp); tmp = mmio_read_8(host_base + SDHCI_BLOCK_GAP_CONTROL); tmp &= ~1; /* clear Stop At Block Gap Request */ mmio_write_8(host_base + SDHCI_BLOCK_GAP_CONTROL, tmp); cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = dev_addr; cmd.is_data = 1; return uniphier_emmc_send_cmd(host_base, &cmd); }
/* * In order to write GPIODATA, the corresponding bits in the mask, resulting * from the address bus, PADDR[9:2], must be HIGH. Otherwise the bit values * remain unchanged by the write. */ static void pl061_set_value(int gpio, int value) { uintptr_t base_addr; int offset; assert((gpio >= 0) && (gpio < PLAT_PL061_MAX_GPIOS)); base_addr = pl061_reg_base[gpio / GPIOS_PER_PL061]; offset = gpio % GPIOS_PER_PL061; if (value == GPIO_LEVEL_HIGH) mmio_write_8(base_addr + BIT(offset + 2), BIT(offset)); else mmio_write_8(base_addr + BIT(offset + 2), 0); }
static void pl061_set_direction(int gpio, int direction) { uintptr_t base_addr; unsigned int data, offset; assert((gpio >= 0) && (gpio < PLAT_PL061_MAX_GPIOS)); base_addr = pl061_reg_base[gpio / GPIOS_PER_PL061]; offset = gpio % GPIOS_PER_PL061; if (direction == GPIO_DIR_OUT) { data = mmio_read_8(base_addr + PL061_GPIO_DIR) | BIT(offset); mmio_write_8(base_addr + PL061_GPIO_DIR, data); } else { data = mmio_read_8(base_addr + PL061_GPIO_DIR) & ~BIT(offset); mmio_write_8(base_addr + PL061_GPIO_DIR, data); } }
/* * Make sure that the interrupt's group is set before expecting * this function to do its job correctly. */ void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) { /* * Enforce ARM recommendation to manage priority values such * that group1 interrupts always have a lower priority than * group0 interrupts. * Note, lower numerical values are higher priorities so the comparison * checks below are reversed from what might be expected. */ assert(gicd_get_igroupr(base, id) == GRP1 ? pri >= GIC_HIGHEST_NS_PRIORITY && pri <= GIC_LOWEST_NS_PRIORITY : pri >= GIC_HIGHEST_SEC_PRIORITY && pri <= GIC_LOWEST_SEC_PRIORITY); mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK); }
static int uniphier_emmc_hw_init(void) { uintptr_t host_base = 0x5a000200; struct uniphier_mmc_cmd cmd = {0}; int ret; /* * deselect card before SEND_CSD command. * Do not check the return code. It fails, but it is OK. */ cmd.cmdidx = MMC_CMD_SELECT_CARD; cmd.resp_type = MMC_RSP_R1; uniphier_emmc_send_cmd(host_base, &cmd); /* CMD7 (arg=0) */ /* reset CMD Line */ mmio_write_8(host_base + SDHCI_SOFTWARE_RESET, SDHCI_RESET_CMD | SDHCI_RESET_DATA); while (mmio_read_8(host_base + SDHCI_SOFTWARE_RESET)) ; ret = uniphier_emmc_is_over_2gb(host_base); if (ret < 0) return ret; uniphier_emmc_block_addressing = ret; cmd.cmdarg = UNIPHIER_EMMC_RCA << 16; /* select card again */ ret = uniphier_emmc_send_cmd(host_base, &cmd); if (ret) return ret; /* switch to Boot Partition 1 */ ret = uniphier_emmc_switch_part(host_base, 1); if (ret) return ret; return 0; }
void gicd_set_itargetsr(uintptr_t base, unsigned int id, unsigned int target) { mmio_write_8(base + GICD_ITARGETSR + id, target & GIC_TARGET_CPU_MASK); }
void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) { mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK); }