power.c 5.88 KB
Newer Older
1 2 3 4
/*
 * Copyright (C) 2012 Samsung Electronics
 * Donghwa Lee <dh09.lee@samsung.com>
 *
5
 * SPDX-License-Identifier:	GPL-2.0+
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 */

#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);
}
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

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);
	}
}

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
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);
	}
}

80 81 82 83
void set_usbhost_phy_ctrl(unsigned int enable)
{
	if (cpu_is_exynos5())
		exynos5_set_usbhost_phy_ctrl(enable);
84 85 86
	else if (cpu_is_exynos4())
		if (proid_is_exynos4412())
			exynos4412_set_usbhost_phy_ctrl(enable);
87
}
88

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
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);
	}
}

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
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);
	}
}

125 126
void set_usbdrd_phy_ctrl(unsigned int enable)
{
127
	if (cpu_is_exynos5()) {
128
		if (proid_is_exynos5420() || proid_is_exynos5422())
129 130 131 132
			exynos5420_set_usbdev_phy_ctrl(enable);
		else
			exynos5_set_usbdrd_phy_ctrl(enable);
	}
133 134
}

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
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);
}

150
void exynos_dp_phy_ctrl(unsigned int enable)
151 152 153 154
{
	if (cpu_is_exynos5())
		exynos5_dp_phy_control(enable);
}
155 156 157 158 159 160 161 162 163 164 165

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);
}

166 167 168 169 170 171
/*
 * 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).
 */
172 173 174 175 176
void set_ps_hold_ctrl(void)
{
	if (cpu_is_exynos5())
		exynos5_set_ps_hold_ctrl();
}
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193


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();
}
194 195 196 197 198 199 200 201 202 203 204 205

/* 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);
	}
}
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255

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();
}
256 257 258 259 260 261 262

unsigned int get_boot_mode(void)
{
	unsigned int om_pin = samsung_get_base_power();

	return readl(om_pin) & OM_PIN_MASK;
}