1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2012 Samsung Electronics 4 * Donghwa Lee <dh09.lee@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_exynos542x()) 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