/* * Copyright (C) 2012 Samsung Electronics * Donghwa Lee * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include 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); } } void set_usbdrd_phy_ctrl(unsigned int enable) { if (cpu_is_exynos5()) 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 set_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; }