Skip to content

Commit

Permalink
[ARM] pxa: PXA3xx base support
Browse files Browse the repository at this point in the history
Signed-off-by: eric miao <eric.y.miao@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
eric miao authored and Russell King committed Oct 15, 2007
1 parent 073ac8f commit 2c8086a
Show file tree
Hide file tree
Showing 21 changed files with 2,942 additions and 9 deletions.
6 changes: 3 additions & 3 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,14 @@ config ARCH_PNX4008
This enables support for Philips PNX4008 mobile platform.

config ARCH_PXA
bool "PXA2xx-based"
bool "PXA2xx/PXA3xx-based"
depends on MMU
select ARCH_MTD_XIP
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for Intel's PXA2XX processor line.
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.

config ARCH_RPC
bool "RiscPC"
Expand Down Expand Up @@ -486,7 +486,7 @@ source arch/arm/mm/Kconfig
config IWMMXT
bool "Enable iWMMXt support"
depends on CPU_XSCALE || CPU_XSC3
default y if PXA27x
default y if PXA27x || PXA3xx
help
Enable support for iWMMXt context switching at run time if
running on a CPU that supports it.
Expand Down
29 changes: 28 additions & 1 deletion arch/arm/mach-pxa/Kconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
if ARCH_PXA

menu "Intel PXA2xx Implementations"
menu "Intel PXA2xx/PXA3xx Implementations"

if PXA3xx

menu "Supported PXA3xx Processor Variants"

config CPU_PXA300
bool "PXA300 (codename Monahans-L)"

config CPU_PXA310
bool "PXA310 (codename Monahans-LV)"
select CPU_PXA300

config CPU_PXA320
bool "PXA320 (codename Monahans-P)"

endmenu

endif

choice
prompt "Select target board"
Expand Down Expand Up @@ -41,6 +59,10 @@ config MACH_EM_X270
bool "CompuLab EM-x270 platform"
select PXA27x

config MACH_ZYLONITE
bool "PXA3xx Development Platform"
select PXA3xx

endchoice

if PXA_SHARPSL
Expand Down Expand Up @@ -130,6 +152,11 @@ config PXA27x
help
Select code specific to PXA27x variants

config PXA3xx
bool
help
Select code specific to PXA3xx variants

config PXA_SHARP_C7xx
bool
select PXA_SSP
Expand Down
9 changes: 9 additions & 0 deletions arch/arm/mach-pxa/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
obj-y += clock.o generic.o irq.o dma.o time.o
obj-$(CONFIG_PXA25x) += pxa25x.o
obj-$(CONFIG_PXA27x) += pxa27x.o
obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o
obj-$(CONFIG_CPU_PXA300) += pxa300.o
obj-$(CONFIG_CPU_PXA320) += pxa320.o

# Specific board support
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
Expand All @@ -20,6 +23,12 @@ obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
obj-$(CONFIG_MACH_TOSA) += tosa.o
obj-$(CONFIG_MACH_EM_X270) += em-x270.o

ifeq ($(CONFIG_MACH_ZYLONITE),y)
obj-y += zylonite.o
obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o
obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o
endif

# Support for blinky lights
led-y := leds.o
led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
Expand Down
8 changes: 6 additions & 2 deletions arch/arm/mach-pxa/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ unsigned int get_clk_frequency_khz(int info)
{
if (cpu_is_pxa21x() || cpu_is_pxa25x())
return pxa25x_get_clk_frequency_khz(info);
else
else if (cpu_is_pxa27x())
return pxa27x_get_clk_frequency_khz(info);
else
return pxa3xx_get_clk_frequency_khz(info);
}
EXPORT_SYMBOL(get_clk_frequency_khz);

Expand All @@ -63,8 +65,10 @@ unsigned int get_memclk_frequency_10khz(void)
{
if (cpu_is_pxa21x() || cpu_is_pxa25x())
return pxa25x_get_memclk_frequency_10khz();
else
else if (cpu_is_pxa27x())
return pxa27x_get_memclk_frequency_10khz();
else
return pxa3xx_get_memclk_frequency_10khz();
}
EXPORT_SYMBOL(get_memclk_frequency_10khz);

Expand Down
8 changes: 8 additions & 0 deletions arch/arm/mach-pxa/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ extern void __init pxa_init_irq_gpio(int gpio_nr);
extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
extern void __init pxa25x_init_irq(void);
extern void __init pxa27x_init_irq(void);
extern void __init pxa3xx_init_irq(void);
extern void __init pxa_map_io(void);

extern unsigned int get_clk_frequency_khz(int info);
Expand All @@ -44,3 +45,10 @@ extern unsigned pxa27x_get_memclk_frequency_10khz(void);
#define pxa27x_get_memclk_frequency_10khz() (0)
#endif

#ifdef CONFIG_PXA3xx
extern unsigned pxa3xx_get_clk_frequency_khz(int);
extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
#else
#define pxa3xx_get_clk_frequency_khz(x) (0)
#define pxa3xx_get_memclk_frequency_10khz() (0)
#endif
2 changes: 1 addition & 1 deletion arch/arm/mach-pxa/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void __init pxa_init_irq_low(void)
}
}

#ifdef CONFIG_PXA27x
#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)

/*
* This is for the second set of internal IRQs as found on the PXA27x.
Expand Down
235 changes: 235 additions & 0 deletions arch/arm/mach-pxa/mfp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
/*
* linux/arch/arm/mach-pxa/mfp.c
*
* PXA3xx Multi-Function Pin Support
*
* Copyright (C) 2007 Marvell Internation Ltd.
*
* 2007-08-21: eric miao <eric.y.miao@gmail.com>
* initial version
*
* 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/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>

#include <asm/hardware.h>
#include <asm/arch/mfp.h>

/* mfp_spin_lock is used to ensure that MFP register configuration
* (most likely a read-modify-write operation) is atomic, and that
* mfp_table[] is consistent
*/
static DEFINE_SPINLOCK(mfp_spin_lock);

static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];

#define mfpr_readl(off) \
__raw_readl(mfpr_mmio_base + (off))

#define mfpr_writel(off, val) \
__raw_writel(val, mfpr_mmio_base + (off))

/*
* perform a read-back of any MFPR register to make sure the
* previous writings are finished
*/
#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)

static inline void __mfp_config(int pin, unsigned long val)
{
unsigned long off = mfp_table[pin].mfpr_off;

mfp_table[pin].mfpr_val = val;
mfpr_writel(off, val);
}

void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num)
{
int i, pin;
unsigned long val, flags;
mfp_cfg_t *mfp_cfg = mfp_cfgs;

spin_lock_irqsave(&mfp_spin_lock, flags);

for (i = 0; i < num; i++, mfp_cfg++) {
pin = MFP_CFG_PIN(*mfp_cfg);
val = MFP_CFG_VAL(*mfp_cfg);

BUG_ON(pin >= MFP_PIN_MAX);

__mfp_config(pin, val);
}

mfpr_sync();
spin_unlock_irqrestore(&mfp_spin_lock, flags);
}

unsigned long pxa3xx_mfp_read(int mfp)
{
unsigned long val, flags;

BUG_ON(mfp >= MFP_PIN_MAX);

spin_lock_irqsave(&mfp_spin_lock, flags);
val = mfpr_readl(mfp_table[mfp].mfpr_off);
spin_unlock_irqrestore(&mfp_spin_lock, flags);

return val;
}

void pxa3xx_mfp_write(int mfp, unsigned long val)
{
unsigned long flags;

BUG_ON(mfp >= MFP_PIN_MAX);

spin_lock_irqsave(&mfp_spin_lock, flags);
mfpr_writel(mfp_table[mfp].mfpr_off, val);
mfpr_sync();
spin_unlock_irqrestore(&mfp_spin_lock, flags);
}

void pxa3xx_mfp_set_afds(int mfp, int af, int ds)
{
uint32_t mfpr_off, mfpr_val;
unsigned long flags;

BUG_ON(mfp >= MFP_PIN_MAX);

spin_lock_irqsave(&mfp_spin_lock, flags);
mfpr_off = mfp_table[mfp].mfpr_off;

mfpr_val = mfpr_readl(mfpr_off);
mfpr_val &= ~(MFPR_AF_MASK | MFPR_DRV_MASK);
mfpr_val |= (((af & 0x7) << MFPR_ALT_OFFSET) |
((ds & 0x7) << MFPR_DRV_OFFSET));

mfpr_writel(mfpr_off, mfpr_val);
mfpr_sync();

spin_unlock_irqrestore(&mfp_spin_lock, flags);
}

void pxa3xx_mfp_set_rdh(int mfp, int rdh)
{
uint32_t mfpr_off, mfpr_val;
unsigned long flags;

BUG_ON(mfp >= MFP_PIN_MAX);

spin_lock_irqsave(&mfp_spin_lock, flags);

mfpr_off = mfp_table[mfp].mfpr_off;

mfpr_val = mfpr_readl(mfpr_off);
mfpr_val &= ~MFPR_RDH_MASK;

if (likely(rdh))
mfpr_val |= (1u << MFPR_SS_OFFSET);

mfpr_writel(mfpr_off, mfpr_val);
mfpr_sync();

spin_unlock_irqrestore(&mfp_spin_lock, flags);
}

void pxa3xx_mfp_set_lpm(int mfp, int lpm)
{
uint32_t mfpr_off, mfpr_val;
unsigned long flags;

BUG_ON(mfp >= MFP_PIN_MAX);

spin_lock_irqsave(&mfp_spin_lock, flags);

mfpr_off = mfp_table[mfp].mfpr_off;
mfpr_val = mfpr_readl(mfpr_off);
mfpr_val &= ~MFPR_LPM_MASK;

if (lpm & 0x1) mfpr_val |= 1u << MFPR_SON_OFFSET;
if (lpm & 0x2) mfpr_val |= 1u << MFPR_SD_OFFSET;
if (lpm & 0x4) mfpr_val |= 1u << MFPR_PU_OFFSET;
if (lpm & 0x8) mfpr_val |= 1u << MFPR_PD_OFFSET;
if (lpm &0x10) mfpr_val |= 1u << MFPR_PS_OFFSET;

mfpr_writel(mfpr_off, mfpr_val);
mfpr_sync();

spin_unlock_irqrestore(&mfp_spin_lock, flags);
}

void pxa3xx_mfp_set_pull(int mfp, int pull)
{
uint32_t mfpr_off, mfpr_val;
unsigned long flags;

BUG_ON(mfp >= MFP_PIN_MAX);

spin_lock_irqsave(&mfp_spin_lock, flags);

mfpr_off = mfp_table[mfp].mfpr_off;
mfpr_val = mfpr_readl(mfpr_off);
mfpr_val &= ~MFPR_PULL_MASK;
mfpr_val |= ((pull & 0x7u) << MFPR_PD_OFFSET);

mfpr_writel(mfpr_off, mfpr_val);
mfpr_sync();

spin_unlock_irqrestore(&mfp_spin_lock, flags);
}

void pxa3xx_mfp_set_edge(int mfp, int edge)
{
uint32_t mfpr_off, mfpr_val;
unsigned long flags;

BUG_ON(mfp >= MFP_PIN_MAX);

spin_lock_irqsave(&mfp_spin_lock, flags);

mfpr_off = mfp_table[mfp].mfpr_off;
mfpr_val = mfpr_readl(mfpr_off);

mfpr_val &= ~MFPR_EDGE_MASK;
mfpr_val |= (edge & 0x3u) << MFPR_ERE_OFFSET;
mfpr_val |= (!edge & 0x1) << MFPR_EC_OFFSET;

mfpr_writel(mfpr_off, mfpr_val);
mfpr_sync();

spin_unlock_irqrestore(&mfp_spin_lock, flags);
}

void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
{
struct pxa3xx_mfp_addr_map *p;
unsigned long offset, flags;
int i;

spin_lock_irqsave(&mfp_spin_lock, flags);

for (p = map; p->start != MFP_PIN_INVALID; p++) {
offset = p->offset;
i = p->start;

do {
mfp_table[i].mfpr_off = offset;
mfp_table[i].mfpr_val = 0;
offset += 4; i++;
} while ((i <= p->end) && (p->end != -1));
}

spin_unlock_irqrestore(&mfp_spin_lock, flags);
}

void __init pxa3xx_init_mfp(void)
{
memset(mfp_table, 0, sizeof(mfp_table));
}
Loading

0 comments on commit 2c8086a

Please sign in to comment.