mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-24 15:42:32 +00:00
soc/tegra: Changes for v4.7-rc1
This contains a bunch of preparatory patches to the PMC driver which are a prerequisite to moving the driver to generic power domains. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJXEPuLAAoJEN0jrNd/PrOh44YP/1wUmB6H52eE3U5BIPNaMLZv XNzp/chmkT59lXgksHOsMK7o40z/nq5+Fc32DW95w9nQmBHcNtRSUXQJzWjfIgdv m5Kl8A11OBaocO5JMaTIGyDUwOXMTYNdD48dEasS+8LdmB2FwiUyY1BgiKxg7LLO JX/YZPo3hwVdmDVUutYNutvOhTJmHXt7HVqO5roSZnU2ydTy72BEZU69hWIFStT1 I7YY8w/Xf5IEGBDYM4EjLWeGUKvsSfKMy1MP+YVxeoGsFON3Xnh2BZtxpquV0uov 8cyiYgmr6BBlh7wlgId/mCUDArTXoOkRqr3E6V/G0UIoqYFIdpAyQ49xdNe5yplk WyXUl7Ui6tkf2V9xUiDJkjXR3jgK53adovNWpMAAjVowO1HQ8rh151H6fqpGu22R MWBXocMrCp2I1/XJ28X/dVpO8fMehMUTOzaXYtB+Q5F6Gh49NcBcEeNGH6wdb02A lCHzU00rq5RnUPvcp/irvv88aiV2rjcePJ8RYnAfkDpH7ugMSdiGb9aMUaMwRW1C p+z2GSswzfsT4Iog6Jtu6yQhkWTthexLW8F17foT5uGx3mNZQ6cyNzxRsRjr59ot Rc9aahzlbkeMUzHDevihHiNuqIXAgM4Cy0JQFgm8lqxdYenKcxkzBHawdpgP60yf IQcsQ+Wq0WERU3e5aw7w =EmlG -----END PGP SIGNATURE----- Merge tag 'tegra-for-4.7-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers Merge "soc/tegra: Changes for v4.7-rc1" from Thierry Reding: This contains a bunch of preparatory patches to the PMC driver which are a prerequisite to moving the driver to generic power domains. * tag 'tegra-for-4.7-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: dt-bindings: Update NVIDIA PMC for Tegra soc/tegra: pmc: Wait for powergate state to change soc/tegra: pmc: Ensure GPU partition can be toggled on/off by PMC soc/tegra: pmc: Remove additional check for a valid partition soc/tegra: pmc: Fix verification of valid partitions soc/tegra: pmc: Fix testing of powergate state soc/tegra: pmc: Change powergate and rail IDs to be an unsigned type soc/tegra: pmc: Protect public functions from potential race conditions soc/tegra: pmc: Restore base address on probe failure soc/tegra: pmc: Remove non-existing L2 partition for Tegra124 soc/tegra: pmc: Remove non-existing power partitions for Tegra210 soc/tegra: pmc: Remove debugfs entry on probe failure soc/tegra: pmc: Fix sparse warning for tegra_pmc_init_tsense_reset() soc/tegra: pmc: Add missing structure members to kernel-doc
This commit is contained in:
commit
c8f7341b29
5 changed files with 124 additions and 91 deletions
|
@ -6,11 +6,13 @@ modes. It provides power-gating controllers for SoC and CPU power-islands.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- name : Should be pmc
|
- name : Should be pmc
|
||||||
- compatible : For Tegra20, must contain "nvidia,tegra20-pmc". For Tegra30,
|
- compatible : Should contain one of the following:
|
||||||
must contain "nvidia,tegra30-pmc". For Tegra114, must contain
|
For Tegra20 must contain "nvidia,tegra20-pmc".
|
||||||
"nvidia,tegra114-pmc". For Tegra124, must contain "nvidia,tegra124-pmc".
|
For Tegra30 must contain "nvidia,tegra30-pmc".
|
||||||
Otherwise, must contain "nvidia,<chip>-pmc", plus at least one of the
|
For Tegra114 must contain "nvidia,tegra114-pmc"
|
||||||
above, where <chip> is tegra132.
|
For Tegra124 must contain "nvidia,tegra124-pmc"
|
||||||
|
For Tegra132 must contain "nvidia,tegra124-pmc"
|
||||||
|
For Tegra210 must contain "nvidia,tegra210-pmc"
|
||||||
- reg : Offset and length of the register set for the device
|
- reg : Offset and length of the register set for the device
|
||||||
- clocks : Must contain an entry for each entry in clock-names.
|
- clocks : Must contain an entry for each entry in clock-names.
|
||||||
See ../clocks/clock-bindings.txt for details.
|
See ../clocks/clock-bindings.txt for details.
|
||||||
|
|
|
@ -108,19 +108,9 @@ static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
* be un-gated by un-toggling the power gate register
|
* be un-gated by un-toggling the power gate register
|
||||||
* manually.
|
* manually.
|
||||||
*/
|
*/
|
||||||
if (!tegra_pmc_cpu_is_powered(cpu)) {
|
ret = tegra_pmc_cpu_power_on(cpu);
|
||||||
ret = tegra_pmc_cpu_power_on(cpu);
|
if (ret)
|
||||||
if (ret)
|
return ret;
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Wait for the power to come up. */
|
|
||||||
timeout = jiffies + msecs_to_jiffies(100);
|
|
||||||
while (!tegra_pmc_cpu_is_powered(cpu)) {
|
|
||||||
if (time_after(jiffies, timeout))
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
udelay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_clamps:
|
remove_clamps:
|
||||||
/* CPU partition is powered. Enable the CPU clock. */
|
/* CPU partition is powered. Enable the CPU clock. */
|
||||||
|
|
|
@ -121,7 +121,7 @@ struct tegra_dc {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
|
||||||
struct drm_crtc base;
|
struct drm_crtc base;
|
||||||
int powergate;
|
unsigned int powergate;
|
||||||
int pipe;
|
int pipe;
|
||||||
|
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
@ -113,8 +114,11 @@ struct tegra_pmc_soc {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct tegra_pmc - NVIDIA Tegra PMC
|
* struct tegra_pmc - NVIDIA Tegra PMC
|
||||||
|
* @dev: pointer to PMC device structure
|
||||||
* @base: pointer to I/O remapped register region
|
* @base: pointer to I/O remapped register region
|
||||||
* @clk: pointer to pclk clock
|
* @clk: pointer to pclk clock
|
||||||
|
* @soc: pointer to SoC data structure
|
||||||
|
* @debugfs: pointer to debugfs entry
|
||||||
* @rate: currently configured rate of pclk
|
* @rate: currently configured rate of pclk
|
||||||
* @suspend_mode: lowest suspend mode available
|
* @suspend_mode: lowest suspend mode available
|
||||||
* @cpu_good_time: CPU power good time (in microseconds)
|
* @cpu_good_time: CPU power good time (in microseconds)
|
||||||
|
@ -134,6 +138,7 @@ struct tegra_pmc {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
struct dentry *debugfs;
|
||||||
|
|
||||||
const struct tegra_pmc_soc *soc;
|
const struct tegra_pmc_soc *soc;
|
||||||
|
|
||||||
|
@ -170,38 +175,56 @@ static void tegra_pmc_writel(u32 value, unsigned long offset)
|
||||||
writel(value, pmc->base + offset);
|
writel(value, pmc->base + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool tegra_powergate_state(int id)
|
||||||
|
{
|
||||||
|
if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps)
|
||||||
|
return (tegra_pmc_readl(GPU_RG_CNTRL) & 0x1) == 0;
|
||||||
|
else
|
||||||
|
return (tegra_pmc_readl(PWRGATE_STATUS) & BIT(id)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool tegra_powergate_is_valid(int id)
|
||||||
|
{
|
||||||
|
return (pmc->soc && pmc->soc->powergates[id]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tegra_powergate_set() - set the state of a partition
|
* tegra_powergate_set() - set the state of a partition
|
||||||
* @id: partition ID
|
* @id: partition ID
|
||||||
* @new_state: new state of the partition
|
* @new_state: new state of the partition
|
||||||
*/
|
*/
|
||||||
static int tegra_powergate_set(int id, bool new_state)
|
static int tegra_powergate_set(unsigned int id, bool new_state)
|
||||||
{
|
{
|
||||||
bool status;
|
bool status;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&pmc->powergates_lock);
|
mutex_lock(&pmc->powergates_lock);
|
||||||
|
|
||||||
status = tegra_pmc_readl(PWRGATE_STATUS) & (1 << id);
|
if (tegra_powergate_state(id) == new_state) {
|
||||||
|
|
||||||
if (status == new_state) {
|
|
||||||
mutex_unlock(&pmc->powergates_lock);
|
mutex_unlock(&pmc->powergates_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tegra_pmc_writel(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
|
tegra_pmc_writel(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
|
||||||
|
|
||||||
|
err = readx_poll_timeout(tegra_powergate_state, id, status,
|
||||||
|
status == new_state, 10, 100000);
|
||||||
|
|
||||||
mutex_unlock(&pmc->powergates_lock);
|
mutex_unlock(&pmc->powergates_lock);
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tegra_powergate_power_on() - power on partition
|
* tegra_powergate_power_on() - power on partition
|
||||||
* @id: partition ID
|
* @id: partition ID
|
||||||
*/
|
*/
|
||||||
int tegra_powergate_power_on(int id)
|
int tegra_powergate_power_on(unsigned int id)
|
||||||
{
|
{
|
||||||
if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
|
if (!tegra_powergate_is_valid(id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return tegra_powergate_set(id, true);
|
return tegra_powergate_set(id, true);
|
||||||
|
@ -211,9 +234,9 @@ int tegra_powergate_power_on(int id)
|
||||||
* tegra_powergate_power_off() - power off partition
|
* tegra_powergate_power_off() - power off partition
|
||||||
* @id: partition ID
|
* @id: partition ID
|
||||||
*/
|
*/
|
||||||
int tegra_powergate_power_off(int id)
|
int tegra_powergate_power_off(unsigned int id)
|
||||||
{
|
{
|
||||||
if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
|
if (!tegra_powergate_is_valid(id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return tegra_powergate_set(id, false);
|
return tegra_powergate_set(id, false);
|
||||||
|
@ -224,28 +247,33 @@ EXPORT_SYMBOL(tegra_powergate_power_off);
|
||||||
* tegra_powergate_is_powered() - check if partition is powered
|
* tegra_powergate_is_powered() - check if partition is powered
|
||||||
* @id: partition ID
|
* @id: partition ID
|
||||||
*/
|
*/
|
||||||
int tegra_powergate_is_powered(int id)
|
int tegra_powergate_is_powered(unsigned int id)
|
||||||
{
|
{
|
||||||
u32 status;
|
int status;
|
||||||
|
|
||||||
if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
|
if (!tegra_powergate_is_valid(id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
status = tegra_pmc_readl(PWRGATE_STATUS) & (1 << id);
|
mutex_lock(&pmc->powergates_lock);
|
||||||
return !!status;
|
status = tegra_powergate_state(id);
|
||||||
|
mutex_unlock(&pmc->powergates_lock);
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tegra_powergate_remove_clamping() - remove power clamps for partition
|
* tegra_powergate_remove_clamping() - remove power clamps for partition
|
||||||
* @id: partition ID
|
* @id: partition ID
|
||||||
*/
|
*/
|
||||||
int tegra_powergate_remove_clamping(int id)
|
int tegra_powergate_remove_clamping(unsigned int id)
|
||||||
{
|
{
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
|
if (!tegra_powergate_is_valid(id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&pmc->powergates_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On Tegra124 and later, the clamps for the GPU are controlled by a
|
* On Tegra124 and later, the clamps for the GPU are controlled by a
|
||||||
* separate register (with different semantics).
|
* separate register (with different semantics).
|
||||||
|
@ -253,7 +281,7 @@ int tegra_powergate_remove_clamping(int id)
|
||||||
if (id == TEGRA_POWERGATE_3D) {
|
if (id == TEGRA_POWERGATE_3D) {
|
||||||
if (pmc->soc->has_gpu_clamps) {
|
if (pmc->soc->has_gpu_clamps) {
|
||||||
tegra_pmc_writel(0, GPU_RG_CNTRL);
|
tegra_pmc_writel(0, GPU_RG_CNTRL);
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +298,9 @@ int tegra_powergate_remove_clamping(int id)
|
||||||
|
|
||||||
tegra_pmc_writel(mask, REMOVE_CLAMPING);
|
tegra_pmc_writel(mask, REMOVE_CLAMPING);
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&pmc->powergates_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tegra_powergate_remove_clamping);
|
EXPORT_SYMBOL(tegra_powergate_remove_clamping);
|
||||||
|
@ -282,7 +313,7 @@ EXPORT_SYMBOL(tegra_powergate_remove_clamping);
|
||||||
*
|
*
|
||||||
* Must be called with clk disabled, and returns with clk enabled.
|
* Must be called with clk disabled, and returns with clk enabled.
|
||||||
*/
|
*/
|
||||||
int tegra_powergate_sequence_power_up(int id, struct clk *clk,
|
int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
|
||||||
struct reset_control *rst)
|
struct reset_control *rst)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -325,9 +356,9 @@ EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
|
||||||
* Returns the partition ID corresponding to the CPU partition ID or a
|
* Returns the partition ID corresponding to the CPU partition ID or a
|
||||||
* negative error code on failure.
|
* negative error code on failure.
|
||||||
*/
|
*/
|
||||||
static int tegra_get_cpu_powergate_id(int cpuid)
|
static int tegra_get_cpu_powergate_id(unsigned int cpuid)
|
||||||
{
|
{
|
||||||
if (pmc->soc && cpuid > 0 && cpuid < pmc->soc->num_cpu_powergates)
|
if (pmc->soc && cpuid < pmc->soc->num_cpu_powergates)
|
||||||
return pmc->soc->cpu_powergates[cpuid];
|
return pmc->soc->cpu_powergates[cpuid];
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -337,7 +368,7 @@ static int tegra_get_cpu_powergate_id(int cpuid)
|
||||||
* tegra_pmc_cpu_is_powered() - check if CPU partition is powered
|
* tegra_pmc_cpu_is_powered() - check if CPU partition is powered
|
||||||
* @cpuid: CPU partition ID
|
* @cpuid: CPU partition ID
|
||||||
*/
|
*/
|
||||||
bool tegra_pmc_cpu_is_powered(int cpuid)
|
bool tegra_pmc_cpu_is_powered(unsigned int cpuid)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
@ -352,7 +383,7 @@ bool tegra_pmc_cpu_is_powered(int cpuid)
|
||||||
* tegra_pmc_cpu_power_on() - power on CPU partition
|
* tegra_pmc_cpu_power_on() - power on CPU partition
|
||||||
* @cpuid: CPU partition ID
|
* @cpuid: CPU partition ID
|
||||||
*/
|
*/
|
||||||
int tegra_pmc_cpu_power_on(int cpuid)
|
int tegra_pmc_cpu_power_on(unsigned int cpuid)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
@ -367,7 +398,7 @@ int tegra_pmc_cpu_power_on(int cpuid)
|
||||||
* tegra_pmc_cpu_remove_clamping() - remove power clamps for CPU partition
|
* tegra_pmc_cpu_remove_clamping() - remove power clamps for CPU partition
|
||||||
* @cpuid: CPU partition ID
|
* @cpuid: CPU partition ID
|
||||||
*/
|
*/
|
||||||
int tegra_pmc_cpu_remove_clamping(int cpuid)
|
int tegra_pmc_cpu_remove_clamping(unsigned int cpuid)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
@ -416,16 +447,18 @@ static struct notifier_block tegra_pmc_restart_handler = {
|
||||||
static int powergate_show(struct seq_file *s, void *data)
|
static int powergate_show(struct seq_file *s, void *data)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
int status;
|
||||||
|
|
||||||
seq_printf(s, " powergate powered\n");
|
seq_printf(s, " powergate powered\n");
|
||||||
seq_printf(s, "------------------\n");
|
seq_printf(s, "------------------\n");
|
||||||
|
|
||||||
for (i = 0; i < pmc->soc->num_powergates; i++) {
|
for (i = 0; i < pmc->soc->num_powergates; i++) {
|
||||||
if (!pmc->soc->powergates[i])
|
status = tegra_powergate_is_powered(i);
|
||||||
|
if (status < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
seq_printf(s, " %9s %7s\n", pmc->soc->powergates[i],
|
seq_printf(s, " %9s %7s\n", pmc->soc->powergates[i],
|
||||||
tegra_powergate_is_powered(i) ? "yes" : "no");
|
status ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -445,17 +478,15 @@ static const struct file_operations powergate_fops = {
|
||||||
|
|
||||||
static int tegra_powergate_debugfs_init(void)
|
static int tegra_powergate_debugfs_init(void)
|
||||||
{
|
{
|
||||||
struct dentry *d;
|
pmc->debugfs = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
|
||||||
|
&powergate_fops);
|
||||||
d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
|
if (!pmc->debugfs)
|
||||||
&powergate_fops);
|
|
||||||
if (!d)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_io_rail_prepare(int id, unsigned long *request,
|
static int tegra_io_rail_prepare(unsigned int id, unsigned long *request,
|
||||||
unsigned long *status, unsigned int *bit)
|
unsigned long *status, unsigned int *bit)
|
||||||
{
|
{
|
||||||
unsigned long rate, value;
|
unsigned long rate, value;
|
||||||
|
@ -512,15 +543,17 @@ static void tegra_io_rail_unprepare(void)
|
||||||
tegra_pmc_writel(DPD_SAMPLE_DISABLE, DPD_SAMPLE);
|
tegra_pmc_writel(DPD_SAMPLE_DISABLE, DPD_SAMPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tegra_io_rail_power_on(int id)
|
int tegra_io_rail_power_on(unsigned int id)
|
||||||
{
|
{
|
||||||
unsigned long request, status, value;
|
unsigned long request, status, value;
|
||||||
unsigned int bit, mask;
|
unsigned int bit, mask;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
mutex_lock(&pmc->powergates_lock);
|
||||||
|
|
||||||
err = tegra_io_rail_prepare(id, &request, &status, &bit);
|
err = tegra_io_rail_prepare(id, &request, &status, &bit);
|
||||||
if (err < 0)
|
if (err)
|
||||||
return err;
|
goto error;
|
||||||
|
|
||||||
mask = 1 << bit;
|
mask = 1 << bit;
|
||||||
|
|
||||||
|
@ -531,27 +564,32 @@ int tegra_io_rail_power_on(int id)
|
||||||
tegra_pmc_writel(value, request);
|
tegra_pmc_writel(value, request);
|
||||||
|
|
||||||
err = tegra_io_rail_poll(status, mask, 0, 250);
|
err = tegra_io_rail_poll(status, mask, 0, 250);
|
||||||
if (err < 0) {
|
if (err) {
|
||||||
pr_info("tegra_io_rail_poll() failed: %d\n", err);
|
pr_info("tegra_io_rail_poll() failed: %d\n", err);
|
||||||
return err;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
tegra_io_rail_unprepare();
|
tegra_io_rail_unprepare();
|
||||||
|
|
||||||
return 0;
|
error:
|
||||||
|
mutex_unlock(&pmc->powergates_lock);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tegra_io_rail_power_on);
|
EXPORT_SYMBOL(tegra_io_rail_power_on);
|
||||||
|
|
||||||
int tegra_io_rail_power_off(int id)
|
int tegra_io_rail_power_off(unsigned int id)
|
||||||
{
|
{
|
||||||
unsigned long request, status, value;
|
unsigned long request, status, value;
|
||||||
unsigned int bit, mask;
|
unsigned int bit, mask;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
mutex_lock(&pmc->powergates_lock);
|
||||||
|
|
||||||
err = tegra_io_rail_prepare(id, &request, &status, &bit);
|
err = tegra_io_rail_prepare(id, &request, &status, &bit);
|
||||||
if (err < 0) {
|
if (err) {
|
||||||
pr_info("tegra_io_rail_prepare() failed: %d\n", err);
|
pr_info("tegra_io_rail_prepare() failed: %d\n", err);
|
||||||
return err;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
mask = 1 << bit;
|
mask = 1 << bit;
|
||||||
|
@ -563,12 +601,15 @@ int tegra_io_rail_power_off(int id)
|
||||||
tegra_pmc_writel(value, request);
|
tegra_pmc_writel(value, request);
|
||||||
|
|
||||||
err = tegra_io_rail_poll(status, mask, mask, 250);
|
err = tegra_io_rail_poll(status, mask, mask, 250);
|
||||||
if (err < 0)
|
if (err)
|
||||||
return err;
|
goto error;
|
||||||
|
|
||||||
tegra_io_rail_unprepare();
|
tegra_io_rail_unprepare();
|
||||||
|
|
||||||
return 0;
|
error:
|
||||||
|
mutex_unlock(&pmc->powergates_lock);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tegra_io_rail_power_off);
|
EXPORT_SYMBOL(tegra_io_rail_power_off);
|
||||||
|
|
||||||
|
@ -727,7 +768,7 @@ static void tegra_pmc_init(struct tegra_pmc *pmc)
|
||||||
tegra_pmc_writel(value, PMC_CNTRL);
|
tegra_pmc_writel(value, PMC_CNTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
|
static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
|
||||||
{
|
{
|
||||||
static const char disabled[] = "emergency thermal reset disabled";
|
static const char disabled[] = "emergency thermal reset disabled";
|
||||||
u32 pmu_addr, ctrl_id, reg_addr, reg_data, pinmux;
|
u32 pmu_addr, ctrl_id, reg_addr, reg_data, pinmux;
|
||||||
|
@ -805,7 +846,7 @@ out:
|
||||||
|
|
||||||
static int tegra_pmc_probe(struct platform_device *pdev)
|
static int tegra_pmc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
void __iomem *base = pmc->base;
|
void __iomem *base;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -815,11 +856,9 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
/* take over the memory region from the early initialization */
|
/* take over the memory region from the early initialization */
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
pmc->base = devm_ioremap_resource(&pdev->dev, res);
|
base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (IS_ERR(pmc->base))
|
if (IS_ERR(base))
|
||||||
return PTR_ERR(pmc->base);
|
return PTR_ERR(base);
|
||||||
|
|
||||||
iounmap(base);
|
|
||||||
|
|
||||||
pmc->clk = devm_clk_get(&pdev->dev, "pclk");
|
pmc->clk = devm_clk_get(&pdev->dev, "pclk");
|
||||||
if (IS_ERR(pmc->clk)) {
|
if (IS_ERR(pmc->clk)) {
|
||||||
|
@ -842,11 +881,17 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
err = register_restart_handler(&tegra_pmc_restart_handler);
|
err = register_restart_handler(&tegra_pmc_restart_handler);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
debugfs_remove(pmc->debugfs);
|
||||||
dev_err(&pdev->dev, "unable to register restart handler, %d\n",
|
dev_err(&pdev->dev, "unable to register restart handler, %d\n",
|
||||||
err);
|
err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&pmc->powergates_lock);
|
||||||
|
iounmap(pmc->base);
|
||||||
|
pmc->base = base;
|
||||||
|
mutex_unlock(&pmc->powergates_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,7 +1009,6 @@ static const char * const tegra124_powergates[] = {
|
||||||
[TEGRA_POWERGATE_VENC] = "venc",
|
[TEGRA_POWERGATE_VENC] = "venc",
|
||||||
[TEGRA_POWERGATE_PCIE] = "pcie",
|
[TEGRA_POWERGATE_PCIE] = "pcie",
|
||||||
[TEGRA_POWERGATE_VDEC] = "vdec",
|
[TEGRA_POWERGATE_VDEC] = "vdec",
|
||||||
[TEGRA_POWERGATE_L2] = "l2",
|
|
||||||
[TEGRA_POWERGATE_MPE] = "mpe",
|
[TEGRA_POWERGATE_MPE] = "mpe",
|
||||||
[TEGRA_POWERGATE_HEG] = "heg",
|
[TEGRA_POWERGATE_HEG] = "heg",
|
||||||
[TEGRA_POWERGATE_SATA] = "sata",
|
[TEGRA_POWERGATE_SATA] = "sata",
|
||||||
|
@ -1006,17 +1050,13 @@ static const char * const tegra210_powergates[] = {
|
||||||
[TEGRA_POWERGATE_3D] = "3d",
|
[TEGRA_POWERGATE_3D] = "3d",
|
||||||
[TEGRA_POWERGATE_VENC] = "venc",
|
[TEGRA_POWERGATE_VENC] = "venc",
|
||||||
[TEGRA_POWERGATE_PCIE] = "pcie",
|
[TEGRA_POWERGATE_PCIE] = "pcie",
|
||||||
[TEGRA_POWERGATE_L2] = "l2",
|
|
||||||
[TEGRA_POWERGATE_MPE] = "mpe",
|
[TEGRA_POWERGATE_MPE] = "mpe",
|
||||||
[TEGRA_POWERGATE_HEG] = "heg",
|
|
||||||
[TEGRA_POWERGATE_SATA] = "sata",
|
[TEGRA_POWERGATE_SATA] = "sata",
|
||||||
[TEGRA_POWERGATE_CPU1] = "cpu1",
|
[TEGRA_POWERGATE_CPU1] = "cpu1",
|
||||||
[TEGRA_POWERGATE_CPU2] = "cpu2",
|
[TEGRA_POWERGATE_CPU2] = "cpu2",
|
||||||
[TEGRA_POWERGATE_CPU3] = "cpu3",
|
[TEGRA_POWERGATE_CPU3] = "cpu3",
|
||||||
[TEGRA_POWERGATE_CELP] = "celp",
|
|
||||||
[TEGRA_POWERGATE_CPU0] = "cpu0",
|
[TEGRA_POWERGATE_CPU0] = "cpu0",
|
||||||
[TEGRA_POWERGATE_C0NC] = "c0nc",
|
[TEGRA_POWERGATE_C0NC] = "c0nc",
|
||||||
[TEGRA_POWERGATE_C1NC] = "c1nc",
|
|
||||||
[TEGRA_POWERGATE_SOR] = "sor",
|
[TEGRA_POWERGATE_SOR] = "sor",
|
||||||
[TEGRA_POWERGATE_DIS] = "dis",
|
[TEGRA_POWERGATE_DIS] = "dis",
|
||||||
[TEGRA_POWERGATE_DISB] = "disb",
|
[TEGRA_POWERGATE_DISB] = "disb",
|
||||||
|
|
|
@ -33,9 +33,9 @@ void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode);
|
||||||
#endif /* CONFIG_PM_SLEEP */
|
#endif /* CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
bool tegra_pmc_cpu_is_powered(int cpuid);
|
bool tegra_pmc_cpu_is_powered(unsigned int cpuid);
|
||||||
int tegra_pmc_cpu_power_on(int cpuid);
|
int tegra_pmc_cpu_power_on(unsigned int cpuid);
|
||||||
int tegra_pmc_cpu_remove_clamping(int cpuid);
|
int tegra_pmc_cpu_remove_clamping(unsigned int cpuid);
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -108,50 +108,51 @@ int tegra_pmc_cpu_remove_clamping(int cpuid);
|
||||||
#define TEGRA_IO_RAIL_SYS_DDC 58
|
#define TEGRA_IO_RAIL_SYS_DDC 58
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_TEGRA
|
#ifdef CONFIG_ARCH_TEGRA
|
||||||
int tegra_powergate_is_powered(int id);
|
int tegra_powergate_is_powered(unsigned int id);
|
||||||
int tegra_powergate_power_on(int id);
|
int tegra_powergate_power_on(unsigned int id);
|
||||||
int tegra_powergate_power_off(int id);
|
int tegra_powergate_power_off(unsigned int id);
|
||||||
int tegra_powergate_remove_clamping(int id);
|
int tegra_powergate_remove_clamping(unsigned int id);
|
||||||
|
|
||||||
/* Must be called with clk disabled, and returns with clk enabled */
|
/* Must be called with clk disabled, and returns with clk enabled */
|
||||||
int tegra_powergate_sequence_power_up(int id, struct clk *clk,
|
int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
|
||||||
struct reset_control *rst);
|
struct reset_control *rst);
|
||||||
|
|
||||||
int tegra_io_rail_power_on(int id);
|
int tegra_io_rail_power_on(unsigned int id);
|
||||||
int tegra_io_rail_power_off(int id);
|
int tegra_io_rail_power_off(unsigned int id);
|
||||||
#else
|
#else
|
||||||
static inline int tegra_powergate_is_powered(int id)
|
static inline int tegra_powergate_is_powered(unsigned int id)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tegra_powergate_power_on(int id)
|
static inline int tegra_powergate_power_on(unsigned int id)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tegra_powergate_power_off(int id)
|
static inline int tegra_powergate_power_off(unsigned int id)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tegra_powergate_remove_clamping(int id)
|
static inline int tegra_powergate_remove_clamping(unsigned int id)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tegra_powergate_sequence_power_up(int id, struct clk *clk,
|
static inline int tegra_powergate_sequence_power_up(unsigned int id,
|
||||||
|
struct clk *clk,
|
||||||
struct reset_control *rst)
|
struct reset_control *rst)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tegra_io_rail_power_on(int id)
|
static inline int tegra_io_rail_power_on(unsigned int id)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tegra_io_rail_power_off(int id)
|
static inline int tegra_io_rail_power_off(unsigned int id)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue