Skip to content

Commit

Permalink
ARM: pxa: Access SMEMC via virtual addresses
Browse files Browse the repository at this point in the history
This is important because on PXA3xx, the physical mapping of SMEMC registers
differs from the one on PXA2xx. In order to get PCMCIA working on both PXA2xx
and PXA320, the PCMCIA driver was adjusted accordingly as well.

Also, various places in the kernel had to be patched to use
__raw_read/__raw_write.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
  • Loading branch information
Marek Vasut authored and Eric Miao committed Dec 16, 2010
1 parent 851982c commit ad68bb9
Show file tree
Hide file tree
Showing 22 changed files with 176 additions and 136 deletions.
13 changes: 7 additions & 6 deletions arch/arm/mach-pxa/cm-x2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <mach/pxa2xx-regs.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
#include <mach/smemc.h>

#include <asm/hardware/it8152.h>

Expand Down Expand Up @@ -392,9 +393,9 @@ static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state)
cmx2xx_pci_suspend();

/* save MSC registers */
sleep_save_msc[0] = MSC0;
sleep_save_msc[1] = MSC1;
sleep_save_msc[2] = MSC2;
sleep_save_msc[0] = __raw_readl(MSC0);
sleep_save_msc[1] = __raw_readl(MSC1);
sleep_save_msc[2] = __raw_readl(MSC2);

/* setup power saving mode registers */
PCFR = 0x0;
Expand All @@ -416,9 +417,9 @@ static int cmx2xx_resume(struct sys_device *dev)
cmx2xx_pci_resume();

/* restore MSC registers */
MSC0 = sleep_save_msc[0];
MSC1 = sleep_save_msc[1];
MSC2 = sleep_save_msc[2];
__raw_writel(sleep_save_msc[0], MSC0);
__raw_writel(sleep_save_msc[1], MSC1);
__raw_writel(sleep_save_msc[2], MSC2);

return 0;
}
Expand Down
10 changes: 6 additions & 4 deletions arch/arm/mach-pxa/cpufreq-pxa2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@
#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/regulator/consumer.h>
#include <linux/io.h>

#include <mach/pxa2xx-regs.h>
#include <mach/smemc.h>

#ifdef DEBUG
static unsigned int freq_debug;
Expand Down Expand Up @@ -242,7 +244,7 @@ static void pxa27x_guess_max_freq(void)

static void init_sdram_rows(void)
{
uint32_t mdcnfg = MDCNFG;
uint32_t mdcnfg = __raw_readl(MDCNFG);
unsigned int drac2 = 0, drac0 = 0;

if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3))
Expand Down Expand Up @@ -331,8 +333,8 @@ static int pxa_set_target(struct cpufreq_policy *policy,
* we need to preset the smaller DRI before the change. If we're
* speeding up we need to set the larger DRI value after the change.
*/
preset_mdrefr = postset_mdrefr = MDREFR;
if ((MDREFR & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
preset_mdrefr = postset_mdrefr = __raw_readl(MDREFR);
if ((preset_mdrefr & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK);
preset_mdrefr |= mdrefr_dri(new_freq_mem);
}
Expand Down Expand Up @@ -370,7 +372,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
3: nop \n\
"
: "=&r" (unused)
: "r" (&MDREFR), "r" (cclkcfg),
: "r" (MDREFR), "r" (cclkcfg),
"r" (preset_mdrefr), "r" (postset_mdrefr)
: "r4", "r5");
local_irq_restore(flags);
Expand Down
7 changes: 4 additions & 3 deletions arch/arm/mach-pxa/csb726.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <mach/ohci.h>
#include <mach/pxa2xx-regs.h>
#include <mach/audio.h>
#include <mach/smemc.h>

#include "generic.h"
#include "devices.h"
Expand Down Expand Up @@ -255,9 +256,9 @@ static struct platform_device *devices[] __initdata = {
static void __init csb726_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(csb726_pin_config));
/* MSC1 = 0x7ffc3ffc; *//* LAN9215/EXP_CS */
/* MSC2 = 0x06697ff4; *//* none/SM501 */
MSC2 = (MSC2 & ~0xffff) | 0x7ff4; /* SM501 */
/* __raw_writel(0x7ffc3ffc, MSC1); *//* LAN9215/EXP_CS */
/* __raw_writel(0x06697ff4, MSC2); *//* none/SM501 */
__raw_writel((__raw_readl(MSC2) & ~0xffff) | 0x7ff4, MSC2); /* SM501 */

pxa_set_ffuart_info(NULL);
pxa_set_btuart_info(NULL);
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-pxa/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <mach/reset.h>
#include <mach/gpio.h>
#include <mach/smemc.h>

#include "generic.h"

Expand Down
9 changes: 5 additions & 4 deletions arch/arm/mach-pxa/h5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <mach/pxa25x.h>
#include <mach/h5000.h>
#include <mach/udc.h>
#include <mach/smemc.h>

#include "generic.h"

Expand Down Expand Up @@ -172,11 +173,11 @@ static unsigned long h5000_pin_config[] __initdata = {

static void fix_msc(void)
{
MSC0 = 0x129c24f2;
MSC1 = 0x7ff424fa;
MSC2 = 0x7ff47ff4;
__raw_writel(0x129c24f2, MSC0);
__raw_writel(0x7ff424fa, MSC1);
__raw_writel(0x7ff47ff4, MSC2);

MDREFR |= 0x02080000;
__raw_writel(__raw_readl(MDREFR) | 0x02080000, MDREFR);
}

/*
Expand Down
55 changes: 0 additions & 55 deletions arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,61 +16,6 @@

#include <mach/hardware.h>

/*
* Memory controller
*/

#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */
#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */
#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */
#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */
#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */
#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */
#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */
#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */
#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */
#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */
#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */
#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */
#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */
#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */
#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */

/*
* More handy macros for PCMCIA
*
* Arg is socket number
*/
#define MCMEM(s) __REG2(0x48000028, (s)<<2 ) /* Card interface Common Memory Space Socket s Timing */
#define MCATT(s) __REG2(0x48000030, (s)<<2 ) /* Card interface Attribute Space Socket s Timing Configuration */
#define MCIO(s) __REG2(0x48000038, (s)<<2 ) /* Card interface I/O Space Socket s Timing Configuration */

/* MECR register defines */
#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */

#define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */
#define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */
#define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */
#define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */

#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */
#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */

/*
* Power Manager
*/
Expand Down
74 changes: 74 additions & 0 deletions arch/arm/mach-pxa/include/mach/smemc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Static memory controller register definitions for PXA CPUs
*
* Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
*
* 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.
*/

#ifndef __SMEMC_REGS_H
#define __SMEMC_REGS_H

#define PXA2XX_SMEMC_BASE 0x48000000
#define PXA3XX_SMEMC_BASE 0x4a000000
#define SMEMC_VIRT 0xf6000000

#define MDCNFG (SMEMC_VIRT + 0x00) /* SDRAM Configuration Register 0 */
#define MDREFR (SMEMC_VIRT + 0x04) /* SDRAM Refresh Control Register */
#define MSC0 (SMEMC_VIRT + 0x08) /* Static Memory Control Register 0 */
#define MSC1 (SMEMC_VIRT + 0x0C) /* Static Memory Control Register 1 */
#define MSC2 (SMEMC_VIRT + 0x10) /* Static Memory Control Register 2 */
#define MECR (SMEMC_VIRT + 0x14) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
#define SXLCR (SMEMC_VIRT + 0x18) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
#define SXCNFG (SMEMC_VIRT + 0x1C) /* Synchronous Static Memory Control Register */
#define SXMRS (SMEMC_VIRT + 0x24) /* MRS value to be written to Synchronous Flash or SMROM */
#define MCMEM0 (SMEMC_VIRT + 0x28) /* Card interface Common Memory Space Socket 0 Timing */
#define MCMEM1 (SMEMC_VIRT + 0x2C) /* Card interface Common Memory Space Socket 1 Timing */
#define MCATT0 (SMEMC_VIRT + 0x30) /* Card interface Attribute Space Socket 0 Timing Configuration */
#define MCATT1 (SMEMC_VIRT + 0x34) /* Card interface Attribute Space Socket 1 Timing Configuration */
#define MCIO0 (SMEMC_VIRT + 0x38) /* Card interface I/O Space Socket 0 Timing Configuration */
#define MCIO1 (SMEMC_VIRT + 0x3C) /* Card interface I/O Space Socket 1 Timing Configuration */
#define MDMRS (SMEMC_VIRT + 0x40) /* MRS value to be written to SDRAM */
#define BOOT_DEF (SMEMC_VIRT + 0x44) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
#define MEMCLKCFG (SMEMC_VIRT + 0x68) /* Clock Configuration */
#define CSADRCFG0 (SMEMC_VIRT + 0x80) /* Address Configuration Register for CS0 */
#define CSADRCFG1 (SMEMC_VIRT + 0x84) /* Address Configuration Register for CS1 */
#define CSADRCFG2 (SMEMC_VIRT + 0x88) /* Address Configuration Register for CS2 */
#define CSADRCFG3 (SMEMC_VIRT + 0x8C) /* Address Configuration Register for CS3 */

/*
* More handy macros for PCMCIA
*
* Arg is socket number
*/
#define MCMEM(s) (SMEMC_VIRT + 0x28 + ((s)<<2)) /* Card interface Common Memory Space Socket s Timing */
#define MCATT(s) (SMEMC_VIRT + 0x30 + ((s)<<2)) /* Card interface Attribute Space Socket s Timing Configuration */
#define MCIO(s) (SMEMC_VIRT + 0x38 + ((s)<<2)) /* Card interface I/O Space Socket s Timing Configuration */

/* MECR register defines */
#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */

#define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */
#define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */
#define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */
#define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */

#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */
#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */

#endif
3 changes: 2 additions & 1 deletion arch/arm/mach-pxa/lpd270.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
#include <mach/smemc.h>

#include "generic.h"
#include "devices.h"
Expand Down Expand Up @@ -463,7 +464,7 @@ static void __init lpd270_init(void)
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);

lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
lpd270_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
lpd270_flash_data[1].width = 4;

/*
Expand Down
3 changes: 2 additions & 1 deletion arch/arm/mach-pxa/lubbock.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/pm.h>
#include <mach/smemc.h>

#include "generic.h"
#include "clock.h"
Expand Down Expand Up @@ -525,7 +526,7 @@ static void __init lubbock_init(void)
pxa_set_ac97_info(NULL);

lubbock_flash_data[0].width = lubbock_flash_data[1].width =
(BOOT_DEF & 1) ? 2 : 4;
(__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
/* Compensate for the nROMBT switch which swaps the flash banks */
printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
flashboot?"Flash":"ROM", flashboot);
Expand Down
3 changes: 2 additions & 1 deletion arch/arm/mach-pxa/mainstone.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <mach/irda.h>
#include <mach/ohci.h>
#include <plat/pxa27x_keypad.h>
#include <mach/smemc.h>

#include "generic.h"
#include "devices.h"
Expand Down Expand Up @@ -565,7 +566,7 @@ static void __init mainstone_init(void)
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);

mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
mst_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
mst_flash_data[1].width = 4;

/* Compensate for SW7 which swaps the flash banks */
Expand Down
5 changes: 3 additions & 2 deletions arch/arm/mach-pxa/pxa25x.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <mach/reset.h>
#include <mach/pm.h>
#include <mach/dma.h>
#include <mach/smemc.h>

#include "generic.h"
#include "devices.h"
Expand Down Expand Up @@ -323,8 +324,8 @@ void __init pxa26x_init_irq(void)

static struct map_desc pxa25x_io_desc[] __initdata = {
{ /* Mem Ctl */
.virtual = 0xf6000000,
.pfn = __phys_to_pfn(0x48000000),
.virtual = SMEMC_VIRT,
.pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE),
.length = 0x00200000,
.type = MT_DEVICE
},
Expand Down
11 changes: 7 additions & 4 deletions arch/arm/mach-pxa/pxa27x.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/suspend.h>
#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/io.h>

#include <asm/mach/map.h>
#include <mach/hardware.h>
Expand All @@ -28,6 +29,8 @@
#include <mach/ohci.h>
#include <mach/pm.h>
#include <mach/dma.h>
#include <mach/smemc.h>

#include <plat/i2c.h>

#include "generic.h"
Expand Down Expand Up @@ -255,7 +258,7 @@ enum {

void pxa27x_cpu_pm_save(unsigned long *sleep_save)
{
SAVE(MDREFR);
sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR);
SAVE(PCFR);

SAVE(CKEN);
Expand All @@ -264,7 +267,7 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save)

void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
{
RESTORE(MDREFR);
__raw_writel(sleep_save[SLEEP_SAVE_MDREFR], MDREFR);
RESTORE(PCFR);

PSSR = PSSR_RDH | PSSR_PH;
Expand Down Expand Up @@ -373,8 +376,8 @@ void __init pxa27x_init_irq(void)

static struct map_desc pxa27x_io_desc[] __initdata = {
{ /* Mem Ctl */
.virtual = 0xf6000000,
.pfn = __phys_to_pfn(0x48000000),
.virtual = SMEMC_VIRT,
.pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE),
.length = 0x00200000,
.type = MT_DEVICE
}, { /* IMem ctl */
Expand Down
5 changes: 3 additions & 2 deletions arch/arm/mach-pxa/pxa3xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <mach/pm.h>
#include <mach/dma.h>
#include <mach/regs-intc.h>
#include <mach/smemc.h>
#include <plat/i2c.h>

#include "generic.h"
Expand Down Expand Up @@ -583,8 +584,8 @@ void __init pxa3xx_init_irq(void)

static struct map_desc pxa3xx_io_desc[] __initdata = {
{ /* Mem Ctl */
.virtual = 0xf6000000,
.pfn = __phys_to_pfn(0x4a000000),
.virtual = SMEMC_VIRT,
.pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE),
.length = 0x00200000,
.type = MT_DEVICE
}
Expand Down
Loading

0 comments on commit ad68bb9

Please sign in to comment.