Commit 8e6de970 authored by Nicolas Ferre's avatar Nicolas Ferre

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
parents 5e358e39 385acc0d
...@@ -24,7 +24,7 @@ config SOC_SAMA5 ...@@ -24,7 +24,7 @@ config SOC_SAMA5
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select MEMORY select MEMORY
select ATMEL_SDRAMC select ATMEL_SDRAMC
select PHYLIB if NETDEVICES select SRAM if PM
menu "Atmel AT91 System-on-Chip" menu "Atmel AT91 System-on-Chip"
...@@ -81,6 +81,7 @@ config SOC_AT91RM9200 ...@@ -81,6 +81,7 @@ config SOC_AT91RM9200
select CPU_ARM920T select CPU_ARM920T
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_AT91_USB_CLK select HAVE_AT91_USB_CLK
select SRAM if PM
config SOC_AT91SAM9 config SOC_AT91SAM9
bool "AT91SAM9" bool "AT91SAM9"
...@@ -94,6 +95,7 @@ config SOC_AT91SAM9 ...@@ -94,6 +95,7 @@ config SOC_AT91SAM9
select HAVE_AT91_UTMI select HAVE_AT91_UTMI
select HAVE_FB_ATMEL select HAVE_FB_ATMEL
select MEMORY select MEMORY
select SRAM if PM
help help
Select this if you are using one of those Atmel SoC: Select this if you are using one of those Atmel SoC:
AT91SAM9260 AT91SAM9260
...@@ -116,20 +118,6 @@ endif # SOC_SAM_V4_V5 ...@@ -116,20 +118,6 @@ endif # SOC_SAM_V4_V5
comment "AT91 Feature Selections" 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 config AT91_TIMER_HZ
int "Kernel HZ (jiffies per second)" int "Kernel HZ (jiffies per second)"
range 32 1024 range 32 1024
......
...@@ -13,7 +13,7 @@ obj-$(CONFIG_SOC_SAMA5) += sama5.o ...@@ -13,7 +13,7 @@ obj-$(CONFIG_SOC_SAMA5) += sama5.o
# Power Management # Power Management
obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o obj-$(CONFIG_PM) += pm_suspend.o
ifeq ($(CONFIG_PM_DEBUG),y) ifeq ($(CONFIG_PM_DEBUG),y)
CFLAGS_pm.o += -DDEBUG CFLAGS_pm.o += -DDEBUG
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/fncpy.h>
#include <asm/cacheflush.h>
#include <mach/cpu.h> #include <mach/cpu.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -41,7 +43,6 @@ static struct { ...@@ -41,7 +43,6 @@ static struct {
int memctrl; int memctrl;
} at91_pm_data; } at91_pm_data;
static void (*at91_pm_standby)(void);
void __iomem *at91_ramc_base[2]; void __iomem *at91_ramc_base[2];
static int at91_pm_valid_state(suspend_state_t state) static int at91_pm_valid_state(suspend_state_t state)
...@@ -119,15 +120,28 @@ int at91_suspend_entering_slow_clock(void) ...@@ -119,15 +120,28 @@ int at91_suspend_entering_slow_clock(void)
} }
EXPORT_SYMBOL(at91_suspend_entering_slow_clock); EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl); void __iomem *ramc1, int memctrl);
#ifdef CONFIG_AT91_SLOW_CLOCK extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0,
extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl); void __iomem *ramc1, int memctrl);
extern u32 at91_slow_clock_sz; extern u32 at91_pm_suspend_in_sram_sz;
#endif
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) static int at91_pm_enter(suspend_state_t state)
{ {
...@@ -136,8 +150,8 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -136,8 +150,8 @@ static int at91_pm_enter(suspend_state_t state)
switch (state) { switch (state) {
/* /*
* Suspend-to-RAM is like STANDBY plus slow clock mode, so * Suspend-to-RAM is like STANDBY plus slow clock mode, so
* drivers must suspend more deeply: only the master clock * drivers must suspend more deeply, the master clock switches
* controller may be using the main oscillator. * to the clk32k and turns off the main oscillator
*/ */
case PM_SUSPEND_MEM: case PM_SUSPEND_MEM:
/* /*
...@@ -146,23 +160,9 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -146,23 +160,9 @@ static int at91_pm_enter(suspend_state_t state)
if (!at91_pm_verify_clocks()) if (!at91_pm_verify_clocks())
goto error; goto error;
/* at91_pm_suspend(state);
* 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; 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 * STANDBY mode has *all* drivers suspended; ignores irqs not
...@@ -171,15 +171,7 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -171,15 +171,7 @@ static int at91_pm_enter(suspend_state_t state)
* nothing fancy done with main or cpu clocks. * nothing fancy done with main or cpu clocks.
*/ */
case PM_SUSPEND_STANDBY: case PM_SUSPEND_STANDBY:
/* at91_pm_suspend(state);
* 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; break;
case PM_SUSPEND_ON: case PM_SUSPEND_ON:
...@@ -218,12 +210,10 @@ static struct platform_device at91_cpuidle_device = { ...@@ -218,12 +210,10 @@ static struct platform_device at91_cpuidle_device = {
.name = "cpuidle-at91", .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_cpuidle_device.dev.platform_data = at91_standby;
at91_pm_standby = at91_standby;
}
} }
static const struct of_device_id ramc_ids[] __initconst = { static const struct of_device_id ramc_ids[] __initconst = {
...@@ -263,7 +253,6 @@ static __init void at91_dt_ramc(void) ...@@ -263,7 +253,6 @@ static __init void at91_dt_ramc(void)
at91_pm_set_standby(standby); at91_pm_set_standby(standby);
} }
#ifdef CONFIG_AT91_SLOW_CLOCK
static void __init at91_pm_sram_init(void) static void __init at91_pm_sram_init(void)
{ {
struct gen_pool *sram_pool; struct gen_pool *sram_pool;
...@@ -291,30 +280,36 @@ static void __init at91_pm_sram_init(void) ...@@ -291,30 +280,36 @@ static void __init at91_pm_sram_init(void)
return; 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) { if (!sram_base) {
pr_warn("%s: unable to alloc ocram!\n", __func__); pr_warn("%s: unable to alloc sram!\n", __func__);
return; return;
} }
sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base); sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false); at91_suspend_sram_fn = __arm_ioremap_exec(sram_pbase,
} at91_pm_suspend_in_sram_sz, false);
#endif 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) static void __init at91_pm_init(void)
{ {
#ifdef CONFIG_AT91_SLOW_CLOCK
at91_pm_sram_init(); 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) if (at91_cpuidle_device.dev.platform_data)
platform_device_register(&at91_cpuidle_device); platform_device_register(&at91_cpuidle_device);
if (at91_suspend_sram_fn)
suspend_set_ops(&at91_pm_ops); 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) void __init at91rm9200_pm_init(void)
......
...@@ -15,11 +15,13 @@ ...@@ -15,11 +15,13 @@
#include <mach/at91_ramc.h> #include <mach/at91_ramc.h>
#ifdef CONFIG_PM #define AT91_PM_MEMTYPE_MASK 0x0f
extern void at91_pm_set_standby(void (*at91_standby)(void));
#else #define AT91_PM_MODE_OFFSET 4
static inline void at91_pm_set_standby(void (*at91_standby)(void)) { } #define AT91_PM_MODE_MASK 0x01
#endif #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 * 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)) { } ...@@ -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. * still in self-refresh is "not recommended", but seems to work.
*/ */
#ifndef __ASSEMBLY__
static inline void at91rm9200_standby(void) static inline void at91rm9200_standby(void)
{ {
u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR); u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR);
...@@ -112,3 +115,4 @@ static inline void at91sam9_sdram_standby(void) ...@@ -112,3 +115,4 @@ static inline void at91sam9_sdram_standby(void)
} }
#endif #endif
#endif
...@@ -11,13 +11,10 @@ ...@@ -11,13 +11,10 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/micrel_phy.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/phy.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -29,25 +26,8 @@ ...@@ -29,25 +26,8 @@
#include "generic.h" #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) 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); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
at91sam9x5_pm_init(); at91sam9x5_pm_init();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment