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