Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ce1e3262
Commit
ce1e3262
authored
May 24, 2010
by
Colin Cross
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ARM: tegra: Add api to control internal powergating
Signed-off-by:
Colin Cross
<
ccross@android.com
>
parent
d377eb0d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
253 additions
and
0 deletions
+253
-0
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/Makefile
+1
-0
arch/arm/mach-tegra/include/mach/powergate.h
arch/arm/mach-tegra/include/mach/powergate.h
+40
-0
arch/arm/mach-tegra/powergate.c
arch/arm/mach-tegra/powergate.c
+212
-0
No files found.
arch/arm/mach-tegra/Makefile
View file @
ce1e3262
...
...
@@ -5,6 +5,7 @@ obj-y += clock.o
obj-y
+=
timer.o
obj-y
+=
gpio.o
obj-y
+=
pinmux.o
obj-y
+=
powergate.o
obj-y
+=
fuse.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)
+=
clock.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)
+=
tegra2_clocks.o
...
...
arch/arm/mach-tegra/include/mach/powergate.h
0 → 100644
View file @
ce1e3262
/*
* drivers/regulator/tegra-regulator.c
*
* Copyright (c) 2010 Google, Inc
*
* Author:
* Colin Cross <ccross@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _MACH_TEGRA_POWERGATE_H_
#define _MACH_TEGRA_POWERGATE_H_
#define TEGRA_POWERGATE_CPU 0
#define TEGRA_POWERGATE_3D 1
#define TEGRA_POWERGATE_VENC 2
#define TEGRA_POWERGATE_PCIE 3
#define TEGRA_POWERGATE_VDEC 4
#define TEGRA_POWERGATE_L2 5
#define TEGRA_POWERGATE_MPE 6
#define TEGRA_NUM_POWERGATE 7
int
tegra_powergate_power_on
(
int
id
);
int
tegra_powergate_power_off
(
int
id
);
bool
tegra_powergate_is_powered
(
int
id
);
int
tegra_powergate_remove_clamping
(
int
id
);
/* Must be called with clk disabled, and returns with clk enabled */
int
tegra_powergate_sequence_power_up
(
int
id
,
struct
clk
*
clk
);
#endif
/* _MACH_TEGRA_POWERGATE_H_ */
arch/arm/mach-tegra/powergate.c
0 → 100644
View file @
ce1e3262
/*
* drivers/powergate/tegra-powergate.c
*
* Copyright (c) 2010 Google, Inc
*
* Author:
* Colin Cross <ccross@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <mach/clk.h>
#include <mach/iomap.h>
#include <mach/powergate.h>
#define PWRGATE_TOGGLE 0x30
#define PWRGATE_TOGGLE_START (1 << 8)
#define REMOVE_CLAMPING 0x34
#define PWRGATE_STATUS 0x38
static
DEFINE_SPINLOCK
(
tegra_powergate_lock
);
static
void
__iomem
*
pmc
=
IO_ADDRESS
(
TEGRA_PMC_BASE
);
static
u32
pmc_read
(
unsigned
long
reg
)
{
return
readl
(
pmc
+
reg
);
}
static
void
pmc_write
(
u32
val
,
unsigned
long
reg
)
{
writel
(
val
,
pmc
+
reg
);
}
static
int
tegra_powergate_set
(
int
id
,
bool
new_state
)
{
bool
status
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
tegra_powergate_lock
,
flags
);
status
=
pmc_read
(
PWRGATE_STATUS
)
&
(
1
<<
id
);
if
(
status
==
new_state
)
{
spin_unlock_irqrestore
(
&
tegra_powergate_lock
,
flags
);
return
-
EINVAL
;
}
pmc_write
(
PWRGATE_TOGGLE_START
|
id
,
PWRGATE_TOGGLE
);
spin_unlock_irqrestore
(
&
tegra_powergate_lock
,
flags
);
return
0
;
}
int
tegra_powergate_power_on
(
int
id
)
{
if
(
id
<
0
||
id
>=
TEGRA_NUM_POWERGATE
)
return
-
EINVAL
;
return
tegra_powergate_set
(
id
,
true
);
}
int
tegra_powergate_power_off
(
int
id
)
{
if
(
id
<
0
||
id
>=
TEGRA_NUM_POWERGATE
)
return
-
EINVAL
;
return
tegra_powergate_set
(
id
,
false
);
}
bool
tegra_powergate_is_powered
(
int
id
)
{
u32
status
;
if
(
id
<
0
||
id
>=
TEGRA_NUM_POWERGATE
)
return
-
EINVAL
;
status
=
pmc_read
(
PWRGATE_STATUS
)
&
(
1
<<
id
);
return
!!
status
;
}
int
tegra_powergate_remove_clamping
(
int
id
)
{
u32
mask
;
if
(
id
<
0
||
id
>=
TEGRA_NUM_POWERGATE
)
return
-
EINVAL
;
/*
* Tegra 2 has a bug where PCIE and VDE clamping masks are
* swapped relatively to the partition ids
*/
if
(
id
==
TEGRA_POWERGATE_VDEC
)
mask
=
(
1
<<
TEGRA_POWERGATE_PCIE
);
else
if
(
id
==
TEGRA_POWERGATE_PCIE
)
mask
=
(
1
<<
TEGRA_POWERGATE_VDEC
);
else
mask
=
(
1
<<
id
);
pmc_write
(
mask
,
REMOVE_CLAMPING
);
return
0
;
}
/* Must be called with clk disabled, and returns with clk enabled */
int
tegra_powergate_sequence_power_up
(
int
id
,
struct
clk
*
clk
)
{
int
ret
;
tegra_periph_reset_assert
(
clk
);
ret
=
tegra_powergate_power_on
(
id
);
if
(
ret
)
goto
err_power
;
ret
=
clk_enable
(
clk
);
if
(
ret
)
goto
err_clk
;
udelay
(
10
);
ret
=
tegra_powergate_remove_clamping
(
id
);
if
(
ret
)
goto
err_clamp
;
udelay
(
10
);
tegra_periph_reset_deassert
(
clk
);
return
0
;
err_clamp:
clk_disable
(
clk
);
err_clk:
tegra_powergate_power_off
(
id
);
err_power:
return
ret
;
}
#ifdef CONFIG_DEBUG_FS
static
const
char
*
const
powergate_name
[]
=
{
[
TEGRA_POWERGATE_CPU
]
=
"cpu"
,
[
TEGRA_POWERGATE_3D
]
=
"3d"
,
[
TEGRA_POWERGATE_VENC
]
=
"venc"
,
[
TEGRA_POWERGATE_VDEC
]
=
"vdec"
,
[
TEGRA_POWERGATE_PCIE
]
=
"pcie"
,
[
TEGRA_POWERGATE_L2
]
=
"l2"
,
[
TEGRA_POWERGATE_MPE
]
=
"mpe"
,
};
static
int
powergate_show
(
struct
seq_file
*
s
,
void
*
data
)
{
int
i
;
seq_printf
(
s
,
" powergate powered
\n
"
);
seq_printf
(
s
,
"------------------
\n
"
);
for
(
i
=
0
;
i
<
TEGRA_NUM_POWERGATE
;
i
++
)
seq_printf
(
s
,
" %9s %7s
\n
"
,
powergate_name
[
i
],
tegra_powergate_is_powered
(
i
)
?
"yes"
:
"no"
);
return
0
;
}
static
int
powergate_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
powergate_show
,
inode
->
i_private
);
}
static
const
struct
file_operations
powergate_fops
=
{
.
open
=
powergate_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
static
int
__init
powergate_debugfs_init
(
void
)
{
struct
dentry
*
d
;
int
err
=
-
ENOMEM
;
d
=
debugfs_create_file
(
"powergate"
,
S_IRUGO
,
NULL
,
NULL
,
&
powergate_fops
);
if
(
!
d
)
return
-
ENOMEM
;
return
err
;
}
late_initcall
(
powergate_debugfs_init
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment