mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-06 06:55:26 +07:00
First batch of cleanup for 4.1:
- little phy fixup that is not needed anymore - hudge cleanup of the PM code: - removal of "use slow clock" option => always use this for suspend to RAM - quicker suspend as the asm function is copied only once to SRAM - use of the same asm function for "standby" and "mem" types of suspend actions - adaptation to the ARMv7 processors -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJVAt/fAAoJEAf03oE53VmQgOoH/jx++6J1scYocHL2qAVEFfj4 USmBkzdr5YjG6AyUW6HfwerxpfUg2jhmJF4ClAEGxVMsa48djZwvuBp1cNv+8174 9Tvbd/UPY0+F+dfOmCeYjABnlA8Q9kYbxaxYrCNoUv0C5TDkuZkNp26KZdNMH97z wbeByy/y2un8hrMeXSz2kQPPqdU1vKTxulFTI9Xc7nr0f6ij4FsGws55X7JI4QXM Dc6EBph0/iEjXDhu6YNaSqyVKu8a0wj3anDWkbVmdbmQYvE3rDDoFXTtxcWGNfDi YssCfqLLv+arrxHXULTc+ifXojcWWgxHdK9HgGzBoVacOQIPrcBD7TcE5H0JU1k= =ylaZ -----END PGP SIGNATURE----- Merge tag 'at91-cleanup' into at91-4.1-multiplatform First batch of cleanup for 4.1: - little phy fixup that is not needed anymore - hudge cleanup of the PM code: - removal of "use slow clock" option => always use this for suspend to RAM - quicker suspend as the asm function is copied only once to SRAM - use of the same asm function for "standby" and "mem" types of suspend actions - adaptation to the ARMv7 processors
This commit is contained in:
commit
8e6de97083
@ -24,7 +24,7 @@ config SOC_SAMA5
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select MEMORY
|
||||
select ATMEL_SDRAMC
|
||||
select PHYLIB if NETDEVICES
|
||||
select SRAM if PM
|
||||
|
||||
menu "Atmel AT91 System-on-Chip"
|
||||
|
||||
@ -81,6 +81,7 @@ config SOC_AT91RM9200
|
||||
select CPU_ARM920T
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_AT91_USB_CLK
|
||||
select SRAM if PM
|
||||
|
||||
config SOC_AT91SAM9
|
||||
bool "AT91SAM9"
|
||||
@ -94,6 +95,7 @@ config SOC_AT91SAM9
|
||||
select HAVE_AT91_UTMI
|
||||
select HAVE_FB_ATMEL
|
||||
select MEMORY
|
||||
select SRAM if PM
|
||||
help
|
||||
Select this if you are using one of those Atmel SoC:
|
||||
AT91SAM9260
|
||||
@ -116,20 +118,6 @@ endif # SOC_SAM_V4_V5
|
||||
|
||||
comment "AT91 Feature Selections"
|
||||
|
||||
config AT91_SLOW_CLOCK
|
||||
bool "Suspend-to-RAM disables main oscillator"
|
||||
select SRAM
|
||||
depends on SUSPEND
|
||||
help
|
||||
Select this if you want Suspend-to-RAM to save the most power
|
||||
possible (without powering off the CPU) by disabling the PLLs
|
||||
and main oscillator so that only the 32 KiHz clock is available.
|
||||
|
||||
When only that slow-clock is available, some peripherals lose
|
||||
functionality. Many can't issue wakeup events unless faster
|
||||
clocks are available. Some lose their operating state and
|
||||
need to be completely re-initialized.
|
||||
|
||||
config AT91_TIMER_HZ
|
||||
int "Kernel HZ (jiffies per second)"
|
||||
range 32 1024
|
||||
|
@ -13,7 +13,7 @@ obj-$(CONFIG_SOC_SAMA5) += sama5.o
|
||||
|
||||
# Power Management
|
||||
obj-$(CONFIG_PM) += pm.o
|
||||
obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o
|
||||
obj-$(CONFIG_PM) += pm_suspend.o
|
||||
|
||||
ifeq ($(CONFIG_PM_DEBUG),y)
|
||||
CFLAGS_pm.o += -DDEBUG
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/fncpy.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <mach/cpu.h>
|
||||
#include <mach/hardware.h>
|
||||
@ -41,7 +43,6 @@ static struct {
|
||||
int memctrl;
|
||||
} at91_pm_data;
|
||||
|
||||
static void (*at91_pm_standby)(void);
|
||||
void __iomem *at91_ramc_base[2];
|
||||
|
||||
static int at91_pm_valid_state(suspend_state_t state)
|
||||
@ -119,76 +120,67 @@ int at91_suspend_entering_slow_clock(void)
|
||||
}
|
||||
EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
|
||||
|
||||
|
||||
static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0,
|
||||
static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
|
||||
void __iomem *ramc1, int memctrl);
|
||||
|
||||
#ifdef CONFIG_AT91_SLOW_CLOCK
|
||||
extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
|
||||
extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0,
|
||||
void __iomem *ramc1, int memctrl);
|
||||
extern u32 at91_slow_clock_sz;
|
||||
#endif
|
||||
extern u32 at91_pm_suspend_in_sram_sz;
|
||||
|
||||
static void at91_pm_suspend(suspend_state_t state)
|
||||
{
|
||||
unsigned int pm_data = at91_pm_data.memctrl;
|
||||
|
||||
pm_data |= (state == PM_SUSPEND_MEM) ?
|
||||
AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
|
||||
|
||||
flush_cache_all();
|
||||
outer_disable();
|
||||
|
||||
at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0],
|
||||
at91_ramc_base[1], pm_data);
|
||||
|
||||
outer_resume();
|
||||
}
|
||||
|
||||
static int at91_pm_enter(suspend_state_t state)
|
||||
{
|
||||
at91_pinctrl_gpio_suspend();
|
||||
|
||||
switch (state) {
|
||||
/*
|
||||
* Suspend-to-RAM is like STANDBY plus slow clock mode, so
|
||||
* drivers must suspend more deeply, the master clock switches
|
||||
* to the clk32k and turns off the main oscillator
|
||||
*/
|
||||
case PM_SUSPEND_MEM:
|
||||
/*
|
||||
* Suspend-to-RAM is like STANDBY plus slow clock mode, so
|
||||
* drivers must suspend more deeply: only the master clock
|
||||
* controller may be using the main oscillator.
|
||||
* Ensure that clocks are in a valid state.
|
||||
*/
|
||||
case PM_SUSPEND_MEM:
|
||||
/*
|
||||
* Ensure that clocks are in a valid state.
|
||||
*/
|
||||
if (!at91_pm_verify_clocks())
|
||||
goto error;
|
||||
|
||||
/*
|
||||
* Enter slow clock mode by switching over to clk32k and
|
||||
* turning off the main oscillator; reverse on wakeup.
|
||||
*/
|
||||
if (slow_clock) {
|
||||
#ifdef CONFIG_AT91_SLOW_CLOCK
|
||||
/* copy slow_clock handler to SRAM, and call it */
|
||||
memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
|
||||
#endif
|
||||
slow_clock(at91_pmc_base, at91_ramc_base[0],
|
||||
at91_ramc_base[1],
|
||||
at91_pm_data.memctrl);
|
||||
break;
|
||||
} else {
|
||||
pr_info("AT91: PM - no slow clock mode enabled ...\n");
|
||||
/* FALLTHROUGH leaving master clock alone */
|
||||
}
|
||||
|
||||
/*
|
||||
* STANDBY mode has *all* drivers suspended; ignores irqs not
|
||||
* marked as 'wakeup' event sources; and reduces DRAM power.
|
||||
* But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and
|
||||
* nothing fancy done with main or cpu clocks.
|
||||
*/
|
||||
case PM_SUSPEND_STANDBY:
|
||||
/*
|
||||
* NOTE: the Wait-for-Interrupt instruction needs to be
|
||||
* in icache so no SDRAM accesses are needed until the
|
||||
* wakeup IRQ occurs and self-refresh is terminated.
|
||||
* For ARM 926 based chips, this requirement is weaker
|
||||
* as at91sam9 can access a RAM in self-refresh mode.
|
||||
*/
|
||||
if (at91_pm_standby)
|
||||
at91_pm_standby();
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_ON:
|
||||
cpu_do_idle();
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_debug("AT91: PM - bogus suspend state %d\n", state);
|
||||
if (!at91_pm_verify_clocks())
|
||||
goto error;
|
||||
|
||||
at91_pm_suspend(state);
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
* STANDBY mode has *all* drivers suspended; ignores irqs not
|
||||
* marked as 'wakeup' event sources; and reduces DRAM power.
|
||||
* But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and
|
||||
* nothing fancy done with main or cpu clocks.
|
||||
*/
|
||||
case PM_SUSPEND_STANDBY:
|
||||
at91_pm_suspend(state);
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_ON:
|
||||
cpu_do_idle();
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_debug("AT91: PM - bogus suspend state %d\n", state);
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
@ -218,12 +210,10 @@ static struct platform_device at91_cpuidle_device = {
|
||||
.name = "cpuidle-at91",
|
||||
};
|
||||
|
||||
void at91_pm_set_standby(void (*at91_standby)(void))
|
||||
static void at91_pm_set_standby(void (*at91_standby)(void))
|
||||
{
|
||||
if (at91_standby) {
|
||||
if (at91_standby)
|
||||
at91_cpuidle_device.dev.platform_data = at91_standby;
|
||||
at91_pm_standby = at91_standby;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct of_device_id ramc_ids[] __initconst = {
|
||||
@ -263,7 +253,6 @@ static __init void at91_dt_ramc(void)
|
||||
at91_pm_set_standby(standby);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AT91_SLOW_CLOCK
|
||||
static void __init at91_pm_sram_init(void)
|
||||
{
|
||||
struct gen_pool *sram_pool;
|
||||
@ -291,30 +280,36 @@ static void __init at91_pm_sram_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz);
|
||||
sram_base = gen_pool_alloc(sram_pool, at91_pm_suspend_in_sram_sz);
|
||||
if (!sram_base) {
|
||||
pr_warn("%s: unable to alloc ocram!\n", __func__);
|
||||
pr_warn("%s: unable to alloc sram!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
|
||||
slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false);
|
||||
}
|
||||
#endif
|
||||
at91_suspend_sram_fn = __arm_ioremap_exec(sram_pbase,
|
||||
at91_pm_suspend_in_sram_sz, false);
|
||||
if (!at91_suspend_sram_fn) {
|
||||
pr_warn("SRAM: Could not map\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the pm suspend handler to SRAM */
|
||||
at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
|
||||
&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
|
||||
}
|
||||
|
||||
static void __init at91_pm_init(void)
|
||||
{
|
||||
#ifdef CONFIG_AT91_SLOW_CLOCK
|
||||
at91_pm_sram_init();
|
||||
#endif
|
||||
|
||||
pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : ""));
|
||||
|
||||
if (at91_cpuidle_device.dev.platform_data)
|
||||
platform_device_register(&at91_cpuidle_device);
|
||||
|
||||
suspend_set_ops(&at91_pm_ops);
|
||||
if (at91_suspend_sram_fn)
|
||||
suspend_set_ops(&at91_pm_ops);
|
||||
else
|
||||
pr_info("AT91: PM not supported, due to no SRAM allocated\n");
|
||||
}
|
||||
|
||||
void __init at91rm9200_pm_init(void)
|
||||
|
@ -15,11 +15,13 @@
|
||||
|
||||
#include <mach/at91_ramc.h>
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
extern void at91_pm_set_standby(void (*at91_standby)(void));
|
||||
#else
|
||||
static inline void at91_pm_set_standby(void (*at91_standby)(void)) { }
|
||||
#endif
|
||||
#define AT91_PM_MEMTYPE_MASK 0x0f
|
||||
|
||||
#define AT91_PM_MODE_OFFSET 4
|
||||
#define AT91_PM_MODE_MASK 0x01
|
||||
#define AT91_PM_MODE(x) (((x) & AT91_PM_MODE_MASK) << AT91_PM_MODE_OFFSET)
|
||||
|
||||
#define AT91_PM_SLOW_CLOCK 0x01
|
||||
|
||||
/*
|
||||
* The AT91RM9200 goes into self-refresh mode with this command, and will
|
||||
@ -31,6 +33,7 @@ static inline void at91_pm_set_standby(void (*at91_standby)(void)) { }
|
||||
* still in self-refresh is "not recommended", but seems to work.
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
static inline void at91rm9200_standby(void)
|
||||
{
|
||||
u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR);
|
||||
@ -112,3 +115,4 @@ static inline void at91sam9_sdram_standby(void)
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,335 +0,0 @@
|
||||
/*
|
||||
* arch/arm/mach-at91/pm_slow_clock.S
|
||||
*
|
||||
* Copyright (C) 2006 Savin Zlobec
|
||||
*
|
||||
* AT91SAM9 support:
|
||||
* Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/clk/at91_pmc.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/at91_ramc.h>
|
||||
|
||||
/*
|
||||
* When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
|
||||
* clock during suspend by adjusting its prescalar and divisor.
|
||||
* NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
|
||||
* are errata regarding adjusting the prescalar and divisor.
|
||||
*/
|
||||
#undef SLOWDOWN_MASTER_CLOCK
|
||||
|
||||
pmc .req r0
|
||||
sdramc .req r1
|
||||
ramc1 .req r2
|
||||
memctrl .req r3
|
||||
tmp1 .req r4
|
||||
tmp2 .req r5
|
||||
|
||||
/*
|
||||
* Wait until master clock is ready (after switching master clock source)
|
||||
*/
|
||||
.macro wait_mckrdy
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_MCKRDY
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Wait until master oscillator has stabilized.
|
||||
*/
|
||||
.macro wait_moscrdy
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_MOSCS
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Wait until PLLA has locked.
|
||||
*/
|
||||
.macro wait_pllalock
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_LOCKA
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Wait until PLLB has locked.
|
||||
*/
|
||||
.macro wait_pllblock
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_LOCKB
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
.text
|
||||
|
||||
.arm
|
||||
|
||||
/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
|
||||
* void __iomem *ramc1, int memctrl)
|
||||
*/
|
||||
ENTRY(at91_slow_clock)
|
||||
/* Save registers on stack */
|
||||
stmfd sp!, {r4 - r12, lr}
|
||||
|
||||
/*
|
||||
* Register usage:
|
||||
* R0 = Base address of AT91_PMC
|
||||
* R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
|
||||
* R2 = Base address of second RAM Controller or 0 if not present
|
||||
* R3 = Memory controller
|
||||
* R4 = temporary register
|
||||
* R5 = temporary register
|
||||
*/
|
||||
|
||||
/* Drain write buffer */
|
||||
mov tmp1, #0
|
||||
mcr p15, 0, tmp1, c7, c10, 4
|
||||
|
||||
cmp memctrl, #AT91_MEMCTRL_MC
|
||||
bne ddr_sr_enable
|
||||
|
||||
/*
|
||||
* at91rm9200 Memory controller
|
||||
*/
|
||||
/* Put SDRAM in self-refresh mode */
|
||||
mov tmp1, #1
|
||||
str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
|
||||
b sdr_sr_done
|
||||
|
||||
/*
|
||||
* DDRSDR Memory controller
|
||||
*/
|
||||
ddr_sr_enable:
|
||||
cmp memctrl, #AT91_MEMCTRL_DDRSDR
|
||||
bne sdr_sr_enable
|
||||
|
||||
/* LPDDR1 --> force DDR2 mode during self-refresh */
|
||||
ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR]
|
||||
str tmp1, .saved_sam9_mdr
|
||||
bic tmp1, tmp1, #~AT91_DDRSDRC_MD
|
||||
cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR
|
||||
ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
|
||||
biceq tmp1, tmp1, #AT91_DDRSDRC_MD
|
||||
orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2
|
||||
streq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
|
||||
|
||||
/* prepare for DDRAM self-refresh mode */
|
||||
ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
|
||||
str tmp1, .saved_sam9_lpr
|
||||
bic tmp1, #AT91_DDRSDRC_LPCB
|
||||
orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
|
||||
|
||||
/* figure out if we use the second ram controller */
|
||||
cmp ramc1, #0
|
||||
beq ddr_no_2nd_ctrl
|
||||
|
||||
ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR]
|
||||
str tmp2, .saved_sam9_mdr1
|
||||
bic tmp2, tmp2, #~AT91_DDRSDRC_MD
|
||||
cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR
|
||||
ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
|
||||
biceq tmp2, tmp2, #AT91_DDRSDRC_MD
|
||||
orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2
|
||||
streq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
|
||||
|
||||
ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR]
|
||||
str tmp2, .saved_sam9_lpr1
|
||||
bic tmp2, #AT91_DDRSDRC_LPCB
|
||||
orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
|
||||
|
||||
/* Enable DDRAM self-refresh mode */
|
||||
str tmp2, [ramc1, #AT91_DDRSDRC_LPR]
|
||||
ddr_no_2nd_ctrl:
|
||||
str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
|
||||
|
||||
b sdr_sr_done
|
||||
|
||||
/*
|
||||
* SDRAMC Memory controller
|
||||
*/
|
||||
sdr_sr_enable:
|
||||
/* Enable SDRAM self-refresh mode */
|
||||
ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
|
||||
str tmp1, .saved_sam9_lpr
|
||||
|
||||
bic tmp1, #AT91_SDRAMC_LPCB
|
||||
orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
|
||||
str tmp1, [sdramc, #AT91_SDRAMC_LPR]
|
||||
|
||||
sdr_sr_done:
|
||||
/* Save Master clock setting */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, .saved_mckr
|
||||
|
||||
/*
|
||||
* Set the Master clock source to slow clock
|
||||
*/
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
#ifdef SLOWDOWN_MASTER_CLOCK
|
||||
/*
|
||||
* Set the Master Clock PRES and MDIV fields.
|
||||
*
|
||||
* See AT91RM9200 errata #27 and #28 for details.
|
||||
*/
|
||||
mov tmp1, #0
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
|
||||
wait_mckrdy
|
||||
#endif
|
||||
|
||||
/* Save PLLA setting and disable it */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
str tmp1, .saved_pllar
|
||||
|
||||
mov tmp1, #AT91_PMC_PLLCOUNT
|
||||
orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
|
||||
str tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
|
||||
/* Save PLLB setting and disable it */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_PLLBR]
|
||||
str tmp1, .saved_pllbr
|
||||
|
||||
mov tmp1, #AT91_PMC_PLLCOUNT
|
||||
str tmp1, [pmc, #AT91_CKGR_PLLBR]
|
||||
|
||||
/* Turn off the main oscillator */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
bic tmp1, tmp1, #AT91_PMC_MOSCEN
|
||||
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
|
||||
/* Wait for interrupt */
|
||||
mcr p15, 0, tmp1, c7, c0, 4
|
||||
|
||||
/* Turn on the main oscillator */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
orr tmp1, tmp1, #AT91_PMC_MOSCEN
|
||||
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
|
||||
wait_moscrdy
|
||||
|
||||
/* Restore PLLB setting */
|
||||
ldr tmp1, .saved_pllbr
|
||||
str tmp1, [pmc, #AT91_CKGR_PLLBR]
|
||||
|
||||
tst tmp1, #(AT91_PMC_MUL & 0xff0000)
|
||||
bne 1f
|
||||
tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
|
||||
beq 2f
|
||||
1:
|
||||
wait_pllblock
|
||||
2:
|
||||
|
||||
/* Restore PLLA setting */
|
||||
ldr tmp1, .saved_pllar
|
||||
str tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
|
||||
tst tmp1, #(AT91_PMC_MUL & 0xff0000)
|
||||
bne 3f
|
||||
tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
|
||||
beq 4f
|
||||
3:
|
||||
wait_pllalock
|
||||
4:
|
||||
|
||||
#ifdef SLOWDOWN_MASTER_CLOCK
|
||||
/*
|
||||
* First set PRES if it was not 0,
|
||||
* than set CSS and MDIV fields.
|
||||
*
|
||||
* See AT91RM9200 errata #27 and #28 for details.
|
||||
*/
|
||||
ldr tmp1, .saved_mckr
|
||||
tst tmp1, #AT91_PMC_PRES
|
||||
beq 2f
|
||||
and tmp1, tmp1, #AT91_PMC_PRES
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
|
||||
wait_mckrdy
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Restore master clock setting
|
||||
*/
|
||||
2: ldr tmp1, .saved_mckr
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
/*
|
||||
* at91rm9200 Memory controller
|
||||
* Do nothing - self-refresh is automatically disabled.
|
||||
*/
|
||||
cmp memctrl, #AT91_MEMCTRL_MC
|
||||
beq ram_restored
|
||||
|
||||
/*
|
||||
* DDRSDR Memory controller
|
||||
*/
|
||||
cmp memctrl, #AT91_MEMCTRL_DDRSDR
|
||||
bne sdr_en_restore
|
||||
/* Restore MDR in case of LPDDR1 */
|
||||
ldr tmp1, .saved_sam9_mdr
|
||||
str tmp1, [sdramc, #AT91_DDRSDRC_MDR]
|
||||
/* Restore LPR on AT91 with DDRAM */
|
||||
ldr tmp1, .saved_sam9_lpr
|
||||
str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
|
||||
|
||||
/* if we use the second ram controller */
|
||||
cmp ramc1, #0
|
||||
ldrne tmp2, .saved_sam9_mdr1
|
||||
strne tmp2, [ramc1, #AT91_DDRSDRC_MDR]
|
||||
ldrne tmp2, .saved_sam9_lpr1
|
||||
strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
|
||||
|
||||
b ram_restored
|
||||
|
||||
/*
|
||||
* SDRAMC Memory controller
|
||||
*/
|
||||
sdr_en_restore:
|
||||
/* Restore LPR on AT91 with SDRAM */
|
||||
ldr tmp1, .saved_sam9_lpr
|
||||
str tmp1, [sdramc, #AT91_SDRAMC_LPR]
|
||||
|
||||
ram_restored:
|
||||
/* Restore registers, and return */
|
||||
ldmfd sp!, {r4 - r12, pc}
|
||||
|
||||
|
||||
.saved_mckr:
|
||||
.word 0
|
||||
|
||||
.saved_pllar:
|
||||
.word 0
|
||||
|
||||
.saved_pllbr:
|
||||
.word 0
|
||||
|
||||
.saved_sam9_lpr:
|
||||
.word 0
|
||||
|
||||
.saved_sam9_lpr1:
|
||||
.word 0
|
||||
|
||||
.saved_sam9_mdr:
|
||||
.word 0
|
||||
|
||||
.saved_sam9_mdr1:
|
||||
.word 0
|
||||
|
||||
ENTRY(at91_slow_clock_sz)
|
||||
.word .-at91_slow_clock
|
338
arch/arm/mach-at91/pm_suspend.S
Normal file
338
arch/arm/mach-at91/pm_suspend.S
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* arch/arm/mach-at91/pm_slow_clock.S
|
||||
*
|
||||
* Copyright (C) 2006 Savin Zlobec
|
||||
*
|
||||
* AT91SAM9 support:
|
||||
* Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/clk/at91_pmc.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/at91_ramc.h>
|
||||
#include "pm.h"
|
||||
|
||||
#define SRAMC_SELF_FRESH_ACTIVE 0x01
|
||||
#define SRAMC_SELF_FRESH_EXIT 0x00
|
||||
|
||||
pmc .req r0
|
||||
tmp1 .req r4
|
||||
tmp2 .req r5
|
||||
|
||||
/*
|
||||
* Wait until master clock is ready (after switching master clock source)
|
||||
*/
|
||||
.macro wait_mckrdy
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_MCKRDY
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Wait until master oscillator has stabilized.
|
||||
*/
|
||||
.macro wait_moscrdy
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_MOSCS
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Wait until PLLA has locked.
|
||||
*/
|
||||
.macro wait_pllalock
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_LOCKA
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Put the processor to enter the idle state
|
||||
*/
|
||||
.macro at91_cpu_idle
|
||||
|
||||
#if defined(CONFIG_CPU_V7)
|
||||
mov tmp1, #AT91_PMC_PCK
|
||||
str tmp1, [pmc, #AT91_PMC_SCDR]
|
||||
|
||||
dsb
|
||||
|
||||
wfi @ Wait For Interrupt
|
||||
#else
|
||||
mcr p15, 0, tmp1, c7, c0, 4
|
||||
#endif
|
||||
|
||||
.endm
|
||||
|
||||
.text
|
||||
|
||||
.arm
|
||||
|
||||
/*
|
||||
* void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
|
||||
* void __iomem *ramc1, int memctrl)
|
||||
* @input param:
|
||||
* @r0: base address of AT91_PMC
|
||||
* @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
|
||||
* @r2: base address of second SDRAM Controller or 0 if not present
|
||||
* @r3: pm information
|
||||
*/
|
||||
ENTRY(at91_pm_suspend_in_sram)
|
||||
/* Save registers on stack */
|
||||
stmfd sp!, {r4 - r12, lr}
|
||||
|
||||
/* Drain write buffer */
|
||||
mov tmp1, #0
|
||||
mcr p15, 0, tmp1, c7, c10, 4
|
||||
|
||||
str r0, .pmc_base
|
||||
str r1, .sramc_base
|
||||
str r2, .sramc1_base
|
||||
|
||||
and r0, r3, #AT91_PM_MEMTYPE_MASK
|
||||
str r0, .memtype
|
||||
|
||||
lsr r0, r3, #AT91_PM_MODE_OFFSET
|
||||
and r0, r0, #AT91_PM_MODE_MASK
|
||||
str r0, .pm_mode
|
||||
|
||||
/* Active the self-refresh mode */
|
||||
mov r0, #SRAMC_SELF_FRESH_ACTIVE
|
||||
bl at91_sramc_self_refresh
|
||||
|
||||
ldr r0, .pm_mode
|
||||
tst r0, #AT91_PM_SLOW_CLOCK
|
||||
beq skip_disable_main_clock
|
||||
|
||||
ldr pmc, .pmc_base
|
||||
|
||||
/* Save Master clock setting */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, .saved_mckr
|
||||
|
||||
/*
|
||||
* Set the Master clock source to slow clock
|
||||
*/
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
/* Save PLLA setting and disable it */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
str tmp1, .saved_pllar
|
||||
|
||||
mov tmp1, #AT91_PMC_PLLCOUNT
|
||||
orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
|
||||
str tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
|
||||
/* Turn off the main oscillator */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
bic tmp1, tmp1, #AT91_PMC_MOSCEN
|
||||
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
|
||||
skip_disable_main_clock:
|
||||
ldr pmc, .pmc_base
|
||||
|
||||
/* Wait for interrupt */
|
||||
at91_cpu_idle
|
||||
|
||||
ldr r0, .pm_mode
|
||||
tst r0, #AT91_PM_SLOW_CLOCK
|
||||
beq skip_enable_main_clock
|
||||
|
||||
ldr pmc, .pmc_base
|
||||
|
||||
/* Turn on the main oscillator */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
orr tmp1, tmp1, #AT91_PMC_MOSCEN
|
||||
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
|
||||
wait_moscrdy
|
||||
|
||||
/* Restore PLLA setting */
|
||||
ldr tmp1, .saved_pllar
|
||||
str tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
|
||||
tst tmp1, #(AT91_PMC_MUL & 0xff0000)
|
||||
bne 3f
|
||||
tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
|
||||
beq 4f
|
||||
3:
|
||||
wait_pllalock
|
||||
4:
|
||||
|
||||
/*
|
||||
* Restore master clock setting
|
||||
*/
|
||||
ldr tmp1, .saved_mckr
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
skip_enable_main_clock:
|
||||
/* Exit the self-refresh mode */
|
||||
mov r0, #SRAMC_SELF_FRESH_EXIT
|
||||
bl at91_sramc_self_refresh
|
||||
|
||||
/* Restore registers, and return */
|
||||
ldmfd sp!, {r4 - r12, pc}
|
||||
ENDPROC(at91_pm_suspend_in_sram)
|
||||
|
||||
/*
|
||||
* void at91_sramc_self_refresh(unsigned int is_active)
|
||||
*
|
||||
* @input param:
|
||||
* @r0: 1 - active self-refresh mode
|
||||
* 0 - exit self-refresh mode
|
||||
* register usage:
|
||||
* @r1: memory type
|
||||
* @r2: base address of the sram controller
|
||||
*/
|
||||
|
||||
ENTRY(at91_sramc_self_refresh)
|
||||
ldr r1, .memtype
|
||||
ldr r2, .sramc_base
|
||||
|
||||
cmp r1, #AT91_MEMCTRL_MC
|
||||
bne ddrc_sf
|
||||
|
||||
/*
|
||||
* at91rm9200 Memory controller
|
||||
*/
|
||||
|
||||
/*
|
||||
* For exiting the self-refresh mode, do nothing,
|
||||
* automatically exit the self-refresh mode.
|
||||
*/
|
||||
tst r0, #SRAMC_SELF_FRESH_ACTIVE
|
||||
beq exit_sramc_sf
|
||||
|
||||
/* Active SDRAM self-refresh mode */
|
||||
mov r3, #1
|
||||
str r3, [r2, #AT91RM9200_SDRAMC_SRR]
|
||||
b exit_sramc_sf
|
||||
|
||||
ddrc_sf:
|
||||
cmp r1, #AT91_MEMCTRL_DDRSDR
|
||||
bne sdramc_sf
|
||||
|
||||
/*
|
||||
* DDR Memory controller
|
||||
*/
|
||||
tst r0, #SRAMC_SELF_FRESH_ACTIVE
|
||||
beq ddrc_exit_sf
|
||||
|
||||
/* LPDDR1 --> force DDR2 mode during self-refresh */
|
||||
ldr r3, [r2, #AT91_DDRSDRC_MDR]
|
||||
str r3, .saved_sam9_mdr
|
||||
bic r3, r3, #~AT91_DDRSDRC_MD
|
||||
cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
|
||||
ldreq r3, [r2, #AT91_DDRSDRC_MDR]
|
||||
biceq r3, r3, #AT91_DDRSDRC_MD
|
||||
orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
|
||||
streq r3, [r2, #AT91_DDRSDRC_MDR]
|
||||
|
||||
/* Active DDRC self-refresh mode */
|
||||
ldr r3, [r2, #AT91_DDRSDRC_LPR]
|
||||
str r3, .saved_sam9_lpr
|
||||
bic r3, r3, #AT91_DDRSDRC_LPCB
|
||||
orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
|
||||
str r3, [r2, #AT91_DDRSDRC_LPR]
|
||||
|
||||
/* If using the 2nd ddr controller */
|
||||
ldr r2, .sramc1_base
|
||||
cmp r2, #0
|
||||
beq no_2nd_ddrc
|
||||
|
||||
ldr r3, [r2, #AT91_DDRSDRC_MDR]
|
||||
str r3, .saved_sam9_mdr1
|
||||
bic r3, r3, #~AT91_DDRSDRC_MD
|
||||
cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
|
||||
ldreq r3, [r2, #AT91_DDRSDRC_MDR]
|
||||
biceq r3, r3, #AT91_DDRSDRC_MD
|
||||
orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
|
||||
streq r3, [r2, #AT91_DDRSDRC_MDR]
|
||||
|
||||
/* Active DDRC self-refresh mode */
|
||||
ldr r3, [r2, #AT91_DDRSDRC_LPR]
|
||||
str r3, .saved_sam9_lpr1
|
||||
bic r3, r3, #AT91_DDRSDRC_LPCB
|
||||
orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
|
||||
str r3, [r2, #AT91_DDRSDRC_LPR]
|
||||
|
||||
no_2nd_ddrc:
|
||||
b exit_sramc_sf
|
||||
|
||||
ddrc_exit_sf:
|
||||
/* Restore MDR in case of LPDDR1 */
|
||||
ldr r3, .saved_sam9_mdr
|
||||
str r3, [r2, #AT91_DDRSDRC_MDR]
|
||||
/* Restore LPR on AT91 with DDRAM */
|
||||
ldr r3, .saved_sam9_lpr
|
||||
str r3, [r2, #AT91_DDRSDRC_LPR]
|
||||
|
||||
/* If using the 2nd ddr controller */
|
||||
ldr r2, .sramc1_base
|
||||
cmp r2, #0
|
||||
ldrne r3, .saved_sam9_mdr1
|
||||
strne r3, [r2, #AT91_DDRSDRC_MDR]
|
||||
ldrne r3, .saved_sam9_lpr1
|
||||
strne r3, [r2, #AT91_DDRSDRC_LPR]
|
||||
|
||||
b exit_sramc_sf
|
||||
|
||||
/*
|
||||
* SDRAMC Memory controller
|
||||
*/
|
||||
sdramc_sf:
|
||||
tst r0, #SRAMC_SELF_FRESH_ACTIVE
|
||||
beq sdramc_exit_sf
|
||||
|
||||
/* Active SDRAMC self-refresh mode */
|
||||
ldr r3, [r2, #AT91_SDRAMC_LPR]
|
||||
str r3, .saved_sam9_lpr
|
||||
bic r3, r3, #AT91_SDRAMC_LPCB
|
||||
orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
|
||||
str r3, [r2, #AT91_SDRAMC_LPR]
|
||||
|
||||
sdramc_exit_sf:
|
||||
ldr r3, .saved_sam9_lpr
|
||||
str r3, [r2, #AT91_SDRAMC_LPR]
|
||||
|
||||
exit_sramc_sf:
|
||||
mov pc, lr
|
||||
ENDPROC(at91_sramc_self_refresh)
|
||||
|
||||
.pmc_base:
|
||||
.word 0
|
||||
.sramc_base:
|
||||
.word 0
|
||||
.sramc1_base:
|
||||
.word 0
|
||||
.memtype:
|
||||
.word 0
|
||||
.pm_mode:
|
||||
.word 0
|
||||
.saved_mckr:
|
||||
.word 0
|
||||
.saved_pllar:
|
||||
.word 0
|
||||
.saved_sam9_lpr:
|
||||
.word 0
|
||||
.saved_sam9_lpr1:
|
||||
.word 0
|
||||
.saved_sam9_mdr:
|
||||
.word 0
|
||||
.saved_sam9_mdr1:
|
||||
.word 0
|
||||
|
||||
ENTRY(at91_pm_suspend_in_sram_sz)
|
||||
.word .-at91_pm_suspend_in_sram
|
@ -11,13 +11,10 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/micrel_phy.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
@ -29,25 +26,8 @@
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
static int ksz8081_phy_fixup(struct phy_device *phy)
|
||||
{
|
||||
int value;
|
||||
|
||||
value = phy_read(phy, 0x16);
|
||||
value &= ~0x20;
|
||||
phy_write(phy, 0x16, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init sama5_dt_device_init(void)
|
||||
{
|
||||
if (of_machine_is_compatible("atmel,sama5d4ek") &&
|
||||
IS_ENABLED(CONFIG_PHYLIB)) {
|
||||
phy_register_fixup_for_id("fc028000.etherne:00",
|
||||
ksz8081_phy_fixup);
|
||||
}
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
at91sam9x5_pm_init();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user