Home | History | Annotate | Download | only in mach-exynos
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2012 Samsung Electronics
      4  * Donghwa Lee <dh09.lee (at) samsung.com>
      5  */
      6 
      7 #include <common.h>
      8 #include <asm/io.h>
      9 #include <asm/arch/power.h>
     10 
     11 static void exynos4_mipi_phy_control(unsigned int dev_index,
     12 					unsigned int enable)
     13 {
     14 	struct exynos4_power *pmu =
     15 	    (struct exynos4_power *)samsung_get_base_power();
     16 	unsigned int addr, cfg = 0;
     17 
     18 	if (dev_index == 0)
     19 		addr = (unsigned int)&pmu->mipi_phy0_control;
     20 	else
     21 		addr = (unsigned int)&pmu->mipi_phy1_control;
     22 
     23 
     24 	cfg = readl(addr);
     25 	if (enable)
     26 		cfg |= (EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
     27 	else
     28 		cfg &= ~(EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
     29 
     30 	writel(cfg, addr);
     31 }
     32 
     33 void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable)
     34 {
     35 	if (cpu_is_exynos4())
     36 		exynos4_mipi_phy_control(dev_index, enable);
     37 }
     38 
     39 void exynos5_set_usbhost_phy_ctrl(unsigned int enable)
     40 {
     41 	struct exynos5_power *power =
     42 		(struct exynos5_power *)samsung_get_base_power();
     43 
     44 	if (enable) {
     45 		/* Enabling USBHOST_PHY */
     46 		setbits_le32(&power->usbhost_phy_control,
     47 				POWER_USB_HOST_PHY_CTRL_EN);
     48 	} else {
     49 		/* Disabling USBHOST_PHY */
     50 		clrbits_le32(&power->usbhost_phy_control,
     51 				POWER_USB_HOST_PHY_CTRL_EN);
     52 	}
     53 }
     54 
     55 void exynos4412_set_usbhost_phy_ctrl(unsigned int enable)
     56 {
     57 	struct exynos4412_power *power =
     58 		(struct exynos4412_power *)samsung_get_base_power();
     59 
     60 	if (enable) {
     61 		/* Enabling USBHOST_PHY */
     62 		setbits_le32(&power->usbhost_phy_control,
     63 			     POWER_USB_HOST_PHY_CTRL_EN);
     64 		setbits_le32(&power->hsic1_phy_control,
     65 			     POWER_USB_HOST_PHY_CTRL_EN);
     66 		setbits_le32(&power->hsic2_phy_control,
     67 			     POWER_USB_HOST_PHY_CTRL_EN);
     68 	} else {
     69 		/* Disabling USBHOST_PHY */
     70 		clrbits_le32(&power->usbhost_phy_control,
     71 			     POWER_USB_HOST_PHY_CTRL_EN);
     72 		clrbits_le32(&power->hsic1_phy_control,
     73 			     POWER_USB_HOST_PHY_CTRL_EN);
     74 		clrbits_le32(&power->hsic2_phy_control,
     75 			     POWER_USB_HOST_PHY_CTRL_EN);
     76 	}
     77 }
     78 
     79 void set_usbhost_phy_ctrl(unsigned int enable)
     80 {
     81 	if (cpu_is_exynos5())
     82 		exynos5_set_usbhost_phy_ctrl(enable);
     83 	else if (cpu_is_exynos4())
     84 		if (proid_is_exynos4412())
     85 			exynos4412_set_usbhost_phy_ctrl(enable);
     86 }
     87 
     88 static void exynos5_set_usbdrd_phy_ctrl(unsigned int enable)
     89 {
     90 	struct exynos5_power *power =
     91 		(struct exynos5_power *)samsung_get_base_power();
     92 
     93 	if (enable) {
     94 		/* Enabling USBDRD_PHY */
     95 		setbits_le32(&power->usbdrd_phy_control,
     96 				POWER_USB_DRD_PHY_CTRL_EN);
     97 	} else {
     98 		/* Disabling USBDRD_PHY */
     99 		clrbits_le32(&power->usbdrd_phy_control,
    100 				POWER_USB_DRD_PHY_CTRL_EN);
    101 	}
    102 }
    103 
    104 static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable)
    105 {
    106 	struct exynos5420_power *power =
    107 		(struct exynos5420_power *)samsung_get_base_power();
    108 
    109 	if (enable) {
    110 		/* Enabling USBDEV_PHY */
    111 		setbits_le32(&power->usbdev_phy_control,
    112 				POWER_USB_DRD_PHY_CTRL_EN);
    113 		setbits_le32(&power->usbdev1_phy_control,
    114 				POWER_USB_DRD_PHY_CTRL_EN);
    115 	} else {
    116 		/* Disabling USBDEV_PHY */
    117 		clrbits_le32(&power->usbdev_phy_control,
    118 				POWER_USB_DRD_PHY_CTRL_EN);
    119 		clrbits_le32(&power->usbdev1_phy_control,
    120 				POWER_USB_DRD_PHY_CTRL_EN);
    121 	}
    122 }
    123 
    124 void set_usbdrd_phy_ctrl(unsigned int enable)
    125 {
    126 	if (cpu_is_exynos5()) {
    127 		if (proid_is_exynos5420() || proid_is_exynos5422())
    128 			exynos5420_set_usbdev_phy_ctrl(enable);
    129 		else
    130 			exynos5_set_usbdrd_phy_ctrl(enable);
    131 	}
    132 }
    133 
    134 static void exynos5_dp_phy_control(unsigned int enable)
    135 {
    136 	unsigned int cfg;
    137 	struct exynos5_power *power =
    138 	    (struct exynos5_power *)samsung_get_base_power();
    139 
    140 	cfg = readl(&power->dptx_phy_control);
    141 	if (enable)
    142 		cfg |= EXYNOS_DP_PHY_ENABLE;
    143 	else
    144 		cfg &= ~EXYNOS_DP_PHY_ENABLE;
    145 
    146 	writel(cfg, &power->dptx_phy_control);
    147 }
    148 
    149 void exynos_dp_phy_ctrl(unsigned int enable)
    150 {
    151 	if (cpu_is_exynos5())
    152 		exynos5_dp_phy_control(enable);
    153 }
    154 
    155 static void exynos5_set_ps_hold_ctrl(void)
    156 {
    157 	struct exynos5_power *power =
    158 		(struct exynos5_power *)samsung_get_base_power();
    159 
    160 	/* Set PS-Hold high */
    161 	setbits_le32(&power->ps_hold_control,
    162 			EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
    163 }
    164 
    165 /*
    166  * Set ps_hold data driving value high
    167  * This enables the machine to stay powered on
    168  * after the initial power-on condition goes away
    169  * (e.g. power button).
    170  */
    171 void set_ps_hold_ctrl(void)
    172 {
    173 	if (cpu_is_exynos5())
    174 		exynos5_set_ps_hold_ctrl();
    175 }
    176 
    177 
    178 static void exynos5_set_xclkout(void)
    179 {
    180 	struct exynos5_power *power =
    181 		(struct exynos5_power *)samsung_get_base_power();
    182 
    183 	/* use xxti for xclk out */
    184 	clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK,
    185 				PMU_DEBUG_XXTI);
    186 }
    187 
    188 void set_xclkout(void)
    189 {
    190 	if (cpu_is_exynos5())
    191 		exynos5_set_xclkout();
    192 }
    193 
    194 /* Enables hardware tripping to power off the system when TMU fails */
    195 void set_hw_thermal_trip(void)
    196 {
    197 	if (cpu_is_exynos5()) {
    198 		struct exynos5_power *power =
    199 			(struct exynos5_power *)samsung_get_base_power();
    200 
    201 		/* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/
    202 		setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP);
    203 	}
    204 }
    205 
    206 static uint32_t exynos5_get_reset_status(void)
    207 {
    208 	struct exynos5_power *power =
    209 		(struct exynos5_power *)samsung_get_base_power();
    210 
    211 	return power->inform1;
    212 }
    213 
    214 static uint32_t exynos4_get_reset_status(void)
    215 {
    216 	struct exynos4_power *power =
    217 		(struct exynos4_power *)samsung_get_base_power();
    218 
    219 	return power->inform1;
    220 }
    221 
    222 uint32_t get_reset_status(void)
    223 {
    224 	if (cpu_is_exynos5())
    225 		return exynos5_get_reset_status();
    226 	else
    227 		return  exynos4_get_reset_status();
    228 }
    229 
    230 static void exynos5_power_exit_wakeup(void)
    231 {
    232 	struct exynos5_power *power =
    233 		(struct exynos5_power *)samsung_get_base_power();
    234 	typedef void (*resume_func)(void);
    235 
    236 	((resume_func)power->inform0)();
    237 }
    238 
    239 static void exynos4_power_exit_wakeup(void)
    240 {
    241 	struct exynos4_power *power =
    242 		(struct exynos4_power *)samsung_get_base_power();
    243 	typedef void (*resume_func)(void);
    244 
    245 	((resume_func)power->inform0)();
    246 }
    247 
    248 void power_exit_wakeup(void)
    249 {
    250 	if (cpu_is_exynos5())
    251 		exynos5_power_exit_wakeup();
    252 	else
    253 		exynos4_power_exit_wakeup();
    254 }
    255 
    256 unsigned int get_boot_mode(void)
    257 {
    258 	unsigned int om_pin = samsung_get_base_power();
    259 
    260 	return readl(om_pin) & OM_PIN_MASK;
    261 }
    262