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
nexedi
linux
Commits
c0d21f73
Commit
c0d21f73
authored
Jan 16, 2017
by
Sebastian Reichel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'psy-arm-at91-immutable' into psy-next
parents
9d60595a
0b040874
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
105 additions
and
3 deletions
+105
-3
drivers/power/reset/Kconfig
drivers/power/reset/Kconfig
+1
-1
drivers/power/reset/at91-poweroff.c
drivers/power/reset/at91-poweroff.c
+53
-1
drivers/power/reset/at91-sama5d2_shdwc.c
drivers/power/reset/at91-sama5d2_shdwc.c
+48
-1
include/soc/at91/at91sam9_ddrsdr.h
include/soc/at91/at91sam9_ddrsdr.h
+3
-0
No files found.
drivers/power/reset/Kconfig
View file @
c0d21f73
...
...
@@ -32,7 +32,7 @@ config POWER_RESET_AT91_RESET
config POWER_RESET_AT91_SAMA5D2_SHDWC
tristate "Atmel AT91 SAMA5D2-Compatible shutdown controller driver"
depends on ARCH_AT91
|| COMPILE_TEST
depends on ARCH_AT91
default SOC_SAMA5
help
This driver supports the alternate shutdown controller for some Atmel
...
...
drivers/power/reset/at91-poweroff.c
View file @
c0d21f73
...
...
@@ -14,9 +14,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
#include <soc/at91/at91sam9_ddrsdr.h>
#define AT91_SHDW_CR 0x00
/* Shut Down Control Register */
#define AT91_SHDW_SHDW BIT(0)
/* Shut Down command */
#define AT91_SHDW_KEY (0xa5 << 24)
/* KEY Password */
...
...
@@ -50,6 +53,7 @@ static const char *shdwc_wakeup_modes[] = {
static
void
__iomem
*
at91_shdwc_base
;
static
struct
clk
*
sclk
;
static
void
__iomem
*
mpddrc_base
;
static
void
__init
at91_wakeup_status
(
void
)
{
...
...
@@ -73,6 +77,29 @@ static void at91_poweroff(void)
writel
(
AT91_SHDW_KEY
|
AT91_SHDW_SHDW
,
at91_shdwc_base
+
AT91_SHDW_CR
);
}
static
void
at91_lpddr_poweroff
(
void
)
{
asm
volatile
(
/* Align to cache lines */
".balign 32
\n\t
"
/* Ensure AT91_SHDW_CR is in the TLB by reading it */
" ldr r6, [%2, #"
__stringify
(
AT91_SHDW_CR
)
"]
\n\t
"
/* Power down SDRAM0 */
" str %1, [%0, #"
__stringify
(
AT91_DDRSDRC_LPR
)
"]
\n\t
"
/* Shutdown CPU */
" str %3, [%2, #"
__stringify
(
AT91_SHDW_CR
)
"]
\n\t
"
" b .
\n\t
"
:
:
"r"
(
mpddrc_base
),
"r"
cpu_to_le32
(
AT91_DDRSDRC_LPDDR2_PWOFF
),
"r"
(
at91_shdwc_base
),
"r"
cpu_to_le32
(
AT91_SHDW_KEY
|
AT91_SHDW_SHDW
)
:
"r0"
);
}
static
int
at91_poweroff_get_wakeup_mode
(
struct
device_node
*
np
)
{
const
char
*
pm
;
...
...
@@ -124,6 +151,8 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
static
int
__init
at91_poweroff_probe
(
struct
platform_device
*
pdev
)
{
struct
resource
*
res
;
struct
device_node
*
np
;
u32
ddr_type
;
int
ret
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
...
...
@@ -150,12 +179,30 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
pm_power_off
=
at91_poweroff
;
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"atmel,sama5d3-ddramc"
);
if
(
!
np
)
return
0
;
mpddrc_base
=
of_iomap
(
np
,
0
);
of_node_put
(
np
);
if
(
!
mpddrc_base
)
return
0
;
ddr_type
=
readl
(
mpddrc_base
+
AT91_DDRSDRC_MDR
)
&
AT91_DDRSDRC_MD
;
if
((
ddr_type
==
AT91_DDRSDRC_MD_LPDDR2
)
||
(
ddr_type
==
AT91_DDRSDRC_MD_LPDDR3
))
pm_power_off
=
at91_lpddr_poweroff
;
else
iounmap
(
mpddrc_base
);
return
0
;
}
static
int
__exit
at91_poweroff_remove
(
struct
platform_device
*
pdev
)
{
if
(
pm_power_off
==
at91_poweroff
)
if
(
pm_power_off
==
at91_poweroff
||
pm_power_off
==
at91_lpddr_poweroff
)
pm_power_off
=
NULL
;
clk_disable_unprepare
(
sclk
);
...
...
@@ -163,6 +210,11 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev)
return
0
;
}
static
const
struct
of_device_id
at91_ramc_of_match
[]
=
{
{
.
compatible
=
"atmel,sama5d3-ddramc"
,
},
{
/* sentinel */
}
};
static
const
struct
of_device_id
at91_poweroff_of_match
[]
=
{
{
.
compatible
=
"atmel,at91sam9260-shdwc"
,
},
{
.
compatible
=
"atmel,at91sam9rl-shdwc"
,
},
...
...
drivers/power/reset/at91-sama5d2_shdwc.c
View file @
c0d21f73
...
...
@@ -22,9 +22,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
#include <soc/at91/at91sam9_ddrsdr.h>
#define SLOW_CLOCK_FREQ 32768
#define AT91_SHDW_CR 0x00
/* Shut Down Control Register */
...
...
@@ -75,6 +78,7 @@ struct shdwc {
*/
static
struct
shdwc
*
at91_shdwc
;
static
struct
clk
*
sclk
;
static
void
__iomem
*
mpddrc_base
;
static
const
unsigned
long
long
sdwc_dbc_period
[]
=
{
0
,
3
,
32
,
512
,
4096
,
32768
,
...
...
@@ -108,6 +112,29 @@ static void at91_poweroff(void)
at91_shdwc
->
at91_shdwc_base
+
AT91_SHDW_CR
);
}
static
void
at91_lpddr_poweroff
(
void
)
{
asm
volatile
(
/* Align to cache lines */
".balign 32
\n\t
"
/* Ensure AT91_SHDW_CR is in the TLB by reading it */
" ldr r6, [%2, #"
__stringify
(
AT91_SHDW_CR
)
"]
\n\t
"
/* Power down SDRAM0 */
" str %1, [%0, #"
__stringify
(
AT91_DDRSDRC_LPR
)
"]
\n\t
"
/* Shutdown CPU */
" str %3, [%2, #"
__stringify
(
AT91_SHDW_CR
)
"]
\n\t
"
" b .
\n\t
"
:
:
"r"
(
mpddrc_base
),
"r"
cpu_to_le32
(
AT91_DDRSDRC_LPDDR2_PWOFF
),
"r"
(
at91_shdwc
->
at91_shdwc_base
),
"r"
cpu_to_le32
(
AT91_SHDW_KEY
|
AT91_SHDW_SHDW
)
:
"r0"
);
}
static
u32
at91_shdwc_debouncer_value
(
struct
platform_device
*
pdev
,
u32
in_period_us
)
{
...
...
@@ -212,6 +239,8 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
{
struct
resource
*
res
;
const
struct
of_device_id
*
match
;
struct
device_node
*
np
;
u32
ddr_type
;
int
ret
;
if
(
!
pdev
->
dev
.
of_node
)
...
...
@@ -249,6 +278,23 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
pm_power_off
=
at91_poweroff
;
np
=
of_find_compatible_node
(
NULL
,
NULL
,
"atmel,sama5d3-ddramc"
);
if
(
!
np
)
return
0
;
mpddrc_base
=
of_iomap
(
np
,
0
);
of_node_put
(
np
);
if
(
!
mpddrc_base
)
return
0
;
ddr_type
=
readl
(
mpddrc_base
+
AT91_DDRSDRC_MDR
)
&
AT91_DDRSDRC_MD
;
if
((
ddr_type
==
AT91_DDRSDRC_MD_LPDDR2
)
||
(
ddr_type
==
AT91_DDRSDRC_MD_LPDDR3
))
pm_power_off
=
at91_lpddr_poweroff
;
else
iounmap
(
mpddrc_base
);
return
0
;
}
...
...
@@ -256,7 +302,8 @@ static int __exit at91_shdwc_remove(struct platform_device *pdev)
{
struct
shdwc
*
shdw
=
platform_get_drvdata
(
pdev
);
if
(
pm_power_off
==
at91_poweroff
)
if
(
pm_power_off
==
at91_poweroff
||
pm_power_off
==
at91_lpddr_poweroff
)
pm_power_off
=
NULL
;
/* Reset values to disable wake-up features */
...
...
include/soc/at91/at91sam9_ddrsdr.h
View file @
c0d21f73
...
...
@@ -81,6 +81,7 @@
#define AT91_DDRSDRC_LPCB_POWER_DOWN 2
#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3
#define AT91_DDRSDRC_CLKFR (1 << 2)
/* Clock Frozen */
#define AT91_DDRSDRC_LPDDR2_PWOFF (1 << 3)
/* LPDDR Power Off */
#define AT91_DDRSDRC_PASR (7 << 4)
/* Partial Array Self Refresh */
#define AT91_DDRSDRC_TCSR (3 << 8)
/* Temperature Compensated Self Refresh */
#define AT91_DDRSDRC_DS (3 << 10)
/* Drive Strength */
...
...
@@ -96,7 +97,9 @@
#define AT91_DDRSDRC_MD_SDR 0
#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
#define AT91_DDRSDRC_MD_LPDDR3 5
#define AT91_DDRSDRC_MD_DDR2 6
/* [SAM9 Only] */
#define AT91_DDRSDRC_MD_LPDDR2 7
#define AT91_DDRSDRC_DBW (1 << 4)
/* Data Bus Width */
#define AT91_DDRSDRC_DBW_32BITS (0 << 4)
#define AT91_DDRSDRC_DBW_16BITS (1 << 4)
...
...
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