Example #1
0
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);
}