mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 03:58:17 +00:00 
			
		
		
		
	Add a convenience function for any Exynos 542x chip. Signed-off-by: Simon Glass <sjg@chromium.org>
		
			
				
	
	
		
			262 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			262 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0+
 | |
| /*
 | |
|  * Copyright (C) 2012 Samsung Electronics
 | |
|  * Donghwa Lee <dh09.lee@samsung.com>
 | |
|  */
 | |
| 
 | |
| #include <common.h>
 | |
| #include <asm/io.h>
 | |
| #include <asm/arch/power.h>
 | |
| 
 | |
| static void exynos4_mipi_phy_control(unsigned int dev_index,
 | |
| 					unsigned int enable)
 | |
| {
 | |
| 	struct exynos4_power *pmu =
 | |
| 	    (struct exynos4_power *)samsung_get_base_power();
 | |
| 	unsigned int addr, cfg = 0;
 | |
| 
 | |
| 	if (dev_index == 0)
 | |
| 		addr = (unsigned int)&pmu->mipi_phy0_control;
 | |
| 	else
 | |
| 		addr = (unsigned int)&pmu->mipi_phy1_control;
 | |
| 
 | |
| 
 | |
| 	cfg = readl(addr);
 | |
| 	if (enable)
 | |
| 		cfg |= (EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
 | |
| 	else
 | |
| 		cfg &= ~(EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
 | |
| 
 | |
| 	writel(cfg, addr);
 | |
| }
 | |
| 
 | |
| void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable)
 | |
| {
 | |
| 	if (cpu_is_exynos4())
 | |
| 		exynos4_mipi_phy_control(dev_index, enable);
 | |
| }
 | |
| 
 | |
| void exynos5_set_usbhost_phy_ctrl(unsigned int enable)
 | |
| {
 | |
| 	struct exynos5_power *power =
 | |
| 		(struct exynos5_power *)samsung_get_base_power();
 | |
| 
 | |
| 	if (enable) {
 | |
| 		/* Enabling USBHOST_PHY */
 | |
| 		setbits_le32(&power->usbhost_phy_control,
 | |
| 				POWER_USB_HOST_PHY_CTRL_EN);
 | |
| 	} else {
 | |
| 		/* Disabling USBHOST_PHY */
 | |
| 		clrbits_le32(&power->usbhost_phy_control,
 | |
| 				POWER_USB_HOST_PHY_CTRL_EN);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void exynos4412_set_usbhost_phy_ctrl(unsigned int enable)
 | |
| {
 | |
| 	struct exynos4412_power *power =
 | |
| 		(struct exynos4412_power *)samsung_get_base_power();
 | |
| 
 | |
| 	if (enable) {
 | |
| 		/* Enabling USBHOST_PHY */
 | |
| 		setbits_le32(&power->usbhost_phy_control,
 | |
| 			     POWER_USB_HOST_PHY_CTRL_EN);
 | |
| 		setbits_le32(&power->hsic1_phy_control,
 | |
| 			     POWER_USB_HOST_PHY_CTRL_EN);
 | |
| 		setbits_le32(&power->hsic2_phy_control,
 | |
| 			     POWER_USB_HOST_PHY_CTRL_EN);
 | |
| 	} else {
 | |
| 		/* Disabling USBHOST_PHY */
 | |
| 		clrbits_le32(&power->usbhost_phy_control,
 | |
| 			     POWER_USB_HOST_PHY_CTRL_EN);
 | |
| 		clrbits_le32(&power->hsic1_phy_control,
 | |
| 			     POWER_USB_HOST_PHY_CTRL_EN);
 | |
| 		clrbits_le32(&power->hsic2_phy_control,
 | |
| 			     POWER_USB_HOST_PHY_CTRL_EN);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void set_usbhost_phy_ctrl(unsigned int enable)
 | |
| {
 | |
| 	if (cpu_is_exynos5())
 | |
| 		exynos5_set_usbhost_phy_ctrl(enable);
 | |
| 	else if (cpu_is_exynos4())
 | |
| 		if (proid_is_exynos4412())
 | |
| 			exynos4412_set_usbhost_phy_ctrl(enable);
 | |
| }
 | |
| 
 | |
| static void exynos5_set_usbdrd_phy_ctrl(unsigned int enable)
 | |
| {
 | |
| 	struct exynos5_power *power =
 | |
| 		(struct exynos5_power *)samsung_get_base_power();
 | |
| 
 | |
| 	if (enable) {
 | |
| 		/* Enabling USBDRD_PHY */
 | |
| 		setbits_le32(&power->usbdrd_phy_control,
 | |
| 				POWER_USB_DRD_PHY_CTRL_EN);
 | |
| 	} else {
 | |
| 		/* Disabling USBDRD_PHY */
 | |
| 		clrbits_le32(&power->usbdrd_phy_control,
 | |
| 				POWER_USB_DRD_PHY_CTRL_EN);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable)
 | |
| {
 | |
| 	struct exynos5420_power *power =
 | |
| 		(struct exynos5420_power *)samsung_get_base_power();
 | |
| 
 | |
| 	if (enable) {
 | |
| 		/* Enabling USBDEV_PHY */
 | |
| 		setbits_le32(&power->usbdev_phy_control,
 | |
| 				POWER_USB_DRD_PHY_CTRL_EN);
 | |
| 		setbits_le32(&power->usbdev1_phy_control,
 | |
| 				POWER_USB_DRD_PHY_CTRL_EN);
 | |
| 	} else {
 | |
| 		/* Disabling USBDEV_PHY */
 | |
| 		clrbits_le32(&power->usbdev_phy_control,
 | |
| 				POWER_USB_DRD_PHY_CTRL_EN);
 | |
| 		clrbits_le32(&power->usbdev1_phy_control,
 | |
| 				POWER_USB_DRD_PHY_CTRL_EN);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void set_usbdrd_phy_ctrl(unsigned int enable)
 | |
| {
 | |
| 	if (cpu_is_exynos5()) {
 | |
| 		if (proid_is_exynos542x())
 | |
| 			exynos5420_set_usbdev_phy_ctrl(enable);
 | |
| 		else
 | |
| 			exynos5_set_usbdrd_phy_ctrl(enable);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void exynos5_dp_phy_control(unsigned int enable)
 | |
| {
 | |
| 	unsigned int cfg;
 | |
| 	struct exynos5_power *power =
 | |
| 	    (struct exynos5_power *)samsung_get_base_power();
 | |
| 
 | |
| 	cfg = readl(&power->dptx_phy_control);
 | |
| 	if (enable)
 | |
| 		cfg |= EXYNOS_DP_PHY_ENABLE;
 | |
| 	else
 | |
| 		cfg &= ~EXYNOS_DP_PHY_ENABLE;
 | |
| 
 | |
| 	writel(cfg, &power->dptx_phy_control);
 | |
| }
 | |
| 
 | |
| void exynos_dp_phy_ctrl(unsigned int enable)
 | |
| {
 | |
| 	if (cpu_is_exynos5())
 | |
| 		exynos5_dp_phy_control(enable);
 | |
| }
 | |
| 
 | |
| static void exynos5_set_ps_hold_ctrl(void)
 | |
| {
 | |
| 	struct exynos5_power *power =
 | |
| 		(struct exynos5_power *)samsung_get_base_power();
 | |
| 
 | |
| 	/* Set PS-Hold high */
 | |
| 	setbits_le32(&power->ps_hold_control,
 | |
| 			EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Set ps_hold data driving value high
 | |
|  * This enables the machine to stay powered on
 | |
|  * after the initial power-on condition goes away
 | |
|  * (e.g. power button).
 | |
|  */
 | |
| void set_ps_hold_ctrl(void)
 | |
| {
 | |
| 	if (cpu_is_exynos5())
 | |
| 		exynos5_set_ps_hold_ctrl();
 | |
| }
 | |
| 
 | |
| 
 | |
| static void exynos5_set_xclkout(void)
 | |
| {
 | |
| 	struct exynos5_power *power =
 | |
| 		(struct exynos5_power *)samsung_get_base_power();
 | |
| 
 | |
| 	/* use xxti for xclk out */
 | |
| 	clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK,
 | |
| 				PMU_DEBUG_XXTI);
 | |
| }
 | |
| 
 | |
| void set_xclkout(void)
 | |
| {
 | |
| 	if (cpu_is_exynos5())
 | |
| 		exynos5_set_xclkout();
 | |
| }
 | |
| 
 | |
| /* Enables hardware tripping to power off the system when TMU fails */
 | |
| void set_hw_thermal_trip(void)
 | |
| {
 | |
| 	if (cpu_is_exynos5()) {
 | |
| 		struct exynos5_power *power =
 | |
| 			(struct exynos5_power *)samsung_get_base_power();
 | |
| 
 | |
| 		/* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/
 | |
| 		setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static uint32_t exynos5_get_reset_status(void)
 | |
| {
 | |
| 	struct exynos5_power *power =
 | |
| 		(struct exynos5_power *)samsung_get_base_power();
 | |
| 
 | |
| 	return power->inform1;
 | |
| }
 | |
| 
 | |
| static uint32_t exynos4_get_reset_status(void)
 | |
| {
 | |
| 	struct exynos4_power *power =
 | |
| 		(struct exynos4_power *)samsung_get_base_power();
 | |
| 
 | |
| 	return power->inform1;
 | |
| }
 | |
| 
 | |
| uint32_t get_reset_status(void)
 | |
| {
 | |
| 	if (cpu_is_exynos5())
 | |
| 		return exynos5_get_reset_status();
 | |
| 	else
 | |
| 		return  exynos4_get_reset_status();
 | |
| }
 | |
| 
 | |
| static void exynos5_power_exit_wakeup(void)
 | |
| {
 | |
| 	struct exynos5_power *power =
 | |
| 		(struct exynos5_power *)samsung_get_base_power();
 | |
| 	typedef void (*resume_func)(void);
 | |
| 
 | |
| 	((resume_func)power->inform0)();
 | |
| }
 | |
| 
 | |
| static void exynos4_power_exit_wakeup(void)
 | |
| {
 | |
| 	struct exynos4_power *power =
 | |
| 		(struct exynos4_power *)samsung_get_base_power();
 | |
| 	typedef void (*resume_func)(void);
 | |
| 
 | |
| 	((resume_func)power->inform0)();
 | |
| }
 | |
| 
 | |
| void power_exit_wakeup(void)
 | |
| {
 | |
| 	if (cpu_is_exynos5())
 | |
| 		exynos5_power_exit_wakeup();
 | |
| 	else
 | |
| 		exynos4_power_exit_wakeup();
 | |
| }
 | |
| 
 | |
| unsigned int get_boot_mode(void)
 | |
| {
 | |
| 	unsigned int om_pin = samsung_get_base_power();
 | |
| 
 | |
| 	return readl(om_pin) & OM_PIN_MASK;
 | |
| }
 |