[ARM] pxa: add base support for Marvell's PXA168 processor line

"""The Marvell® PXA168 processor is the first in a family of application
processors targeted at mass market opportunities in computing and consumer
devices. It balances high computing and multimedia performance with low
power consumption to support extended battery life, and includes a wealth
of integrated peripherals to reduce overall BOM cost .... """

See http://www.marvell.com/featured/pxa168.jsp for more information.

  1. Marvell Mohawk core is a hybrid of xscale3 and its own ARM core,
     there are many enhancements like instructions for flushing the
     whole D-cache, and so on

  2. Clock reuses Russell's common clkdev, and added the basic support
     for UART1/2.

  3. Devices are a bit different from the 'mach-pxa' way, the platform
     devices are now dynamically allocated only when necessary (i.e.
     when pxa_register_device() is called). Description for each device
     are stored in an array of 'struct pxa_device_desc'. Now that:

     a. this array of device description is marked with __initdata and
        can be freed up system is fully up

     b. which means board code has to add all needed devices early in
        his initializing function

     c. platform specific data can now be marked as __initdata since
        they are allocated and copied by platform_device_add_data()

  4. only the basic UART1/2/3 are added, more devices will come later.

Signed-off-by: Jason Chagas <chagas@marvell.com>
Signed-off-by: Eric Miao <eric.miao@marvell.com>
This commit is contained in:
Eric Miao
2009-01-20 14:15:18 +08:00
parent f8dec04d33
commit 49cbe78637
40 changed files with 1669 additions and 2 deletions

View File

@@ -478,6 +478,8 @@ config ARCH_PXA
select HAVE_CLK
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select COMMON_CLKDEV
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
@@ -485,6 +487,18 @@ config ARCH_PXA
help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
config ARCH_MMP
bool "Marvell PXA168"
depends on MMU
select HAVE_CLK
select COMMON_CLKDEV
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
select PLAT_PXA
help
Support for Marvell's PXA168 processor line.
config ARCH_RPC
bool "RiscPC"
select ARCH_ACORN
@@ -621,6 +635,8 @@ source "arch/arm/mach-mv78xx0/Kconfig"
source "arch/arm/mach-pxa/Kconfig"
source "arch/arm/plat-pxa/Kconfig"
source "arch/arm/mach-mmp/Kconfig"
source "arch/arm/mach-sa1100/Kconfig"
source "arch/arm/plat-omap/Kconfig"

View File

@@ -109,6 +109,7 @@ ifeq ($(CONFIG_ARCH_SA1100),y)
textofs-$(CONFIG_SA1111) := 0x00208000
endif
machine-$(CONFIG_ARCH_PXA) := pxa
machine-$(CONFIG_ARCH_MMP) := mmp
plat-$(CONFIG_PLAT_PXA) := pxa
machine-$(CONFIG_ARCH_L7200) := l7200
machine-$(CONFIG_ARCH_INTEGRATOR) := integrator

View File

@@ -636,6 +636,18 @@ proc_types:
b __armv4_mmu_cache_off
b __armv4_mmu_cache_flush
.word 0x56158000 @ PXA168
.word 0xfffff000
b __armv4_mmu_cache_on
b __armv4_mmu_cache_off
b __armv5tej_mmu_cache_flush
.word 0x56056930
.word 0xff0ffff0 @ PXA935
b __armv4_mmu_cache_on
b __armv4_mmu_cache_off
b __armv4_mmu_cache_flush
.word 0x56050000 @ Feroceon
.word 0xff0f0000
b __armv4_mmu_cache_on

View File

@@ -94,6 +94,14 @@
# endif
#endif
#if defined(CONFIG_CPU_MOHAWK)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE mohawk
# endif
#endif
#if defined(CONFIG_CPU_FEROCEON)
# define MULTI_CACHE 1
#endif

View File

@@ -185,6 +185,14 @@
# define CPU_NAME cpu_xsc3
# endif
# endif
# ifdef CONFIG_CPU_MOHAWK
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_mohawk
# endif
# endif
# ifdef CONFIG_CPU_FEROCEON
# ifdef CPU_NAME
# undef MULTI_CPU

27
arch/arm/mach-mmp/Kconfig Normal file
View File

@@ -0,0 +1,27 @@
if ARCH_MMP
menu "Marvell PXA168 Implmentations"
config MACH_ASPENITE
bool "Marvell's PXA168 Aspenite Development Board"
select CPU_PXA168
help
Say 'Y' here if you want to support the Marvell PXA168-based
Aspenite Development Board.
config MACH_ZYLONITE2
bool "Marvell's PXA168 Zylonite2 Development Board"
select CPU_PXA168
help
Say 'Y' here if you want to support the Marvell PXA168-based
Zylonite2 Development Board.
endmenu
config CPU_PXA168
bool
select CPU_MOHAWK
help
Select code specific to PXA168
endif

View File

@@ -0,0 +1,12 @@
#
# Makefile for Marvell's PXA168 processors line
#
obj-y += common.o clock.o devices.o irq.o time.o
# SoC support
obj-$(CONFIG_CPU_PXA168) += pxa168.o
# board support
obj-$(CONFIG_MACH_ASPENITE) += aspenite.o
obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o

View File

@@ -0,0 +1 @@
zreladdr-y := 0x00008000

View File

@@ -0,0 +1,42 @@
/*
* linux/arch/arm/mach-mmp/aspenite.c
*
* Support for the Marvell PXA168-based Aspenite and Zylonite2
* Development Platform.
*
* 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
* publishhed by the Free Software Foundation.
*/
#include <linux/init.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/addr-map.h>
#include "common.h"
static void __init common_init(void)
{
}
MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
.phys_io = APB_PHYS_BASE,
.boot_params = 0x00000100,
.io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa168_init_irq,
.timer = &pxa168_timer,
.init_machine = common_init,
MACHINE_END
MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
.phys_io = APB_PHYS_BASE,
.boot_params = 0x00000100,
.io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa168_init_irq,
.timer = &pxa168_timer,
.init_machine = common_init,
MACHINE_END

83
arch/arm/mach-mmp/clock.c Normal file
View File

@@ -0,0 +1,83 @@
/*
* linux/arch/arm/mach-mmp/clock.c
*
* 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/list.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <mach/regs-apbc.h>
#include "clock.h"
static void apbc_clk_enable(struct clk *clk)
{
uint32_t clk_rst;
clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
__raw_writel(clk_rst, clk->clk_rst);
}
static void apbc_clk_disable(struct clk *clk)
{
__raw_writel(0, clk->clk_rst);
}
struct clkops apbc_clk_ops = {
.enable = apbc_clk_enable,
.disable = apbc_clk_disable,
};
static DEFINE_SPINLOCK(clocks_lock);
int clk_enable(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clocks_lock, flags);
if (clk->enabled++ == 0)
clk->ops->enable(clk);
spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
unsigned long flags;
WARN_ON(clk->enabled == 0);
spin_lock_irqsave(&clocks_lock, flags);
if (--clk->enabled == 0)
clk->ops->disable(clk);
spin_unlock_irqrestore(&clocks_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
unsigned long rate;
if (clk->ops->getrate)
rate = clk->ops->getrate(clk);
else
rate = clk->rate;
return rate;
}
EXPORT_SYMBOL(clk_get_rate);
void clks_register(struct clk_lookup *clks, size_t num)
{
int i;
for (i = 0; i < num; i++)
clkdev_add(&clks[i]);
}

71
arch/arm/mach-mmp/clock.h Normal file
View File

@@ -0,0 +1,71 @@
/*
* linux/arch/arm/mach-mmp/clock.h
*
* 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 <asm/clkdev.h>
struct clkops {
void (*enable)(struct clk *);
void (*disable)(struct clk *);
unsigned long (*getrate)(struct clk *);
};
struct clk {
const struct clkops *ops;
void __iomem *clk_rst; /* clock reset control register */
int fnclksel; /* functional clock select (APBC) */
uint32_t enable_val; /* value for clock enable (APMU) */
unsigned long rate;
int enabled;
};
extern struct clkops apbc_clk_ops;
#define APBC_CLK(_name, _reg, _fnclksel, _rate) \
struct clk clk_##_name = { \
.clk_rst = (void __iomem *)APBC_##_reg, \
.fnclksel = _fnclksel, \
.rate = _rate, \
.ops = &apbc_clk_ops, \
}
#define APBC_CLK_OPS(_name, _reg, _fnclksel, _rate, _ops) \
struct clk clk_##_name = { \
.clk_rst = (void __iomem *)APBC_##_reg, \
.fnclksel = _fnclksel, \
.rate = _rate, \
.ops = _ops, \
}
#define APMU_CLK(_name, _reg, _eval, _rate) \
struct clk clk_##_name = { \
.clk_rst = (void __iomem *)APMU_##_reg, \
.enable_val = _eval, \
.rate = _rate, \
.ops = &apmu_clk_ops, \
}
#define APMU_CLK_OPS(_name, _reg, _eval, _rate, _ops) \
struct clk clk_##_name = { \
.clk_rst = (void __iomem *)APMU_##_reg, \
.enable_val = _eval, \
.rate = _rate, \
.ops = _ops, \
}
#define INIT_CLKREG(_clk, _devname, _conname) \
{ \
.clk = _clk, \
.dev_id = _devname, \
.con_id = _conname, \
}
extern struct clk clk_pxa168_gpio;
extern struct clk clk_pxa168_timers;
extern void clks_register(struct clk_lookup *, size_t);

View File

@@ -0,0 +1,37 @@
/*
* linux/arch/arm/mach-mmp/common.c
*
* Code common to PXA168 processor lines
*
* 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/init.h>
#include <linux/kernel.h>
#include <asm/page.h>
#include <asm/mach/map.h>
#include <mach/addr-map.h>
#include "common.h"
static struct map_desc standard_io_desc[] __initdata = {
{
.pfn = __phys_to_pfn(APB_PHYS_BASE),
.virtual = APB_VIRT_BASE,
.length = APB_PHYS_SIZE,
.type = MT_DEVICE,
}, {
.pfn = __phys_to_pfn(AXI_PHYS_BASE),
.virtual = AXI_VIRT_BASE,
.length = AXI_PHYS_SIZE,
.type = MT_DEVICE,
},
};
void __init pxa_map_io(void)
{
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
}

View File

@@ -0,0 +1,11 @@
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
struct sys_timer;
extern void timer_init(int irq);
extern struct sys_timer pxa168_timer;
extern void __init pxa168_init_irq(void);
extern void __init icu_init_irq(void);
extern void __init pxa_map_io(void);

View File

@@ -0,0 +1,69 @@
/*
* linux/arch/arm/mach-mmp/devices.c
*
* 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/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/irq.h>
#include <mach/devices.h>
int __init pxa_register_device(struct pxa_device_desc *desc,
void *data, size_t size)
{
struct platform_device *pdev;
struct resource res[2 + MAX_RESOURCE_DMA];
int i, ret = 0, nres = 0;
pdev = platform_device_alloc(desc->drv_name, desc->id);
if (pdev == NULL)
return -ENOMEM;
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
memset(res, 0, sizeof(res));
if (desc->start != -1ul && desc->size > 0) {
res[nres].start = desc->start;
res[nres].end = desc->start + desc->size - 1;
res[nres].flags = IORESOURCE_MEM;
nres++;
}
if (desc->irq != NO_IRQ) {
res[nres].start = desc->irq;
res[nres].end = desc->irq;
res[nres].flags = IORESOURCE_IRQ;
nres++;
}
for (i = 0; i < MAX_RESOURCE_DMA; i++, nres++) {
if (desc->dma[i] == 0)
break;
res[nres].start = desc->dma[i];
res[nres].end = desc->dma[i];
res[nres].flags = IORESOURCE_DMA;
}
ret = platform_device_add_resources(pdev, res, nres);
if (ret) {
platform_device_put(pdev);
return ret;
}
if (data && size) {
ret = platform_device_add_data(pdev, data, size);
if (ret) {
platform_device_put(pdev);
return ret;
}
}
return platform_device_add(pdev);
}

View File

@@ -0,0 +1,34 @@
/*
* linux/arch/arm/mach-mmp/include/mach/addr-map.h
*
* Common address map definitions
*
* 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 __ASM_MACH_ADDR_MAP_H
#define __ASM_MACH_ADDR_MAP_H
/* APB - Application Subsystem Peripheral Bus
*
* NOTE: the DMA controller registers are actually on the AXI fabric #1
* slave port to AHB/APB bridge, due to its close relationship to those
* peripherals on APB, let's count it into the ABP mapping area.
*/
#define APB_PHYS_BASE 0xd4000000
#define APB_VIRT_BASE 0xfe000000
#define APB_PHYS_SIZE 0x00200000
#define AXI_PHYS_BASE 0xd4200000
#define AXI_VIRT_BASE 0xfe200000
#define AXI_PHYS_SIZE 0x00200000
/* Static Memory Controller - Chip Select 0 and 1 */
#define SMC_CS0_PHYS_BASE 0x80000000
#define SMC_CS0_PHYS_SIZE 0x10000000
#define SMC_CS1_PHYS_BASE 0x90000000
#define SMC_CS1_PHYS_SIZE 0x10000000
#endif /* __ASM_MACH_ADDR_MAP_H */

View File

@@ -0,0 +1,7 @@
#ifndef __ASM_MACH_CLKDEV_H
#define __ASM_MACH_CLKDEV_H
#define __clk_get(clk) ({ 1; })
#define __clk_put(clk) do { } while (0)
#endif /* __ASM_MACH_CLKDEV_H */

View File

@@ -0,0 +1,21 @@
#ifndef __ASM_MACH_CPUTYPE_H
#define __ASM_MACH_CPUTYPE_H
#include <asm/cputype.h>
/*
* CPU Stepping OLD_ID CPU_ID CHIP_ID
*
* PXA168 A0 0x41159263 0x56158400 0x00A0A333
*/
#ifdef CONFIG_CPU_PXA168
# define __cpu_is_pxa168(id) \
({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x84; })
#else
# define __cpu_is_pxa168(id) (0)
#endif
#define cpu_is_pxa168() ({ __cpu_is_pxa168(read_cpuid_id()); })
#endif /* __ASM_MACH_CPUTYPE_H */

View File

@@ -0,0 +1,23 @@
/* arch/arm/mach-mmp/include/mach/debug-macro.S
*
* Debugging macro include header
*
* Copied from arch/arm/mach-pxa/include/mach/debug.S
*
* 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 <mach/addr-map.h>
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
ldreq \rx, =APB_PHYS_BASE @ physical
ldrne \rx, =APB_VIRT_BASE @ virtual
orr \rx, \rx, #0x00017000
.endm
#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>

View File

@@ -0,0 +1,27 @@
#include <linux/types.h>
#define MAX_RESOURCE_DMA 2
/* structure for describing the on-chip devices */
struct pxa_device_desc {
const char *dev_name;
const char *drv_name;
int id;
int irq;
unsigned long start;
unsigned long size;
int dma[MAX_RESOURCE_DMA];
};
#define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \
struct pxa_device_desc pxa168_device_##_name __initdata = { \
.dev_name = "pxa168-" #_name, \
.drv_name = _drv, \
.id = _id, \
.irq = IRQ_PXA168_##_irq, \
.start = _start, \
.size = _size, \
.dma = { _dma }, \
};
extern int pxa_register_device(struct pxa_device_desc *, void *, size_t);

View File

@@ -0,0 +1,13 @@
/*
* linux/arch/arm/mach-mmp/include/mach/dma.h
*/
#ifndef __ASM_MACH_DMA_H
#define __ASM_MACH_DMA_H
#include <mach/addr-map.h>
#define DMAC_REGS_VIRT (APB_VIRT_BASE + 0x00000)
#include <plat/dma.h>
#endif /* __ASM_MACH_DMA_H */

Some files were not shown because too many files have changed in this diff Show More