Merge with /home/stefan/git/u-boot/denx

This commit is contained in:
Stefan Roese
2006-11-10 07:48:47 +01:00
562 changed files with 27997 additions and 2273 deletions

View File

@@ -39,7 +39,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -33,7 +33,7 @@ OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -34,7 +34,7 @@ OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -34,7 +34,7 @@ OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -25,40 +25,6 @@
#include <command.h>
#include <arm925t.h>
ushort gpioreserved;
void gpioreserve(ushort mask)
{
gpioreserved |= mask;
}
void gpiosetdir(ushort mask, ushort in)
{
*(ushort *)GPIO_DIR_CONTROL_REG = (*(ushort *)GPIO_DIR_CONTROL_REG & ~mask) | (in & mask);
}
void gpiosetout(ushort mask, ushort out)
{
ushort *r_ptr, r_val;
r_ptr = (ushort *)GPIO_DATA_OUTPUT_REG; /* set pointer */
r_val = *r_ptr & ~mask; /* get previous val, clear bits we want to change */
r_val |= (out & mask); /* set specified bits in value + plus origional ones */
*r_ptr = r_val; /* write it out */
/*
* gcc screwed this one up :(.
*
* *(ushort *)GPIO_DATA_OUTPUT_REG = (*(ushort *)GPIO_DATA_OUTPUT_REG & ~mask) | (out & mask);
*/
}
void gpioinit(void)
{
}
#define MIF_CONFIG_REG 0xFFFECC0C
#define FLASH_GLOBAL_CTRL_NWP 1

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

50
cpu/at32ap/Makefile Normal file
View File

@@ -0,0 +1,50 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# Copyright (C) 2005-2006 Atmel Corporation.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB := $(obj)lib$(CPU).a
START := start.o
SOBJS := entry.o
COBJS := cpu.o hsdramc.o exception.o cache.o
COBJS += interrupts.o device.o pm.o pio.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $@ $^
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View File

@@ -0,0 +1,43 @@
#
# Copyright (C) 2005-2006 Atmel Corporation
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB := $(obj)lib$(SOC).a
COBJS := hebi.o devices.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $@ $^
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View File

@@ -0,0 +1,448 @@
/*
* Copyright (C) 2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/memory-map.h>
#include <asm/arch/platform.h>
#include "../sm.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
const struct clock_domain chip_clock[] = {
[CLOCK_CPU] = {
.reg = SM_PM_CPU_MASK,
.id = CLOCK_CPU,
.bridge = NO_DEVICE,
},
[CLOCK_HSB] = {
.reg = SM_PM_HSB_MASK,
.id = CLOCK_HSB,
.bridge = NO_DEVICE,
},
[CLOCK_PBA] = {
.reg = SM_PM_PBA_MASK,
.id = CLOCK_PBA,
.bridge = DEVICE_PBA_BRIDGE,
},
[CLOCK_PBB] = {
.reg = SM_PM_PBB_MASK,
.id = CLOCK_PBB,
.bridge = DEVICE_PBB_BRIDGE,
},
};
static const struct resource hebi_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_HSB, 0 },
},
}, {
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBB, 13 },
},
}, {
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBB, 14 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 27, DEVICE_PIOE, GPIO_FUNC_A, 0 },
},
},
};
static const struct resource pba_bridge_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_HSB, 1 },
}
}, {
.type = RESOURCE_CLOCK,
.u = {
/* HSB-HSB Bridge */
.clock = { CLOCK_HSB, 4 },
},
},
};
static const struct resource pbb_bridge_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_HSB, 2 },
},
},
};
static const struct resource hramc_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_HSB, 3 },
},
},
};
static const struct resource pioa_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 10 },
},
},
};
static const struct resource piob_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 11 },
},
},
};
static const struct resource pioc_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 12 },
},
},
};
static const struct resource piod_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 13 },
},
},
};
static const struct resource pioe_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 14 },
},
},
};
static const struct resource sm_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBB, 0 },
},
},
};
static const struct resource intc_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBB, 1 },
},
},
};
static const struct resource hmatrix_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBB, 2 },
},
},
};
#if defined(CFG_HPDC)
static const struct resource hpdc_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 16 },
},
},
};
#endif
#if defined(CFG_MACB0)
static const struct resource macb0_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_HSB, 8 },
},
}, {
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBB, 6 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 19, DEVICE_PIOC, GPIO_FUNC_A, 0 },
},
},
};
#endif
#if defined(CFG_MACB1)
static const struct resource macb1_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_HSB, 9 },
},
}, {
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBB, 7 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 12, DEVICE_PIOC, GPIO_FUNC_B, 19 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 14, DEVICE_PIOD, GPIO_FUNC_B, 2 },
},
},
};
#endif
#if defined(CFG_LCDC)
static const struct resource lcdc_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_HSB, 7 },
},
},
};
#endif
#if defined(CFG_USART0)
static const struct resource usart0_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 3 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 2, DEVICE_PIOA, GPIO_FUNC_B, 8 },
},
},
};
#endif
#if defined(CFG_USART1)
static const struct resource usart1_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 4 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 2, DEVICE_PIOA, GPIO_FUNC_A, 17 },
},
},
};
#endif
#if defined(CFG_USART2)
static const struct resource usart2_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 5 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 26 },
},
},
};
#endif
#if defined(CFG_USART3)
static const struct resource usart3_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBA, 6 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 17 },
},
},
};
#endif
#if defined(CFG_MMCI)
static const struct resource mmci_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_PBB, 9 },
},
}, {
.type = RESOURCE_GPIO,
.u = {
.gpio = { 6, DEVICE_PIOA, GPIO_FUNC_A, 10 },
},
},
};
#endif
#if defined(CFG_DMAC)
static const struct resource dmac_resource[] = {
{
.type = RESOURCE_CLOCK,
.u = {
.clock = { CLOCK_HSB, 10 },
},
},
};
#endif
const struct device chip_device[] = {
[DEVICE_HEBI] = {
.regs = (void *)HSMC_BASE,
.nr_resources = ARRAY_SIZE(hebi_resource),
.resource = hebi_resource,
},
[DEVICE_PBA_BRIDGE] = {
.nr_resources = ARRAY_SIZE(pba_bridge_resource),
.resource = pba_bridge_resource,
},
[DEVICE_PBB_BRIDGE] = {
.nr_resources = ARRAY_SIZE(pbb_bridge_resource),
.resource = pbb_bridge_resource,
},
[DEVICE_HRAMC] = {
.nr_resources = ARRAY_SIZE(hramc_resource),
.resource = hramc_resource,
},
[DEVICE_PIOA] = {
.regs = (void *)PIOA_BASE,
.nr_resources = ARRAY_SIZE(pioa_resource),
.resource = pioa_resource,
},
[DEVICE_PIOB] = {
.regs = (void *)PIOB_BASE,
.nr_resources = ARRAY_SIZE(piob_resource),
.resource = piob_resource,
},
[DEVICE_PIOC] = {
.regs = (void *)PIOC_BASE,
.nr_resources = ARRAY_SIZE(pioc_resource),
.resource = pioc_resource,
},
[DEVICE_PIOD] = {
.regs = (void *)PIOD_BASE,
.nr_resources = ARRAY_SIZE(piod_resource),
.resource = piod_resource,
},
[DEVICE_PIOE] = {
.regs = (void *)PIOE_BASE,
.nr_resources = ARRAY_SIZE(pioe_resource),
.resource = pioe_resource,
},
[DEVICE_SM] = {
.regs = (void *)SM_BASE,
.nr_resources = ARRAY_SIZE(sm_resource),
.resource = sm_resource,
},
[DEVICE_INTC] = {
.regs = (void *)INTC_BASE,
.nr_resources = ARRAY_SIZE(intc_resource),
.resource = intc_resource,
},
[DEVICE_HMATRIX] = {
.regs = (void *)HMATRIX_BASE,
.nr_resources = ARRAY_SIZE(hmatrix_resource),
.resource = hmatrix_resource,
},
#if defined(CFG_HPDC)
[DEVICE_HPDC] = {
.nr_resources = ARRAY_SIZE(hpdc_resource),
.resource = hpdc_resource,
},
#endif
#if defined(CFG_MACB0)
[DEVICE_MACB0] = {
.regs = (void *)MACB0_BASE,
.nr_resources = ARRAY_SIZE(macb0_resource),
.resource = macb0_resource,
},
#endif
#if defined(CFG_MACB1)
[DEVICE_MACB1] = {
.regs = (void *)MACB1_BASE,
.nr_resources = ARRAY_SIZE(macb1_resource),
.resource = macb1_resource,
},
#endif
#if defined(CFG_LCDC)
[DEVICE_LCDC] = {
.nr_resources = ARRAY_SIZE(lcdc_resource),
.resource = lcdc_resource,
},
#endif
#if defined(CFG_USART0)
[DEVICE_USART0] = {
.regs = (void *)USART0_BASE,
.nr_resources = ARRAY_SIZE(usart0_resource),
.resource = usart0_resource,
},
#endif
#if defined(CFG_USART1)
[DEVICE_USART1] = {
.regs = (void *)USART1_BASE,
.nr_resources = ARRAY_SIZE(usart1_resource),
.resource = usart1_resource,
},
#endif
#if defined(CFG_USART2)
[DEVICE_USART2] = {
.regs = (void *)USART2_BASE,
.nr_resources = ARRAY_SIZE(usart2_resource),
.resource = usart2_resource,
},
#endif
#if defined(CFG_USART3)
[DEVICE_USART3] = {
.regs = (void *)USART3_BASE,
.nr_resources = ARRAY_SIZE(usart3_resource),
.resource = usart3_resource,
},
#endif
#if defined(CFG_MMCI)
[DEVICE_MMCI] = {
.regs = (void *)MMCI_BASE,
.nr_resources = ARRAY_SIZE(mmci_resource),
.resource = mmci_resource,
},
#endif
#if defined(CFG_DMAC)
[DEVICE_DMAC] = {
.regs = (void *)DMAC_BASE,
.nr_resources = ARRAY_SIZE(dmac_resource),
.resource = dmac_resource,
},
#endif
};

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/hmatrix2.h>
#include <asm/arch/memory-map.h>
#include <asm/arch/platform.h>
void cpu_enable_sdram(void)
{
const struct device *hmatrix;
hmatrix = get_device(DEVICE_HMATRIX);
/* Set the SDRAM_ENABLE bit in the HEBI SFR */
hmatrix2_writel(hmatrix, SFR4, 1 << 1);
}

97
cpu/at32ap/cache.c Normal file
View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2004-2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/cacheflush.h>
void dcache_clean_range(volatile void *start, size_t size)
{
unsigned long v, begin, end, linesz;
linesz = CFG_DCACHE_LINESZ;
/* You asked for it, you got it */
begin = (unsigned long)start & ~(linesz - 1);
end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
for (v = begin; v < end; v += linesz)
dcache_clean_line((void *)v);
sync_write_buffer();
}
void dcache_invalidate_range(volatile void *start, size_t size)
{
unsigned long v, begin, end, linesz;
linesz = CFG_DCACHE_LINESZ;
/* You asked for it, you got it */
begin = (unsigned long)start & ~(linesz - 1);
end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
for (v = begin; v < end; v += linesz)
dcache_invalidate_line((void *)v);
}
void dcache_flush_range(volatile void *start, size_t size)
{
unsigned long v, begin, end, linesz;
linesz = CFG_DCACHE_LINESZ;
/* You asked for it, you got it */
begin = (unsigned long)start & ~(linesz - 1);
end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
for (v = begin; v < end; v += linesz)
dcache_flush_line((void *)v);
sync_write_buffer();
}
void icache_invalidate_range(volatile void *start, size_t size)
{
unsigned long v, begin, end, linesz;
linesz = CFG_ICACHE_LINESZ;
/* You asked for it, you got it */
begin = (unsigned long)start & ~(linesz - 1);
end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
for (v = begin; v < end; v += linesz)
icache_invalidate_line((void *)v);
}
/*
* This is called after loading something into memory. We need to
* make sure that everything that was loaded is actually written to
* RAM, and that the icache will look for it. Cleaning the dcache and
* invalidating the icache will do the trick.
*/
void flush_cache (unsigned long start_addr, unsigned long size)
{
dcache_clean_range((void *)start_addr, size);
icache_invalidate_range((void *)start_addr, size);
}

22
cpu/at32ap/config.mk Normal file
View File

@@ -0,0 +1,22 @@
#
# Copyright (C) 2005-2006 Atmel Corporation
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -mcpu=ap7000

83
cpu/at32ap/cpu.c Normal file
View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2005-2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <asm/io.h>
#include <asm/sections.h>
#include <asm/sysreg.h>
#include <asm/arch/memory-map.h>
#include <asm/arch/platform.h>
#include "hsmc3.h"
DECLARE_GLOBAL_DATA_PTR;
int cpu_init(void)
{
const struct device *hebi;
extern void _evba(void);
char *p;
gd->cpu_hz = CFG_OSC0_HZ;
/* fff03400: 00010001 04030402 00050005 10011103 */
hebi = get_device(DEVICE_HEBI);
hsmc3_writel(hebi, MODE0, 0x00031103);
hsmc3_writel(hebi, CYCLE0, 0x000c000d);
hsmc3_writel(hebi, PULSE0, 0x0b0a0906);
hsmc3_writel(hebi, SETUP0, 0x00010002);
pm_init();
sysreg_write(EVBA, (unsigned long)&_evba);
asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET));
gd->console_uart = get_device(CFG_CONSOLE_UART_DEV);
/* Lock everything that mess with the flash in the icache */
for (p = __flashprog_start; p <= (__flashprog_end + CFG_ICACHE_LINESZ);
p += CFG_ICACHE_LINESZ)
asm volatile("cache %0, 0x02" : "=m"(*p) :: "memory");
return 0;
}
void prepare_to_boot(void)
{
/* Flush both caches and the write buffer */
asm volatile("cache %0[4], 010\n\t"
"cache %0[0], 000\n\t"
"sync 0" : : "r"(0) : "memory");
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
/* This will reset the CPU core, caches, MMU and all internal busses */
__builtin_mtdr(8, 1 << 13); /* set DC:DBE */
__builtin_mtdr(8, 1 << 30); /* set DC:RES */
/* Flush the pipeline before we declare it a failure */
asm volatile("sub pc, pc, -4");
return -1;
}

126
cpu/at32ap/device.c Normal file
View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/platform.h>
#include "sm.h"
struct device_state {
int refcount;
};
static struct device_state device_state[NR_DEVICES];
static int claim_resource(const struct resource *res)
{
int ret = 0;
switch (res->type) {
case RESOURCE_GPIO:
ret = gpio_set_func(res->u.gpio.gpio_dev,
res->u.gpio.start,
res->u.gpio.nr_pins,
res->u.gpio.func);
break;
case RESOURCE_CLOCK:
ret = pm_enable_clock(res->u.clock.id, res->u.clock.index);
break;
}
return ret;
}
static void free_resource(const struct resource *res)
{
switch (res->type) {
case RESOURCE_GPIO:
gpio_free(res->u.gpio.gpio_dev, res->u.gpio.start,
res->u.gpio.nr_pins);
break;
case RESOURCE_CLOCK:
pm_disable_clock(res->u.clock.id, res->u.clock.index);
break;
}
}
static int init_dev(const struct device *dev)
{
unsigned int i;
int ret = 0;
for (i = 0; i < dev->nr_resources; i++) {
ret = claim_resource(&dev->resource[i]);
if (ret)
goto cleanup;
}
return 0;
cleanup:
while (i--)
free_resource(&dev->resource[i]);
return ret;
}
const struct device *get_device(enum device_id devid)
{
struct device_state *devstate;
const struct device *dev;
unsigned long flags;
int initialized = 0;
int ret = 0;
devstate = &device_state[devid];
dev = &chip_device[devid];
flags = disable_interrupts();
if (devstate->refcount++)
initialized = 1;
if (flags)
enable_interrupts();
if (!initialized)
ret = init_dev(dev);
return ret ? NULL : dev;
}
void put_device(const struct device *dev)
{
struct device_state *devstate;
unsigned long devid, flags;
devid = (unsigned long)(dev - chip_device) / sizeof(struct device);
devstate = &device_state[devid];
flags = disable_interrupts();
devstate--;
if (!devstate) {
unsigned int i;
for (i = 0; i < dev->nr_resources; i++)
free_resource(&dev->resource[i]);
}
if (flags)
enable_interrupts();
}

65
cpu/at32ap/entry.S Normal file
View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2004-2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <asm/sysreg.h>
#include <asm/ptrace.h>
.section .text.exception,"ax"
.global _evba
.type _evba,@function
.align 10
_evba:
.irp x,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
.align 2
rjmp unknown_exception
.endr
.global timer_interrupt_handler
.type timer_interrupt_handler,@function
.align 2
timer_interrupt_handler:
/*
* Increment timer_overflow and re-write COMPARE with 0xffffffff.
*
* We're running at interrupt level 3, so we don't need to save
* r8-r12 or lr to the stack.
*/
mov r8, lo(timer_overflow)
orh r8, hi(timer_overflow)
ld.w r9, r8[0]
mov r10, -1
mtsr SYSREG_COMPARE, r10
sub r9, -1
st.w r8[0], r9
rete
.type unknown_exception, @function
unknown_exception:
pushm r0-r12
sub r8, sp, REG_R12 - REG_R0 - 4
mov r9, lr
mfsr r10, SYSREG_RAR_EX
mfsr r11, SYSREG_RSR_EX
pushm r8-r11
mfsr r12, SYSREG_ECR
mov r11, sp
rcall do_unknown_exception
1: rjmp 1b

119
cpu/at32ap/exception.c Normal file
View File

@@ -0,0 +1,119 @@
/*
* Copyright (C) 2005-2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/sysreg.h>
#include <asm/ptrace.h>
static const char * const cpu_modes[8] = {
"Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
"Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
};
static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
{
unsigned long p;
int i;
printf("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
for (p = bottom & ~31; p < top; ) {
printf("%04lx: ", p & 0xffff);
for (i = 0; i < 8; i++, p += 4) {
unsigned int val;
if (p < bottom || p >= top)
printf(" ");
else {
val = *(unsigned long *)p;
printf("%08x ", val);
}
}
printf("\n");
}
}
void do_unknown_exception(unsigned int ecr, struct pt_regs *regs)
{
unsigned int mode;
printf("\n *** Unhandled exception %u at PC=0x%08lx\n", ecr, regs->pc);
switch (ecr) {
case ECR_BUS_ERROR_WRITE:
case ECR_BUS_ERROR_READ:
printf("Bus error at address 0x%08lx\n",
sysreg_read(BEAR));
break;
case ECR_TLB_MULTIPLE:
case ECR_ADDR_ALIGN_X:
case ECR_PROTECTION_X:
case ECR_ADDR_ALIGN_R:
case ECR_ADDR_ALIGN_W:
case ECR_PROTECTION_R:
case ECR_PROTECTION_W:
case ECR_DTLB_MODIFIED:
case ECR_TLB_MISS_X:
case ECR_TLB_MISS_R:
case ECR_TLB_MISS_W:
printf("MMU exception at address 0x%08lx\n",
sysreg_read(TLBEAR));
break;
}
printf(" pc: %08lx lr: %08lx sp: %08lx r12: %08lx\n",
regs->pc, regs->lr, regs->sp, regs->r12);
printf(" r11: %08lx r10: %08lx r9: %08lx r8: %08lx\n",
regs->r11, regs->r10, regs->r9, regs->r8);
printf(" r7: %08lx r6: %08lx r5: %08lx r4: %08lx\n",
regs->r7, regs->r6, regs->r5, regs->r4);
printf(" r3: %08lx r2: %08lx r1: %08lx r0: %08lx\n",
regs->r3, regs->r2, regs->r1, regs->r0);
printf("Flags: %c%c%c%c%c\n",
regs->sr & SR_Q ? 'Q' : 'q',
regs->sr & SR_V ? 'V' : 'v',
regs->sr & SR_N ? 'N' : 'n',
regs->sr & SR_Z ? 'Z' : 'z',
regs->sr & SR_C ? 'C' : 'c');
printf("Mode bits: %c%c%c%c%c%c%c%c%c\n",
regs->sr & SR_H ? 'H' : 'h',
regs->sr & SR_R ? 'R' : 'r',
regs->sr & SR_J ? 'J' : 'j',
regs->sr & SR_EM ? 'E' : 'e',
regs->sr & SR_I3M ? '3' : '.',
regs->sr & SR_I2M ? '2' : '.',
regs->sr & SR_I1M ? '1' : '.',
regs->sr & SR_I0M ? '0' : '.',
regs->sr & SR_GM ? 'G' : 'g');
mode = (regs->sr >> SYSREG_M0_OFFSET) & 7;
printf("CPU Mode: %s\n", cpu_modes[mode]);
/* Avoid exception loops */
if (regs->sp >= CFG_INIT_SP_ADDR
|| regs->sp < (CFG_INIT_SP_ADDR - CONFIG_STACKSIZE))
printf("\nStack pointer seems bogus, won't do stack dump\n");
else
dump_mem("\nStack: ", regs->sp, CFG_INIT_SP_ADDR);
panic("Unhandled exception\n");
}

155
cpu/at32ap/hsdramc.c Normal file
View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2005-2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#ifdef CFG_HSDRAMC
#include <asm/io.h>
#include <asm/sdram.h>
#include <asm/arch/platform.h>
#include "hsdramc1.h"
struct hsdramc {
const struct device *hebi;
void *regs;
};
static struct hsdramc hsdramc;
unsigned long sdram_init(const struct sdram_info *info)
{
unsigned long *sdram = (unsigned long *)uncached(info->phys_addr);
unsigned long sdram_size;
unsigned long tmp;
unsigned long bus_hz;
unsigned int i;
hsdramc.hebi = get_device(DEVICE_HEBI);
if (!hsdramc.hebi)
return 0;
/* FIXME: Both of these lines are complete hacks */
hsdramc.regs = hsdramc.hebi->regs + 0x400;
bus_hz = pm_get_clock_freq(hsdramc.hebi->resource[0].u.clock.id);
cpu_enable_sdram();
tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
| HSDRAMC1_BF(NR, info->row_bits - 11)
| HSDRAMC1_BF(NB, info->bank_bits - 1)
| HSDRAMC1_BF(CAS, info->cas)
| HSDRAMC1_BF(TWR, info->twr)
| HSDRAMC1_BF(TRC, info->trc)
| HSDRAMC1_BF(TRP, info->trp)
| HSDRAMC1_BF(TRCD, info->trcd)
| HSDRAMC1_BF(TRAS, info->tras)
| HSDRAMC1_BF(TXSR, info->txsr));
#ifdef CFG_SDRAM_16BIT
tmp |= HSDRAMC1_BIT(DBW);
sdram_size = 1 << (info->row_bits + info->col_bits
+ info->bank_bits + 1);
#else
sdram_size = 1 << (info->row_bits + info->col_bits
+ info->bank_bits + 2);
#endif
hsdramc1_writel(&hsdramc, CR, tmp);
/*
* Initialization sequence for SDRAM, from the data sheet:
*
* 1. A minimum pause of 200 us is provided to precede any
* signal toggle.
*/
udelay(200);
/*
* 2. A Precharge All command is issued to the SDRAM
*/
hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
hsdramc1_readl(&hsdramc, MR);
writel(0, sdram);
/*
* 3. Eight auto-refresh (CBR) cycles are provided
*/
hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_AUTO_REFRESH);
hsdramc1_readl(&hsdramc, MR);
for (i = 0; i < 8; i++)
writel(0, sdram);
/*
* 4. A mode register set (MRS) cycle is issued to program
* SDRAM parameters, in particular CAS latency and burst
* length.
*
* CAS from info struct, burst length 1, serial burst type
*/
hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_LOAD_MODE);
hsdramc1_readl(&hsdramc, MR);
writel(0, sdram + (info->cas << 4));
/*
* 5. A Normal Mode command is provided, 3 clocks after tMRD
* is met.
*
* From the timing diagram, it looks like tMRD is 3
* cycles...try a dummy read from the peripheral bus.
*/
hsdramc1_readl(&hsdramc, MR);
hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_NORMAL);
hsdramc1_readl(&hsdramc, MR);
writel(0, sdram);
/*
* 6. Write refresh rate into SDRAMC refresh timer count
* register (refresh rate = timing between refresh cycles).
*
* 15.6 us is a typical value for a burst of length one
*/
hsdramc1_writel(&hsdramc, TR, (156 * (bus_hz / 1000)) / 10000);
printf("SDRAM: %u MB at address 0x%08lx\n",
sdram_size >> 20, info->phys_addr);
printf("Testing SDRAM...");
for (i = 0; i < sdram_size / 4; i++)
sdram[i] = i;
for (i = 0; i < sdram_size / 4; i++) {
tmp = sdram[i];
if (tmp != i) {
printf("FAILED at address 0x%08lx\n",
info->phys_addr + i * 4);
printf("SDRAM: read 0x%lx, expected 0x%lx\n", tmp, i);
return 0;
}
}
puts("OK\n");
return sdram_size;
}
#endif /* CFG_HSDRAMC */

143
cpu/at32ap/hsdramc1.h Normal file
View File

@@ -0,0 +1,143 @@
/*
* Register definitions for SDRAM Controller
*/
#ifndef __ASM_AVR32_HSDRAMC1_H__
#define __ASM_AVR32_HSDRAMC1_H__
/* HSDRAMC1 register offsets */
#define HSDRAMC1_MR 0x0000
#define HSDRAMC1_TR 0x0004
#define HSDRAMC1_CR 0x0008
#define HSDRAMC1_HSR 0x000c
#define HSDRAMC1_LPR 0x0010
#define HSDRAMC1_IER 0x0014
#define HSDRAMC1_IDR 0x0018
#define HSDRAMC1_IMR 0x001c
#define HSDRAMC1_ISR 0x0020
#define HSDRAMC1_MDR 0x0024
#define HSDRAMC1_VERSION 0x00fc
/* Bitfields in MR */
#define HSDRAMC1_MODE_OFFSET 0
#define HSDRAMC1_MODE_SIZE 3
/* Bitfields in TR */
#define HSDRAMC1_COUNT_OFFSET 0
#define HSDRAMC1_COUNT_SIZE 12
/* Bitfields in CR */
#define HSDRAMC1_NC_OFFSET 0
#define HSDRAMC1_NC_SIZE 2
#define HSDRAMC1_NR_OFFSET 2
#define HSDRAMC1_NR_SIZE 2
#define HSDRAMC1_NB_OFFSET 4
#define HSDRAMC1_NB_SIZE 1
#define HSDRAMC1_CAS_OFFSET 5
#define HSDRAMC1_CAS_SIZE 2
#define HSDRAMC1_DBW_OFFSET 7
#define HSDRAMC1_DBW_SIZE 1
#define HSDRAMC1_TWR_OFFSET 8
#define HSDRAMC1_TWR_SIZE 4
#define HSDRAMC1_TRC_OFFSET 12
#define HSDRAMC1_TRC_SIZE 4
#define HSDRAMC1_TRP_OFFSET 16
#define HSDRAMC1_TRP_SIZE 4
#define HSDRAMC1_TRCD_OFFSET 20
#define HSDRAMC1_TRCD_SIZE 4
#define HSDRAMC1_TRAS_OFFSET 24
#define HSDRAMC1_TRAS_SIZE 4
#define HSDRAMC1_TXSR_OFFSET 28
#define HSDRAMC1_TXSR_SIZE 4
/* Bitfields in HSR */
#define HSDRAMC1_DA_OFFSET 0
#define HSDRAMC1_DA_SIZE 1
/* Bitfields in LPR */
#define HSDRAMC1_LPCB_OFFSET 0
#define HSDRAMC1_LPCB_SIZE 2
#define HSDRAMC1_PASR_OFFSET 4
#define HSDRAMC1_PASR_SIZE 3
#define HSDRAMC1_TCSR_OFFSET 8
#define HSDRAMC1_TCSR_SIZE 2
#define HSDRAMC1_DS_OFFSET 10
#define HSDRAMC1_DS_SIZE 2
#define HSDRAMC1_TIMEOUT_OFFSET 12
#define HSDRAMC1_TIMEOUT_SIZE 2
/* Bitfields in IDR */
#define HSDRAMC1_RES_OFFSET 0
#define HSDRAMC1_RES_SIZE 1
/* Bitfields in MDR */
#define HSDRAMC1_MD_OFFSET 0
#define HSDRAMC1_MD_SIZE 2
/* Bitfields in VERSION */
#define HSDRAMC1_VERSION_OFFSET 0
#define HSDRAMC1_VERSION_SIZE 12
#define HSDRAMC1_MFN_OFFSET 16
#define HSDRAMC1_MFN_SIZE 3
/* Constants for MODE */
#define HSDRAMC1_MODE_NORMAL 0
#define HSDRAMC1_MODE_NOP 1
#define HSDRAMC1_MODE_BANKS_PRECHARGE 2
#define HSDRAMC1_MODE_LOAD_MODE 3
#define HSDRAMC1_MODE_AUTO_REFRESH 4
#define HSDRAMC1_MODE_EXT_LOAD_MODE 5
#define HSDRAMC1_MODE_POWER_DOWN 6
/* Constants for NC */
#define HSDRAMC1_NC_8_COLUMN_BITS 0
#define HSDRAMC1_NC_9_COLUMN_BITS 1
#define HSDRAMC1_NC_10_COLUMN_BITS 2
#define HSDRAMC1_NC_11_COLUMN_BITS 3
/* Constants for NR */
#define HSDRAMC1_NR_11_ROW_BITS 0
#define HSDRAMC1_NR_12_ROW_BITS 1
#define HSDRAMC1_NR_13_ROW_BITS 2
/* Constants for NB */
#define HSDRAMC1_NB_TWO_BANKS 0
#define HSDRAMC1_NB_FOUR_BANKS 1
/* Constants for CAS */
#define HSDRAMC1_CAS_ONE_CYCLE 1
#define HSDRAMC1_CAS_TWO_CYCLES 2
/* Constants for DBW */
#define HSDRAMC1_DBW_32_BITS 0
#define HSDRAMC1_DBW_16_BITS 1
/* Constants for TIMEOUT */
#define HSDRAMC1_TIMEOUT_AFTER_END 0
#define HSDRAMC1_TIMEOUT_64_CYC_AFTER_END 1
#define HSDRAMC1_TIMEOUT_128_CYC_AFTER_END 2
/* Constants for MD */
#define HSDRAMC1_MD_SDRAM 0
#define HSDRAMC1_MD_LOW_POWER_SDRAM 1
/* Bit manipulation macros */
#define HSDRAMC1_BIT(name) \
(1 << HSDRAMC1_##name##_OFFSET)
#define HSDRAMC1_BF(name,value) \
(((value) & ((1 << HSDRAMC1_##name##_SIZE) - 1)) \
<< HSDRAMC1_##name##_OFFSET)
#define HSDRAMC1_BFEXT(name,value) \
(((value) >> HSDRAMC1_##name##_OFFSET) \
& ((1 << HSDRAMC1_##name##_SIZE) - 1))
#define HSDRAMC1_BFINS(name,value,old) \
(((old) & ~(((1 << HSDRAMC1_##name##_SIZE) - 1) \
<< HSDRAMC1_##name##_OFFSET)) \
| HSDRAMC1_BF(name,value))
/* Register access macros */
#define hsdramc1_readl(port,reg) \
readl((port)->regs + HSDRAMC1_##reg)
#define hsdramc1_writel(port,reg,value) \
writel((value), (port)->regs + HSDRAMC1_##reg)
#endif /* __ASM_AVR32_HSDRAMC1_H__ */

126
cpu/at32ap/hsmc3.h Normal file
View File

@@ -0,0 +1,126 @@
/*
* Register definitions for Static Memory Controller
*/
#ifndef __CPU_AT32AP_HSMC3_H__
#define __CPU_AT32AP_HSMC3_H__
/* HSMC3 register offsets */
#define HSMC3_SETUP0 0x0000
#define HSMC3_PULSE0 0x0004
#define HSMC3_CYCLE0 0x0008
#define HSMC3_MODE0 0x000c
#define HSMC3_SETUP1 0x0010
#define HSMC3_PULSE1 0x0014
#define HSMC3_CYCLE1 0x0018
#define HSMC3_MODE1 0x001c
#define HSMC3_SETUP2 0x0020
#define HSMC3_PULSE2 0x0024
#define HSMC3_CYCLE2 0x0028
#define HSMC3_MODE2 0x002c
#define HSMC3_SETUP3 0x0030
#define HSMC3_PULSE3 0x0034
#define HSMC3_CYCLE3 0x0038
#define HSMC3_MODE3 0x003c
#define HSMC3_SETUP4 0x0040
#define HSMC3_PULSE4 0x0044
#define HSMC3_CYCLE4 0x0048
#define HSMC3_MODE4 0x004c
#define HSMC3_SETUP5 0x0050
#define HSMC3_PULSE5 0x0054
#define HSMC3_CYCLE5 0x0058
#define HSMC3_MODE5 0x005c
/* Bitfields in SETUP0 */
#define HSMC3_NWE_SETUP_OFFSET 0
#define HSMC3_NWE_SETUP_SIZE 6
#define HSMC3_NCS_WR_SETUP_OFFSET 8
#define HSMC3_NCS_WR_SETUP_SIZE 6
#define HSMC3_NRD_SETUP_OFFSET 16
#define HSMC3_NRD_SETUP_SIZE 6
#define HSMC3_NCS_RD_SETUP_OFFSET 24
#define HSMC3_NCS_RD_SETUP_SIZE 6
/* Bitfields in PULSE0 */
#define HSMC3_NWE_PULSE_OFFSET 0
#define HSMC3_NWE_PULSE_SIZE 7
#define HSMC3_NCS_WR_PULSE_OFFSET 8
#define HSMC3_NCS_WR_PULSE_SIZE 7
#define HSMC3_NRD_PULSE_OFFSET 16
#define HSMC3_NRD_PULSE_SIZE 7
#define HSMC3_NCS_RD_PULSE_OFFSET 24
#define HSMC3_NCS_RD_PULSE_SIZE 7
/* Bitfields in CYCLE0 */
#define HSMC3_NWE_CYCLE_OFFSET 0
#define HSMC3_NWE_CYCLE_SIZE 9
#define HSMC3_NRD_CYCLE_OFFSET 16
#define HSMC3_NRD_CYCLE_SIZE 9
/* Bitfields in MODE0 */
#define HSMC3_READ_MODE_OFFSET 0
#define HSMC3_READ_MODE_SIZE 1
#define HSMC3_WRITE_MODE_OFFSET 1
#define HSMC3_WRITE_MODE_SIZE 1
#define HSMC3_EXNW_MODE_OFFSET 4
#define HSMC3_EXNW_MODE_SIZE 2
#define HSMC3_BAT_OFFSET 8
#define HSMC3_BAT_SIZE 1
#define HSMC3_DBW_OFFSET 12
#define HSMC3_DBW_SIZE 2
#define HSMC3_TDF_CYCLES_OFFSET 16
#define HSMC3_TDF_CYCLES_SIZE 4
#define HSMC3_TDF_MODE_OFFSET 20
#define HSMC3_TDF_MODE_SIZE 1
#define HSMC3_PMEN_OFFSET 24
#define HSMC3_PMEN_SIZE 1
#define HSMC3_PS_OFFSET 28
#define HSMC3_PS_SIZE 2
/* Bitfields in MODE1 */
#define HSMC3_PD_OFFSET 28
#define HSMC3_PD_SIZE 2
/* Constants for READ_MODE */
#define HSMC3_READ_MODE_NCS_CONTROLLED 0
#define HSMC3_READ_MODE_NRD_CONTROLLED 1
/* Constants for WRITE_MODE */
#define HSMC3_WRITE_MODE_NCS_CONTROLLED 0
#define HSMC3_WRITE_MODE_NWE_CONTROLLED 1
/* Constants for EXNW_MODE */
#define HSMC3_EXNW_MODE_DISABLED 0
#define HSMC3_EXNW_MODE_RESERVED 1
#define HSMC3_EXNW_MODE_FROZEN 2
#define HSMC3_EXNW_MODE_READY 3
/* Constants for BAT */
#define HSMC3_BAT_BYTE_SELECT 0
#define HSMC3_BAT_BYTE_WRITE 1
/* Constants for DBW */
#define HSMC3_DBW_8_BITS 0
#define HSMC3_DBW_16_BITS 1
#define HSMC3_DBW_32_BITS 2
/* Bit manipulation macros */
#define HSMC3_BIT(name) \
(1 << HSMC3_##name##_OFFSET)
#define HSMC3_BF(name,value) \
(((value) & ((1 << HSMC3_##name##_SIZE) - 1)) \
<< HSMC3_##name##_OFFSET)
#define HSMC3_BFEXT(name,value) \
(((value) >> HSMC3_##name##_OFFSET) \
& ((1 << HSMC3_##name##_SIZE) - 1))
#define HSMC3_BFINS(name,value,old)\
(((old) & ~(((1 << HSMC3_##name##_SIZE) - 1) \
<< HSMC3_##name##_OFFSET)) \
| HSMC3_BF(name,value))
/* Register access macros */
#define hsmc3_readl(port,reg) \
readl((port)->regs + HSMC3_##reg)
#define hsmc3_writel(port,reg,value) \
writel((value), (port)->regs + HSMC3_##reg)
#endif /* __CPU_AT32AP_HSMC3_H__ */

154
cpu/at32ap/interrupts.c Normal file
View File

@@ -0,0 +1,154 @@
/*
* Copyright (C) 2004-2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/div64.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/sysreg.h>
#include <asm/arch/platform.h>
#define HANDLER_MASK 0x00ffffff
#define INTLEV_SHIFT 30
#define INTLEV_MASK 0x00000003
DECLARE_GLOBAL_DATA_PTR;
/* Incremented whenever COUNT reaches 0xffffffff by timer_interrupt_handler */
volatile unsigned long timer_overflow;
/*
* Instead of dividing by get_tbclk(), multiply by this constant and
* right-shift the result by 32 bits.
*/
static unsigned long tb_factor;
static const struct device *intc_dev;
unsigned long get_tbclk(void)
{
return gd->cpu_hz;
}
unsigned long long get_ticks(void)
{
unsigned long lo, hi_now, hi_prev;
do {
hi_prev = timer_overflow;
lo = sysreg_read(COUNT);
hi_now = timer_overflow;
} while (hi_prev != hi_now);
return ((unsigned long long)hi_now << 32) | lo;
}
void reset_timer(void)
{
sysreg_write(COUNT, 0);
cpu_sync_pipeline(); /* process any pending interrupts */
timer_overflow = 0;
}
unsigned long get_timer(unsigned long base)
{
u64 now = get_ticks();
now *= tb_factor;
return (unsigned long)(now >> 32) - base;
}
void set_timer(unsigned long t)
{
unsigned long long ticks = t;
unsigned long lo, hi, hi_new;
ticks = (ticks * get_tbclk()) / CFG_HZ;
hi = ticks >> 32;
lo = ticks & 0xffffffffUL;
do {
timer_overflow = hi;
sysreg_write(COUNT, lo);
hi_new = timer_overflow;
} while (hi_new != hi);
}
/*
* For short delays only. It will overflow after a few seconds.
*/
void udelay(unsigned long usec)
{
unsigned long now, end;
now = sysreg_read(COUNT);
end = ((usec * (get_tbclk() / 10000)) + 50) / 100;
end += now;
while (now > end)
now = sysreg_read(COUNT);
while (now < end)
now = sysreg_read(COUNT);
}
static int set_interrupt_handler(unsigned int nr, void (*handler)(void),
unsigned int priority)
{
unsigned long intpr;
unsigned long handler_addr = (unsigned long)handler;
if ((handler_addr & HANDLER_MASK) != handler_addr
|| (priority & INTLEV_MASK) != priority)
return -EINVAL;
intpr = (handler_addr & HANDLER_MASK);
intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT;
writel(intpr, intc_dev->regs + 4 * nr);
return 0;
}
void timer_init(void)
{
extern void timer_interrupt_handler(void);
u64 tmp;
sysreg_write(COUNT, 0);
tmp = (u64)CFG_HZ << 32;
tmp += gd->cpu_hz / 2;
do_div(tmp, gd->cpu_hz);
tb_factor = (u32)tmp;
intc_dev = get_device(DEVICE_INTC);
if (!intc_dev
|| set_interrupt_handler(0, &timer_interrupt_handler, 3))
return;
/* For all practical purposes, this gives us an overflow interrupt */
sysreg_write(COMPARE, 0xffffffff);
}

94
cpu/at32ap/pio.c Normal file
View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/arch/platform.h>
#include "pio2.h"
struct pio_state {
const struct device *dev;
u32 alloc_mask;
};
static struct pio_state pio_state[CFG_NR_PIOS];
int gpio_set_func(enum device_id gpio_devid, unsigned int start,
unsigned int nr_pins, enum gpio_func func)
{
const struct device *gpio;
struct pio_state *state;
u32 mask;
state = &pio_state[gpio_devid - DEVICE_PIOA];
gpio = get_device(gpio_devid);
if (!gpio)
return -EBUSY;
state->dev = gpio;
mask = ((1 << nr_pins) - 1) << start;
if (mask & state->alloc_mask) {
put_device(gpio);
return -EBUSY;
}
state->alloc_mask |= mask;
switch (func) {
case GPIO_FUNC_GPIO:
/* TODO */
return -EINVAL;
case GPIO_FUNC_A:
pio2_writel(gpio, ASR, mask);
pio2_writel(gpio, PDR, mask);
pio2_writel(gpio, PUDR, mask);
break;
case GPIO_FUNC_B:
pio2_writel(gpio, BSR, mask);
pio2_writel(gpio, PDR, mask);
pio2_writel(gpio, PUDR, mask);
break;
}
return 0;
}
void gpio_free(enum device_id gpio_devid, unsigned int start,
unsigned int nr_pins)
{
const struct device *gpio;
struct pio_state *state;
u32 mask;
state = &pio_state[gpio_devid - DEVICE_PIOA];
gpio = state->dev;
mask = ((1 << nr_pins) - 1) << start;
pio2_writel(gpio, ODR, mask);
pio2_writel(gpio, PER, mask);
state->alloc_mask &= ~mask;
put_device(gpio);
}

44
cpu/at32ap/pio2.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* Register definitions for Parallel Input/Output Controller
*/
#ifndef __CPU_AT32AP_PIO2_H__
#define __CPU_AT32AP_PIO2_H__
/* PIO2 register offsets */
#define PIO2_PER 0x0000
#define PIO2_PDR 0x0004
#define PIO2_PSR 0x0008
#define PIO2_OER 0x0010
#define PIO2_ODR 0x0014
#define PIO2_OSR 0x0018
#define PIO2_IFER 0x0020
#define PIO2_IFDR 0x0024
#define PIO2_ISFR 0x0028
#define PIO2_SODR 0x0030
#define PIO2_CODR 0x0034
#define PIO2_ODSR 0x0038
#define PIO2_PDSR 0x003c
#define PIO2_IER 0x0040
#define PIO2_IDR 0x0044
#define PIO2_IMR 0x0048
#define PIO2_ISR 0x004c
#define PIO2_MDER 0x0050
#define PIO2_MDDR 0x0054
#define PIO2_MDSR 0x0058
#define PIO2_PUDR 0x0060
#define PIO2_PUER 0x0064
#define PIO2_PUSR 0x0068
#define PIO2_ASR 0x0070
#define PIO2_BSR 0x0074
#define PIO2_ABSR 0x0078
#define PIO2_OWER 0x00a0
#define PIO2_OWDR 0x00a4
#define PIO2_OWSR 0x00a8
/* Register access macros */
#define pio2_readl(port,reg) \
readl((port)->regs + PIO2_##reg)
#define pio2_writel(port,reg,value) \
writel((value), (port)->regs + PIO2_##reg)
#endif /* __CPU_AT32AP_PIO2_H__ */

163
cpu/at32ap/pm.c Normal file
View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#ifdef CFG_POWER_MANAGER
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/arch/memory-map.h>
#include <asm/arch/platform.h>
#include "sm.h"
/* Sanity checks */
#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB) \
|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA) \
|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB)
# error Constraint fCPU >= fHSB >= fPB{A,B} violated
#endif
#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1))
# error Invalid PLL multiplier and/or divider
#endif
DECLARE_GLOBAL_DATA_PTR;
struct clock_domain_state {
const struct device *bridge;
unsigned long freq;
u32 mask;
};
static struct clock_domain_state ckd_state[NR_CLOCK_DOMAINS];
int pm_enable_clock(enum clock_domain_id id, unsigned int index)
{
const struct clock_domain *ckd = &chip_clock[id];
struct clock_domain_state *state = &ckd_state[id];
if (ckd->bridge != NO_DEVICE) {
state->bridge = get_device(ckd->bridge);
if (!state->bridge)
return -EBUSY;
}
state->mask |= 1 << index;
if (gd->sm)
writel(state->mask, gd->sm->regs + ckd->reg);
return 0;
}
void pm_disable_clock(enum clock_domain_id id, unsigned int index)
{
const struct clock_domain *ckd = &chip_clock[id];
struct clock_domain_state *state = &ckd_state[id];
state->mask &= ~(1 << index);
if (gd->sm)
writel(state->mask, gd->sm->regs + ckd->reg);
if (ckd->bridge)
put_device(state->bridge);
}
unsigned long pm_get_clock_freq(enum clock_domain_id domain)
{
return ckd_state[domain].freq;
}
void pm_init(void)
{
uint32_t cksel = 0;
unsigned long main_clock;
/* Make sure we don't disable any device we're already using */
get_device(DEVICE_HRAMC);
get_device(DEVICE_HEBI);
/* Enable the PICO as well */
ckd_state[CLOCK_CPU].mask |= 1;
gd->sm = get_device(DEVICE_SM);
if (!gd->sm)
panic("Unable to claim system manager device!\n");
/* Disable any devices that haven't been explicitly claimed */
sm_writel(gd->sm, PM_PBB_MASK, ckd_state[CLOCK_PBB].mask);
sm_writel(gd->sm, PM_PBA_MASK, ckd_state[CLOCK_PBA].mask);
sm_writel(gd->sm, PM_HSB_MASK, ckd_state[CLOCK_HSB].mask);
sm_writel(gd->sm, PM_CPU_MASK, ckd_state[CLOCK_CPU].mask);
#ifdef CONFIG_PLL
/* Initialize the PLL */
main_clock = (CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL;
sm_writel(gd->sm, PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES)
| SM_BF(PLLMUL, CFG_PLL0_MUL - 1)
| SM_BF(PLLDIV, CFG_PLL0_DIV - 1)
| SM_BF(PLLOPT, CFG_PLL0_OPT)
| SM_BF(PLLOSC, 0)
| SM_BIT(PLLEN)));
/* Wait for lock */
while (!(sm_readl(gd->sm, PM_ISR) & SM_BIT(LOCK0))) ;
#else
main_clock = CFG_OSC0_HZ;
#endif
/* Set up clocks for the CPU and all peripheral buses */
if (CFG_CLKDIV_CPU) {
cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1);
ckd_state[CLOCK_CPU].freq = main_clock / (1 << CFG_CLKDIV_CPU);
} else {
ckd_state[CLOCK_CPU].freq = main_clock;
}
if (CFG_CLKDIV_HSB) {
cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1);
ckd_state[CLOCK_HSB].freq = main_clock / (1 << CFG_CLKDIV_HSB);
} else {
ckd_state[CLOCK_HSB].freq = main_clock;
}
if (CFG_CLKDIV_PBA) {
cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1);
ckd_state[CLOCK_PBA].freq = main_clock / (1 << CFG_CLKDIV_PBA);
} else {
ckd_state[CLOCK_PBA].freq = main_clock;
}
if (CFG_CLKDIV_PBB) {
cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1);
ckd_state[CLOCK_PBB].freq = main_clock / (1 << CFG_CLKDIV_PBB);
} else {
ckd_state[CLOCK_PBB].freq = main_clock;
}
sm_writel(gd->sm, PM_CKSEL, cksel);
/* CFG_HZ currently depends on cpu_hz */
gd->cpu_hz = ckd_state[CLOCK_CPU].freq;
#ifdef CONFIG_PLL
/* Use PLL0 as main clock */
sm_writel(gd->sm, PM_MCCTRL, SM_BIT(PLLSEL));
#endif
}
#endif /* CFG_POWER_MANAGER */

204
cpu/at32ap/sm.h Normal file
View File

@@ -0,0 +1,204 @@
/*
* Register definitions for System Manager
*/
#ifndef __CPU_AT32AP_SM_H__
#define __CPU_AT32AP_SM_H__
/* SM register offsets */
#define SM_PM_MCCTRL 0x0000
#define SM_PM_CKSEL 0x0004
#define SM_PM_CPU_MASK 0x0008
#define SM_PM_HSB_MASK 0x000c
#define SM_PM_PBA_MASK 0x0010
#define SM_PM_PBB_MASK 0x0014
#define SM_PM_PLL0 0x0020
#define SM_PM_PLL1 0x0024
#define SM_PM_VCTRL 0x0030
#define SM_PM_VMREF 0x0034
#define SM_PM_VMV 0x0038
#define SM_PM_IER 0x0040
#define SM_PM_IDR 0x0044
#define SM_PM_IMR 0x0048
#define SM_PM_ISR 0x004c
#define SM_PM_ICR 0x0050
#define SM_PM_GCCTRL 0x0060
#define SM_RTC_CTRL 0x0080
#define SM_RTC_VAL 0x0084
#define SM_RTC_TOP 0x0088
#define SM_RTC_IER 0x0090
#define SM_RTC_IDR 0x0094
#define SM_RTC_IMR 0x0098
#define SM_RTC_ISR 0x009c
#define SM_RTC_ICR 0x00a0
#define SM_WDT_CTRL 0x00b0
#define SM_WDT_CLR 0x00b4
#define SM_WDT_EXT 0x00b8
#define SM_RC_RCAUSE 0x00c0
#define SM_EIM_IER 0x0100
#define SM_EIM_IDR 0x0104
#define SM_EIM_IMR 0x0108
#define SM_EIM_ISR 0x010c
#define SM_EIM_ICR 0x0110
#define SM_EIM_MODE 0x0114
#define SM_EIM_EDGE 0x0118
#define SM_EIM_LEVEL 0x011c
#define SM_EIM_TEST 0x0120
#define SM_EIM_NMIC 0x0124
/* Bitfields in PM_CKSEL */
#define SM_CPUSEL_OFFSET 0
#define SM_CPUSEL_SIZE 3
#define SM_CPUDIV_OFFSET 7
#define SM_CPUDIV_SIZE 1
#define SM_HSBSEL_OFFSET 8
#define SM_HSBSEL_SIZE 3
#define SM_HSBDIV_OFFSET 15
#define SM_HSBDIV_SIZE 1
#define SM_PBASEL_OFFSET 16
#define SM_PBASEL_SIZE 3
#define SM_PBADIV_OFFSET 23
#define SM_PBADIV_SIZE 1
#define SM_PBBSEL_OFFSET 24
#define SM_PBBSEL_SIZE 3
#define SM_PBBDIV_OFFSET 31
#define SM_PBBDIV_SIZE 1
/* Bitfields in PM_PLL0 */
#define SM_PLLEN_OFFSET 0
#define SM_PLLEN_SIZE 1
#define SM_PLLOSC_OFFSET 1
#define SM_PLLOSC_SIZE 1
#define SM_PLLOPT_OFFSET 2
#define SM_PLLOPT_SIZE 3
#define SM_PLLDIV_OFFSET 8
#define SM_PLLDIV_SIZE 8
#define SM_PLLMUL_OFFSET 16
#define SM_PLLMUL_SIZE 8
#define SM_PLLCOUNT_OFFSET 24
#define SM_PLLCOUNT_SIZE 6
#define SM_PLLTEST_OFFSET 31
#define SM_PLLTEST_SIZE 1
/* Bitfields in PM_VCTRL */
#define SM_VAUTO_OFFSET 0
#define SM_VAUTO_SIZE 1
#define SM_PM_VCTRL_VAL_OFFSET 8
#define SM_PM_VCTRL_VAL_SIZE 7
/* Bitfields in PM_VMREF */
#define SM_REFSEL_OFFSET 0
#define SM_REFSEL_SIZE 4
/* Bitfields in PM_VMV */
#define SM_PM_VMV_VAL_OFFSET 0
#define SM_PM_VMV_VAL_SIZE 8
/* Bitfields in PM_ICR */
#define SM_LOCK0_OFFSET 0
#define SM_LOCK0_SIZE 1
#define SM_LOCK1_OFFSET 1
#define SM_LOCK1_SIZE 1
#define SM_WAKE_OFFSET 2
#define SM_WAKE_SIZE 1
#define SM_VOK_OFFSET 3
#define SM_VOK_SIZE 1
#define SM_VMRDY_OFFSET 4
#define SM_VMRDY_SIZE 1
#define SM_CKRDY_OFFSET 5
#define SM_CKRDY_SIZE 1
/* Bitfields in PM_GCCTRL */
#define SM_OSCSEL_OFFSET 0
#define SM_OSCSEL_SIZE 1
#define SM_PLLSEL_OFFSET 1
#define SM_PLLSEL_SIZE 1
#define SM_CEN_OFFSET 2
#define SM_CEN_SIZE 1
#define SM_CPC_OFFSET 3
#define SM_CPC_SIZE 1
#define SM_DIVEN_OFFSET 4
#define SM_DIVEN_SIZE 1
#define SM_DIV_OFFSET 8
#define SM_DIV_SIZE 8
/* Bitfields in RTC_CTRL */
#define SM_PCLR_OFFSET 1
#define SM_PCLR_SIZE 1
#define SM_TOPEN_OFFSET 2
#define SM_TOPEN_SIZE 1
#define SM_CLKEN_OFFSET 3
#define SM_CLKEN_SIZE 1
#define SM_PSEL_OFFSET 8
#define SM_PSEL_SIZE 16
/* Bitfields in RTC_VAL */
#define SM_RTC_VAL_VAL_OFFSET 0
#define SM_RTC_VAL_VAL_SIZE 31
/* Bitfields in RTC_TOP */
#define SM_RTC_TOP_VAL_OFFSET 0
#define SM_RTC_TOP_VAL_SIZE 32
/* Bitfields in RTC_ICR */
#define SM_TOPI_OFFSET 0
#define SM_TOPI_SIZE 1
/* Bitfields in WDT_CTRL */
#define SM_KEY_OFFSET 24
#define SM_KEY_SIZE 8
/* Bitfields in RC_RCAUSE */
#define SM_POR_OFFSET 0
#define SM_POR_SIZE 1
#define SM_BOD_OFFSET 1
#define SM_BOD_SIZE 1
#define SM_EXT_OFFSET 2
#define SM_EXT_SIZE 1
#define SM_WDT_OFFSET 3
#define SM_WDT_SIZE 1
#define SM_NTAE_OFFSET 4
#define SM_NTAE_SIZE 1
#define SM_SERP_OFFSET 5
#define SM_SERP_SIZE 1
/* Bitfields in EIM_EDGE */
#define SM_INT0_OFFSET 0
#define SM_INT0_SIZE 1
#define SM_INT1_OFFSET 1
#define SM_INT1_SIZE 1
#define SM_INT2_OFFSET 2
#define SM_INT2_SIZE 1
#define SM_INT3_OFFSET 3
#define SM_INT3_SIZE 1
/* Bitfields in EIM_LEVEL */
/* Bitfields in EIM_TEST */
#define SM_TESTEN_OFFSET 31
#define SM_TESTEN_SIZE 1
/* Bitfields in EIM_NMIC */
#define SM_EN_OFFSET 0
#define SM_EN_SIZE 1
/* Bit manipulation macros */
#define SM_BIT(name) \
(1 << SM_##name##_OFFSET)
#define SM_BF(name,value) \
(((value) & ((1 << SM_##name##_SIZE) - 1)) \
<< SM_##name##_OFFSET)
#define SM_BFEXT(name,value) \
(((value) >> SM_##name##_OFFSET) \
& ((1 << SM_##name##_SIZE) - 1))
#define SM_BFINS(name,value,old) \
(((old) & ~(((1 << SM_##name##_SIZE) - 1) \
<< SM_##name##_OFFSET)) \
| SM_BF(name,value))
/* Register access macros */
#define sm_readl(port,reg) \
readl((port)->regs + SM_##reg)
#define sm_writel(port,reg,value) \
writel((value), (port)->regs + SM_##reg)
#endif /* __CPU_AT32AP_SM_H__ */

113
cpu/at32ap/start.S Normal file
View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) 2005-2006 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <asm/sysreg.h>
#ifndef PART_SPECIFIC_BOOTSTRAP
# define PART_SPECIFIC_BOOTSTRAP
#endif
#define SYSREG_MMUCR_I_OFFSET 2
#define SYSREG_MMUCR_S_OFFSET 4
#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
#define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE) \
| SYSREG_BIT(FE) | SYSREG_BIT(RE) \
| SYSREG_BIT(IBE) | SYSREG_BIT(IEE))
.text
.global _start
_start:
PART_SPECIFIC_BOOTSTRAP
/* Reset the Status Register */
mov r0, lo(SR_INIT)
orh r0, hi(SR_INIT)
mtsr SYSREG_SR, r0
/* Reset CPUCR and invalidate the BTB */
mov r2, CPUCR_INIT
mtsr SYSREG_CPUCR, r2
/* Flush the caches */
mov r1, 0
cache r1[4], 8
cache r1[0], 0
sync 0
/* Reset the MMU to default settings */
mov r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
mtsr SYSREG_MMUCR, r0
/* Internal RAM should not need any initialization. We might
have to initialize external RAM here if the part doesn't
have internal RAM (or we may use the data cache) */
/* Jump to cacheable segment */
lddpc pc, 1f
.align 2
1: .long 2f
2: lddpc sp, sp_init
/*
* Relocate the data section and initialize .bss. Everything
* is guaranteed to be at least doubleword aligned by the
* linker script.
*/
lddpc r12, .Ldata_vma
lddpc r11, .Ldata_lma
lddpc r10, .Ldata_end
sub r10, r12
4: ld.d r8, r11++
sub r10, 8
st.d r12++, r8
brne 4b
mov r8, 0
mov r9, 0
lddpc r10, .Lbss_end
sub r10, r12
4: sub r10, 8
st.d r12++, r8
brne 4b
/* Initialize the GOT pointer */
lddpc r6, got_init
3: rsub r6, pc
ld.w pc, r6[start_u_boot@got]
.align 2
.type sp_init,@object
sp_init:
.long CFG_INIT_SP_ADDR
got_init:
.long 3b - _GLOBAL_OFFSET_TABLE_
.Ldata_lma:
.long __data_lma
.Ldata_vma:
.long _data
.Ldata_end:
.long _edata
.Lbss_end:
.long _end

View File

@@ -38,7 +38,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -1,7 +1,7 @@
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
#
# (C) Copyright 2002
# Daniel Engstr<74>m, Omicron Ceti AB, daniel@omicron.se.
#
@@ -39,7 +39,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -88,7 +88,7 @@ START := $(addprefix $(obj),$(START))
all: $(LIB)
$(LIB): $(obj).depend $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -37,7 +37,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -37,7 +37,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -47,7 +47,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -37,7 +37,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -882,7 +882,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
defined(CONFIG_ICECUBE) || defined(CONFIG_INKA4X0) || \
defined(CONFIG_MCC200) || defined(CONFIG_O2DNT) || \
defined(CONFIG_PM520) || defined(CONFIG_TOP5200) || \
defined(CONFIG_TQM5200)
defined(CONFIG_TQM5200) || defined(CONFIG_V38B)
# ifndef CONFIG_FEC_10MBIT
fec->xcv_type = MII100;
# else

View File

@@ -32,7 +32,7 @@
*
* Based on (well, mostly copied from) the code from the 2.4 kernel by
* Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
*
*
* Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003 Montavista Software, Inc
*/

View File

@@ -38,7 +38,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -41,7 +41,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
$(obj)bedbug_603e.c:
ln -s $(src)../mpc8260/bedbug_603e.c $(obj)bedbug_603e.c

View File

@@ -37,7 +37,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS) $(obj)kgdb.o
$(AR) $(ARFLAGS) $@ $(OBJS) $(obj)kgdb.o
#########################################################################

View File

@@ -1,7 +1,7 @@
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
#
# Copyright 2004 Freescale Semiconductor, Inc.
#
# See file CREDITS for list of people who contributed to this
@@ -38,7 +38,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -30,7 +30,7 @@ LIB = $(obj)lib$(CPU).a
START = start.o resetvec.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
pci.o serial_scc.o commproc.o ether_fcc.o i2c.o spd_sdram.o
pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
@@ -39,7 +39,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -30,7 +30,10 @@
#include <command.h>
#include <asm/cache.h>
/* ------------------------------------------------------------------------- */
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
int checkcpu (void)
{
@@ -227,3 +230,48 @@ int dma_xfer(void *dest, uint count, void *src) {
return dma_check();
}
#endif
#ifdef CONFIG_OF_FLAT_TREE
void
ft_cpu_setup(void *blob, bd_t *bd)
{
u32 *p;
ulong clock;
int len;
clock = bd->bi_busfreq;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
#if defined(CONFIG_MPC85XX_TSEC1)
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
memcpy(p, bd->bi_enetaddr, 6);
#endif
#if defined(CONFIG_HAS_ETH1)
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
memcpy(p, bd->bi_enet1addr, 6);
#endif
#if defined(CONFIG_HAS_ETH2)
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
memcpy(p, bd->bi_enet2addr, 6);
#endif
#if defined(CONFIG_HAS_ETH3)
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
memcpy(p, bd->bi_enet3addr, 6);
#endif
}
#endif

View File

@@ -32,6 +32,7 @@
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_CPM2
static void config_8560_ioports (volatile immap_t * immr)
{

View File

@@ -1,265 +0,0 @@
/*
* (C) Copyright 2003,Motorola Inc.
* Xianghua Xiao <x.xiao@motorola.com>
* Adapted for Motorola 85xx chip.
*
* (C) Copyright 2003
* Gleb Natapov <gnatapov@mrv.com>
* Some bits are taken from linux driver writen by adrian@humboldt.co.uk
*
* Hardware I2C driver for MPC107 PCI bridge.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <asm/io.h>
#ifdef CONFIG_HARD_I2C
#include <i2c.h>
#define TIMEOUT (CFG_HZ/4)
#define I2C_Addr ((u8 *)(CFG_CCSRBAR + 0x3000))
#define I2CADR &I2C_Addr[0]
#define I2CFDR &I2C_Addr[4]
#define I2CCCR &I2C_Addr[8]
#define I2CCSR &I2C_Addr[12]
#define I2CCDR &I2C_Addr[16]
#define I2CDFSRR &I2C_Addr[20]
#define I2C_READ 1
#define I2C_WRITE 0
void
i2c_init(int speed, int slaveadd)
{
/* stop I2C controller */
writeb(0x0, I2CCCR);
/* set clock */
writeb(0x3f, I2CFDR);
/* set default filter */
writeb(0x10,I2CDFSRR);
/* write slave address */
writeb(slaveadd, I2CADR);
/* clear status register */
writeb(0x0, I2CCSR);
/* start I2C controller */
writeb(MPC85xx_I2CCR_MEN, I2CCCR);
}
static __inline__ int
i2c_wait4bus (void)
{
ulong timeval = get_timer (0);
while (readb(I2CCSR) & MPC85xx_I2CSR_MBB) {
if (get_timer (timeval) > TIMEOUT) {
return -1;
}
}
return 0;
}
static __inline__ int
i2c_wait (int write)
{
u32 csr;
ulong timeval = get_timer (0);
do {
csr = readb(I2CCSR);
if (!(csr & MPC85xx_I2CSR_MIF))
continue;
writeb(0x0, I2CCSR);
if (csr & MPC85xx_I2CSR_MAL) {
debug("i2c_wait: MAL\n");
return -1;
}
if (!(csr & MPC85xx_I2CSR_MCF)) {
debug("i2c_wait: unfinished\n");
return -1;
}
if (write == I2C_WRITE && (csr & MPC85xx_I2CSR_RXAK)) {
debug("i2c_wait: No RXACK\n");
return -1;
}
return 0;
} while (get_timer (timeval) < TIMEOUT);
debug("i2c_wait: timed out\n");
return -1;
}
static __inline__ int
i2c_write_addr (u8 dev, u8 dir, int rsta)
{
writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX |
(rsta?MPC85xx_I2CCR_RSTA:0),
I2CCCR);
writeb((dev << 1) | dir, I2CCDR);
if (i2c_wait (I2C_WRITE) < 0)
return 0;
return 1;
}
static __inline__ int
__i2c_write (u8 *data, int length)
{
int i;
writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX,
I2CCCR);
for (i=0; i < length; i++) {
writeb(data[i], I2CCDR);
if (i2c_wait (I2C_WRITE) < 0)
break;
}
return i;
}
static __inline__ int
__i2c_read (u8 *data, int length)
{
int i;
writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
((length == 1) ? MPC85xx_I2CCR_TXAK : 0),
I2CCCR);
/* dummy read */
readb(I2CCDR);
for (i=0; i < length; i++) {
if (i2c_wait (I2C_READ) < 0)
break;
/* Generate ack on last next to last byte */
if (i == length - 2)
writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
MPC85xx_I2CCR_TXAK,
I2CCCR);
/* Generate stop on last byte */
if (i == length - 1)
writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_TXAK, I2CCCR);
data[i] = readb(I2CCDR);
}
return i;
}
int
i2c_read (u8 dev, uint addr, int alen, u8 *data, int length)
{
int i = 0;
u8 *a = (u8*)&addr;
if (i2c_wait4bus () < 0)
goto exit;
if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
goto exit;
if (__i2c_write (&a[4 - alen], alen) != alen)
goto exit;
if (i2c_write_addr (dev, I2C_READ, 1) == 0)
goto exit;
i = __i2c_read (data, length);
exit:
writeb(MPC85xx_I2CCR_MEN, I2CCCR);
return !(i == length);
}
int
i2c_write (u8 dev, uint addr, int alen, u8 *data, int length)
{
int i = 0;
u8 *a = (u8*)&addr;
if (i2c_wait4bus () < 0)
goto exit;
if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
goto exit;
if (__i2c_write (&a[4 - alen], alen) != alen)
goto exit;
i = __i2c_write (data, length);
exit:
writeb(MPC85xx_I2CCR_MEN, I2CCCR);
return !(i == length);
}
int i2c_probe (uchar chip)
{
int tmp;
/*
* Try to read the first location of the chip. The underlying
* driver doesn't appear to support sending just the chip address
* and looking for an <ACK> back.
*/
udelay(10000);
return i2c_read (chip, 0, 1, (uchar *)&tmp, 1);
}
uchar i2c_reg_read (uchar i2c_addr, uchar reg)
{
uchar buf[1];
i2c_read (i2c_addr, reg, 1, buf, 1);
return (buf[0]);
}
void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
{
i2c_write (i2c_addr, reg, 1, &val, 1);
}
#endif /* CONFIG_HARD_I2C */

View File

@@ -29,20 +29,86 @@
#include <asm/cpm_85xx.h>
#include <pci.h>
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
#if defined(CONFIG_PCI)
static struct pci_controller *pci_hose;
void
pci_mpc85xx_init(struct pci_controller *hose)
pci_mpc85xx_init(struct pci_controller *board_hose)
{
u16 reg16;
u32 dev;
volatile immap_t *immap = (immap_t *)CFG_CCSRBAR;
volatile ccsr_pcix_t *pcix = &immap->im_pcix;
#ifdef CONFIG_MPC85XX_PCI2
volatile ccsr_pcix_t *pcix2 = &immap->im_pcix2;
#endif
volatile ccsr_gur_t *gur = &immap->im_gur;
struct pci_controller * hose;
u16 reg16;
pci_hose = board_hose;
hose = &pci_hose[0];
hose->first_busno = 0;
hose->last_busno = 0xff;
pci_setup_indirect(hose,
(CFG_IMMR+0x8000),
(CFG_IMMR+0x8004));
/*
* Hose scan.
*/
dev = PCI_BDF(hose->first_busno, 0, 0);
pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
*/
pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
if (!(gur->pordevsr & PORDEVSR_PCI)) {
/* PCI-X init */
if (CONFIG_SYS_CLK_FREQ < 66000000)
printf("PCI-X will only work at 66 MHz\n");
reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
| PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16);
}
pcix->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcix->potear1 = 0x00000000;
pcix->powbar1 = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff;
pcix->powbear1 = 0x00000000;
pcix->powar1 = (POWAR_EN | POWAR_MEM_READ |
POWAR_MEM_WRITE | POWAR_MEM_512M);
pcix->potar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
pcix->potear2 = 0x00000000;
pcix->powbar2 = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff;
pcix->powbear2 = 0x00000000;
pcix->powar2 = (POWAR_EN | POWAR_IO_READ |
POWAR_IO_WRITE | POWAR_IO_1M);
pcix->pitar1 = 0x00000000;
pcix->piwbar1 = 0x00000000;
pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
pcix->powar3 = 0;
pcix->powar4 = 0;
pcix->piwar2 = 0;
pcix->piwar3 = 0;
pci_set_region(hose->regions + 0,
CFG_PCI1_MEM_BASE,
CFG_PCI1_MEM_PHYS,
@@ -57,42 +123,8 @@ pci_mpc85xx_init(struct pci_controller *hose)
hose->region_count = 2;
pci_setup_indirect(hose,
(CFG_IMMR+0x8000),
(CFG_IMMR+0x8004));
pcix->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcix->potear1 = 0x00000000;
pcix->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcix->powbear1 = 0x00000000;
pcix->powar1 = 0x8004401c; /* 512M MEM space */
pcix->potar2 = 0x00000000;
pcix->potear2 = 0x00000000;
pcix->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
pcix->powbear2 = 0x00000000;
pcix->powar2 = 0x80088017; /* 16M IO space */
pcix->pitar1 = 0x00000000;
pcix->piwbar1 = 0x00000000;
pcix->piwar1 = 0xa0f5501e; /* Enable, Prefetch, Local Mem,
* Snoop R/W, 2G */
/*
* Hose scan.
*/
pci_register_hose(hose);
pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, &reg16);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
*/
pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff);
pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80);
#if defined(CONFIG_MPC8555CDS) || defined(CONFIG_MPC8541CDS)
/*
* This is a SW workaround for an apparent HW problem
@@ -117,6 +149,94 @@ pci_mpc85xx_init(struct pci_controller *hose)
#endif
hose->last_busno = pci_hose_scan(hose);
#ifdef CONFIG_MPC85XX_PCI2
hose = &pci_hose[1];
hose->first_busno = pci_hose[0].last_busno + 1;
hose->last_busno = 0xff;
pci_setup_indirect(hose,
(CFG_IMMR+0x9000),
(CFG_IMMR+0x9004));
dev = PCI_BDF(hose->first_busno, 0, 0);
pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
*/
pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
pcix2->potar1 = (CFG_PCI2_MEM_BASE >> 12) & 0x000fffff;
pcix2->potear1 = 0x00000000;
pcix2->powbar1 = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff;
pcix2->powbear1 = 0x00000000;
pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ |
POWAR_MEM_WRITE | POWAR_MEM_512M);
pcix2->potar2 = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff;
pcix2->potear2 = 0x00000000;
pcix2->powbar2 = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff;
pcix2->powbear2 = 0x00000000;
pcix2->powar2 = (POWAR_EN | POWAR_IO_READ |
POWAR_IO_WRITE | POWAR_IO_1M);
pcix2->pitar1 = 0x00000000;
pcix2->piwbar1 = 0x00000000;
pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
pcix2->powar3 = 0;
pcix2->powar4 = 0;
pcix2->piwar2 = 0;
pcix2->piwar3 = 0;
pci_set_region(hose->regions + 0,
CFG_PCI2_MEM_BASE,
CFG_PCI2_MEM_PHYS,
CFG_PCI2_MEM_SIZE,
PCI_REGION_MEM);
pci_set_region(hose->regions + 1,
CFG_PCI2_IO_BASE,
CFG_PCI2_IO_PHYS,
CFG_PCI2_IO_SIZE,
PCI_REGION_IO);
hose->region_count = 2;
/*
* Hose scan.
*/
pci_register_hose(hose);
hose->last_busno = pci_hose_scan(hose);
#endif
}
#ifdef CONFIG_OF_FLAT_TREE
void
ft_pci_setup(void *blob, bd_t *bd)
{
u32 *p;
int len;
p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8000/bus-range", &len);
if (p != NULL) {
p[0] = pci_hose[0].first_busno;
p[1] = pci_hose[0].last_busno;
}
#ifdef CONFIG_MPC85XX_PCI2
p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len);
if (p != NULL) {
p[0] = pci_hose[1].first_busno;
p[1] = pci_hose[1].last_busno;
}
#endif
}
#endif /* CONFIG_OF_FLAT_TREE */
#endif /* CONFIG_PCI */

View File

@@ -131,8 +131,8 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
800,
900,
250,
330, /* FIXME: Is 333 better/valid? */
660, /* FIXME: Is 667 better/valid? */
330,
660,
750,
0, /* undefined */
0 /* undefined */
@@ -146,6 +146,28 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
}
/*
* Determine Refresh Rate. Ignore self refresh bit on DDR I.
* Table from SPD Spec, Byte 12, converted to picoseconds and
* filled in with "default" normal values.
*/
unsigned int determine_refresh_rate(unsigned int spd_refresh)
{
unsigned int refresh_time_ns[8] = {
15625000, /* 0 Normal 1.00x */
3900000, /* 1 Reduced .25x */
7800000, /* 2 Extended .50x */
31300000, /* 3 Extended 2.00x */
62500000, /* 4 Extended 4.00x */
125000000, /* 5 Extended 8.00x */
15625000, /* 6 Normal 1.00x filler */
15625000, /* 7 Normal 1.00x filler */
};
return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]);
}
long int
spd_sdram(void)
{
@@ -157,6 +179,10 @@ spd_sdram(void)
unsigned int rank_density;
unsigned int odt_rd_cfg, odt_wr_cfg;
unsigned int odt_cfg, mode_odt_enable;
unsigned int refresh_clk;
#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
unsigned char clk_adjust;
#endif
unsigned int dqs_cfg;
unsigned char twr_clk, twtr_clk, twr_auto_clk;
unsigned int tCKmin_ps, tCKmax_ps;
@@ -740,38 +766,21 @@ spd_sdram(void)
ddr->sdram_mode_2 = 0;
debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
/*
* Determine Refresh Rate.
*/
refresh_clk = determine_refresh_rate(spd.refresh & 0x7);
/*
* Determine Refresh Rate. Ignore self refresh bit on DDR I.
* Table from SPD Spec, Byte 12, converted to picoseconds and
* filled in with "default" normal values.
* Set BSTOPRE to 0x100 for page mode
* If auto-charge is used, set BSTOPRE = 0
*/
{
unsigned int refresh_clk;
unsigned int refresh_time_ns[8] = {
15625000, /* 0 Normal 1.00x */
3900000, /* 1 Reduced .25x */
7800000, /* 2 Extended .50x */
31300000, /* 3 Extended 2.00x */
62500000, /* 4 Extended 4.00x */
125000000, /* 5 Extended 8.00x */
15625000, /* 6 Normal 1.00x filler */
15625000, /* 7 Normal 1.00x filler */
};
refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]);
/*
* Set BSTOPRE to 0x100 for page mode
* If auto-charge is used, set BSTOPRE = 0
*/
ddr->sdram_interval =
(0
| (refresh_clk & 0x3fff) << 16
| 0x100
);
debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
}
ddr->sdram_interval =
(0
| (refresh_clk & 0x3fff) << 16
| 0x100
);
debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
/*
* Is this an ECC DDR chip?
@@ -835,28 +844,23 @@ spd_sdram(void)
#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
{
unsigned char clk_adjust;
/*
* Setup the clock control.
* SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
* SDRAM_CLK_CNTL[5-7] = Clock Adjust
* 0110 3/4 cycle late
* 0111 7/8 cycle late
*/
if (spd.mem_type == SPD_MEMTYPE_DDR)
clk_adjust = 0x6;
else
clk_adjust = 0x7;
/*
* Setup the clock control.
* SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
* SDRAM_CLK_CNTL[5-7] = Clock Adjust
* 0110 3/4 cycle late
* 0111 7/8 cycle late
*/
if (spd.mem_type == SPD_MEMTYPE_DDR) {
clk_adjust = 0x6;
} else {
clk_adjust = 0x7;
}
ddr->sdram_clk_cntl = (0
ddr->sdram_clk_cntl = (0
| 0x80000000
| (clk_adjust << 23)
);
debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
}
debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
#endif
/*
@@ -1081,26 +1085,16 @@ ddr_enable_ecc(unsigned int dram_size)
}
}
/* 8K */
dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
/* 16K */
dma_xfer((uint *)0x4000, 0x4000, (uint *)0);
/* 32K */
dma_xfer((uint *)0x8000, 0x8000, (uint *)0);
/* 64K */
dma_xfer((uint *)0x10000, 0x10000, (uint *)0);
/* 128k */
dma_xfer((uint *)0x20000, 0x20000, (uint *)0);
/* 256k */
dma_xfer((uint *)0x40000, 0x40000, (uint *)0);
/* 512k */
dma_xfer((uint *)0x80000, 0x80000, (uint *)0);
/* 1M */
dma_xfer((uint *)0x100000, 0x100000, (uint *)0);
/* 2M */
dma_xfer((uint *)0x200000, 0x200000, (uint *)0);
/* 4M */
dma_xfer((uint *)0x400000, 0x400000, (uint *)0);
dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */
dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */
dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */
dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */
dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */
dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */
dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */
dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
for (i = 1; i < dram_size / 0x800000; i++) {
dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);

51
cpu/mpc86xx/Makefile Normal file
View File

@@ -0,0 +1,51 @@
#
# (C) Copyright 2002,2003 Motorola Inc.
# Xianghua Xiao,X.Xiao@motorola.com
#
# (C) Copyright 2004 Freescale Semiconductor. (MC86xx Port)
# Jeff Brown
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o #resetvec.o
SOBJS = cache.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
pci.o pcie_indirect.o spd_sdram.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $@ $(ASOBJS) $(OBJS)
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

374
cpu/mpc86xx/cache.S Normal file
View File

@@ -0,0 +1,374 @@
#include <config.h>
#include <mpc86xx.h>
#include <version.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#ifndef CACHE_LINE_SIZE
# define CACHE_LINE_SIZE L1_CACHE_BYTES
#endif
#if CACHE_LINE_SIZE == 128
#define LG_CACHE_LINE_SIZE 7
#elif CACHE_LINE_SIZE == 32
#define LG_CACHE_LINE_SIZE 5
#elif CACHE_LINE_SIZE == 16
#define LG_CACHE_LINE_SIZE 4
#elif CACHE_LINE_SIZE == 8
#define LG_CACHE_LINE_SIZE 3
#else
# error "Invalid cache line size!"
#endif
/*
* Most of this code is taken from 74xx_7xx/cache.S
* and then cleaned up a bit
*/
/*
* Invalidate L1 instruction cache.
*/
_GLOBAL(invalidate_l1_instruction_cache)
/* use invalidate-all bit in HID0 */
mfspr r3,HID0
ori r3,r3,HID0_ICFI
mtspr HID0,r3
isync
blr
/*
* Invalidate L1 data cache.
*/
_GLOBAL(invalidate_l1_data_cache)
mfspr r3,HID0
ori r3,r3,HID0_DCFI
mtspr HID0,r3
isync
blr
/*
* Flush data cache.
*/
_GLOBAL(flush_data_cache)
lis r3,0
lis r5,CACHE_LINE_SIZE
flush:
cmp 0,1,r3,r5
bge done
lwz r5,0(r3)
lis r5,CACHE_LINE_SIZE
addi r3,r3,0x4
b flush
done:
blr
/*
* Write any modified data cache blocks out to memory
* and invalidate the corresponding instruction cache blocks.
* This is a no-op on the 601.
*
* flush_icache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(flush_icache_range)
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,LG_CACHE_LINE_SIZE
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync /* wait for dcbst's to get to ram */
mtctr r4
2: icbi 0,r6
addi r6,r6,CACHE_LINE_SIZE
bdnz 2b
sync /* additional sync needed on g4 */
isync
blr
/*
* Write any modified data cache blocks out to memory.
* Does not invalidate the corresponding cache lines (especially for
* any corresponding instruction cache).
*
* clean_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(clean_dcache_range)
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5 /* align r3 down to cache line */
subf r4,r3,r4 /* r4 = offset of stop from start of cache line */
add r4,r4,r5 /* r4 += cache_line_size-1 */
srwi. r4,r4,LG_CACHE_LINE_SIZE /* r4 = number of cache lines to flush */
beqlr /* if r4 == 0 return */
mtctr r4 /* ctr = r4 */
sync
1: dcbst 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync /* wait for dcbst's to get to ram */
blr
/*
* Write any modified data cache blocks out to memory
* and invalidate the corresponding instruction cache blocks.
*
* flush_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(flush_dcache_range)
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,LG_CACHE_LINE_SIZE
beqlr
mtctr r4
sync
1: dcbf 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync /* wait for dcbf's to get to ram */
blr
/*
* Like above, but invalidate the D-cache. This is used by the 8xx
* to invalidate the cache so the PPC core doesn't get stale data
* from the CPM (no cache snooping here :-).
*
* invalidate_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(invalidate_dcache_range)
li r5,CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,LG_CACHE_LINE_SIZE
beqlr
mtctr r4
sync
1: dcbi 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync /* wait for dcbi's to get to ram */
blr
/*
* Flush a particular page from the data cache to RAM.
* Note: this is necessary because the instruction cache does *not*
* snoop from the data cache.
*
* void __flush_page_to_ram(void *page)
*/
_GLOBAL(__flush_page_to_ram)
rlwinm r3,r3,0,0,19 /* Get page base address */
li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
mtctr r4
mr r6,r3
0: dcbst 0,r3 /* Write line to ram */
addi r3,r3,CACHE_LINE_SIZE
bdnz 0b
sync
mtctr r4
1: icbi 0,r6
addi r6,r6,CACHE_LINE_SIZE
bdnz 1b
sync
isync
blr
/*
* Flush a particular page from the instruction cache.
* Note: this is necessary because the instruction cache does *not*
* snoop from the data cache.
*
* void __flush_icache_page(void *page)
*/
_GLOBAL(__flush_icache_page)
li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
mtctr r4
1: icbi 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
sync
isync
blr
/*
* Clear a page using the dcbz instruction, which doesn't cause any
* memory traffic (except to write out any cache lines which get
* displaced). This only works on cacheable memory.
*/
_GLOBAL(clear_page)
li r0,4096/CACHE_LINE_SIZE
mtctr r0
1: dcbz 0,r3
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
blr
/*
* Enable L1 Instruction cache
*/
_GLOBAL(icache_enable)
mfspr r3, HID0
li r5, HID0_ICFI|HID0_ILOCK
andc r3, r3, r5
ori r3, r3, HID0_ICE
ori r5, r3, HID0_ICFI
mtspr HID0, r5
mtspr HID0, r3
isync
blr
/*
* Disable L1 Instruction cache
*/
_GLOBAL(icache_disable)
mfspr r3, HID0
li r5, 0
ori r5, r5, HID0_ICE
andc r3, r3, r5
mtspr HID0, r3
isync
blr
/*
* Is instruction cache enabled?
*/
_GLOBAL(icache_status)
mfspr r3, HID0
andi. r3, r3, HID0_ICE
blr
_GLOBAL(l1dcache_enable)
mfspr r3, HID0
li r5, HID0_DCFI|HID0_DLOCK
andc r3, r3, r5
mtspr HID0, r3 /* no invalidate, unlock */
ori r3, r3, HID0_DCE
ori r5, r3, HID0_DCFI
mtspr HID0, r5 /* enable + invalidate */
mtspr HID0, r3 /* enable */
sync
blr
/*
* Enable data cache(s) - L1 and optionally L2
* Calls l2cache_enable. LR saved in r5
*/
_GLOBAL(dcache_enable)
mfspr r3, HID0
li r5, HID0_DCFI|HID0_DLOCK
andc r3, r3, r5
mtspr HID0, r3 /* no invalidate, unlock */
ori r3, r3, HID0_DCE
ori r5, r3, HID0_DCFI
mtspr HID0, r5 /* enable + invalidate */
mtspr HID0, r3 /* enable */
sync
#ifdef CFG_L2
mflr r5
bl l2cache_enable /* uses r3 and r4 */
sync
mtlr r5
#endif
blr
/*
* Disable data cache(s) - L1 and optionally L2
* Calls flush_data_cache and l2cache_disable_no_flush.
* LR saved in r4
*/
_GLOBAL(dcache_disable)
mflr r4 /* save link register */
bl flush_data_cache /* uses r3 and r5 */
sync
mfspr r3, HID0
li r5, HID0_DCFI|HID0_DLOCK
andc r3, r3, r5
mtspr HID0, r3 /* no invalidate, unlock */
li r5, HID0_DCE|HID0_DCFI
andc r3, r3, r5 /* no enable, no invalidate */
mtspr HID0, r3
sync
#ifdef CFG_L2
bl l2cache_disable_no_flush /* uses r3 */
#endif
mtlr r4 /* restore link register */
blr
/*
* Is data cache enabled?
*/
_GLOBAL(dcache_status)
mfspr r3, HID0
andi. r3, r3, HID0_DCE
blr
/*
* Invalidate L2 cache using L2I, assume L2 is enabled
*/
_GLOBAL(l2cache_invalidate)
mfspr r3, l2cr
rlwinm. r3, r3, 0, 0, 0
beq 1f
mfspr r3, l2cr
rlwinm r3, r3, 0, 1, 31
#ifdef CONFIG_ALTIVEC
dssall
#endif
sync
mtspr l2cr, r3
sync
1: mfspr r3, l2cr
oris r3, r3, L2CR_L2I@h
mtspr l2cr, r3
invl2:
mfspr r3, l2cr
andi. r3, r3, L2CR_L2I@h
bne invl2
blr
/*
* Enable L2 cache
* Calls l2cache_invalidate. LR is saved in r4
*/
_GLOBAL(l2cache_enable)
mflr r4 /* save link register */
bl l2cache_invalidate /* uses r3 */
sync
lis r3, L2_ENABLE@h
ori r3, r3, L2_ENABLE@l
mtspr l2cr, r3
isync
mtlr r4 /* restore link register */
blr
/*
* Disable L2 cache
* Calls flush_data_cache. LR is saved in r4
*/
_GLOBAL(l2cache_disable)
mflr r4 /* save link register */
bl flush_data_cache /* uses r3 and r5 */
sync
mtlr r4 /* restore link register */
l2cache_disable_no_flush: /* provide way to disable L2 w/o flushing */
lis r3, L2_INIT@h
ori r3, r3, L2_INIT@l
mtspr l2cr, r3
isync
blr

26
cpu/mpc86xx/config.mk Normal file
View File

@@ -0,0 +1,26 @@
#
# (C) Copyright 2004 Freescale Semiconductor.
# Jeff Brown
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
PLATFORM_CPPFLAGS += -DCONFIG_MPC86xx -ffixed-r2 -ffixed-r29 -mstring

308
cpu/mpc86xx/cpu.c Normal file
View File

@@ -0,0 +1,308 @@
/*
* Copyright 2006 Freescale Semiconductor
* Jeff Brown
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <asm/cache.h>
#include <mpc86xx.h>
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
#ifdef CONFIG_MPC8641HPCN
extern void mpc8641_reset_board(cmd_tbl_t *cmdtp, int flag,
int argc, char *argv[]);
#endif
int
checkcpu(void)
{
sys_info_t sysinfo;
uint pvr, svr;
uint ver;
uint major, minor;
uint lcrr; /* local bus clock ratio register */
uint clkdiv; /* clock divider portion of lcrr */
puts("Freescale PowerPC\n");
pvr = get_pvr();
ver = PVR_VER(pvr);
major = PVR_MAJ(pvr);
minor = PVR_MIN(pvr);
puts("CPU:\n");
puts(" Core: ");
switch (ver) {
case PVR_VER(PVR_86xx):
puts("E600");
break;
default:
puts("Unknown");
break;
}
printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
svr = get_svr();
ver = SVR_VER(svr);
major = SVR_MAJ(svr);
minor = SVR_MIN(svr);
puts(" System: ");
switch (ver) {
case SVR_8641:
if (SVR_SUBVER(svr) == 1) {
puts("8641D");
} else {
puts("8641");
}
break;
default:
puts("Unknown");
break;
}
printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
get_sys_info(&sysinfo);
puts(" Clocks: ");
printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);
printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000);
printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000);
#if defined(CFG_LBC_LCRR)
lcrr = CFG_LBC_LCRR;
#else
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile ccsr_lbc_t *lbc = &immap->im_lbc;
lcrr = lbc->lcrr;
}
#endif
clkdiv = lcrr & 0x0f;
if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
printf("LBC:%4lu MHz\n",
sysinfo.freqSystemBus / 1000000 / clkdiv);
} else {
printf(" LBC: unknown (lcrr: 0x%08x)\n", lcrr);
}
puts(" L2: ");
if (get_l2cr() & 0x80000000)
puts("Enabled\n");
else
puts("Disabled\n");
return 0;
}
static inline void
soft_restart(unsigned long addr)
{
#ifndef CONFIG_MPC8641HPCN
/*
* SRR0 has system reset vector, SRR1 has default MSR value
* rfi restores MSR from SRR1 and sets the PC to the SRR0 value
*/
__asm__ __volatile__ ("mtspr 26, %0" :: "r" (addr));
__asm__ __volatile__ ("li 4, (1 << 6)" ::: "r4");
__asm__ __volatile__ ("mtspr 27, 4");
__asm__ __volatile__ ("rfi");
#else /* CONFIG_MPC8641HPCN */
out8(PIXIS_BASE + PIXIS_RST, 0);
#endif /* !CONFIG_MPC8641HPCN */
while (1) ; /* not reached */
}
/*
* No generic way to do board reset. Simply call soft_reset.
*/
void
do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
#ifndef CONFIG_MPC8641HPCN
#ifdef CFG_RESET_ADDRESS
ulong addr = CFG_RESET_ADDRESS;
#else
/*
* note: when CFG_MONITOR_BASE points to a RAM address,
* CFG_MONITOR_BASE - sizeof (ulong) is usually a valid
* address. Better pick an address known to be invalid on your
* system and assign it to CFG_RESET_ADDRESS.
*/
ulong addr = CFG_MONITOR_BASE - sizeof(ulong);
#endif
/* flush and disable I/D cache */
__asm__ __volatile__ ("mfspr 3, 1008" ::: "r3");
__asm__ __volatile__ ("ori 5, 5, 0xcc00" ::: "r5");
__asm__ __volatile__ ("ori 4, 3, 0xc00" ::: "r4");
__asm__ __volatile__ ("andc 5, 3, 5" ::: "r5");
__asm__ __volatile__ ("sync");
__asm__ __volatile__ ("mtspr 1008, 4");
__asm__ __volatile__ ("isync");
__asm__ __volatile__ ("sync");
__asm__ __volatile__ ("mtspr 1008, 5");
__asm__ __volatile__ ("isync");
__asm__ __volatile__ ("sync");
soft_restart(addr);
#else /* CONFIG_MPC8641HPCN */
mpc8641_reset_board(cmdtp, flag, argc, argv);
#endif /* !CONFIG_MPC8641HPCN */
while (1) ; /* not reached */
}
/*
* Get timebase clock frequency
*/
unsigned long
get_tbclk(void)
{
sys_info_t sys_info;
get_sys_info(&sys_info);
return (sys_info.freqSystemBus + 3L) / 4L;
}
#if defined(CONFIG_WATCHDOG)
void
watchdog_reset(void)
{
}
#endif /* CONFIG_WATCHDOG */
#if defined(CONFIG_DDR_ECC)
void
dma_init(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile ccsr_dma_t *dma = &immap->im_dma;
dma->satr0 = 0x00040000;
dma->datr0 = 0x00040000;
asm("sync; isync");
}
uint
dma_check(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile ccsr_dma_t *dma = &immap->im_dma;
volatile uint status = dma->sr0;
/* While the channel is busy, spin */
while ((status & 4) == 4) {
status = dma->sr0;
}
if (status != 0) {
printf("DMA Error: status = %x\n", status);
}
return status;
}
int
dma_xfer(void *dest, uint count, void *src)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile ccsr_dma_t *dma = &immap->im_dma;
dma->dar0 = (uint) dest;
dma->sar0 = (uint) src;
dma->bcr0 = count;
dma->mr0 = 0xf000004;
asm("sync;isync");
dma->mr0 = 0xf000005;
asm("sync;isync");
return dma_check();
}
#endif /* CONFIG_DDR_ECC */
#ifdef CONFIG_OF_FLAT_TREE
void
ft_cpu_setup(void *blob, bd_t *bd)
{
u32 *p;
ulong clock;
int len;
clock = bd->bi_busfreq;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
#if defined(CONFIG_MPC86XX_TSEC1)
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
memcpy(p, bd->bi_enetaddr, 6);
#endif
#if defined(CONFIG_MPC86XX_TSEC2)
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
memcpy(p, bd->bi_enet1addr, 6);
#endif
#if defined(CONFIG_MPC86XX_TSEC3)
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
memcpy(p, bd->bi_enet2addr, 6);
#endif
#if defined(CONFIG_MPC86XX_TSEC4)
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
memcpy(p, bd->bi_enet3addr, 6);
#endif
}
#endif

117
cpu/mpc86xx/cpu_init.c Normal file
View File

@@ -0,0 +1,117 @@
/*
* Copyright 2004 Freescale Semiconductor.
* Jeff Brown
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* cpu_init.c - low level cpu init
*/
#include <common.h>
#include <mpc86xx.h>
/*
* Breathe some life into the CPU...
*
* Set up the memory map
* initialize a bunch of registers
*/
void cpu_init_f(void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ccsr_lbc_t *memctl = &immap->im_lbc;
/* Pointer is writable since we allocated a register for it */
gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
/* Clear initial global data */
memset ((void *) gd, 0, sizeof (gd_t));
/* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
* addresses - these have to be modified later when FLASH size
* has been determined
*/
#if defined(CFG_OR0_REMAP)
memctl->or0 = CFG_OR0_REMAP;
#endif
#if defined(CFG_OR1_REMAP)
memctl->or1 = CFG_OR1_REMAP;
#endif
/* now restrict to preliminary range */
#if defined(CFG_BR0_PRELIM) && defined(CFG_OR0_PRELIM)
memctl->br0 = CFG_BR0_PRELIM;
memctl->or0 = CFG_OR0_PRELIM;
#endif
#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM)
memctl->or1 = CFG_OR1_PRELIM;
memctl->br1 = CFG_BR1_PRELIM;
#endif
#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
memctl->or2 = CFG_OR2_PRELIM;
memctl->br2 = CFG_BR2_PRELIM;
#endif
#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM)
memctl->or3 = CFG_OR3_PRELIM;
memctl->br3 = CFG_BR3_PRELIM;
#endif
#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
memctl->or4 = CFG_OR4_PRELIM;
memctl->br4 = CFG_BR4_PRELIM;
#endif
#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
memctl->or5 = CFG_OR5_PRELIM;
memctl->br5 = CFG_BR5_PRELIM;
#endif
#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM)
memctl->or6 = CFG_OR6_PRELIM;
memctl->br6 = CFG_BR6_PRELIM;
#endif
#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM)
memctl->or7 = CFG_OR7_PRELIM;
memctl->br7 = CFG_BR7_PRELIM;
#endif
/* enable the timebase bit in HID0 */
set_hid0(get_hid0() | 0x4000000);
/* enable SYNCBE | ABE bits in HID1 */
set_hid1(get_hid1() | 0x00000C00);
}
/*
* initialize higher level parts of CPU like timers
*/
int cpu_init_r(void)
{
return 0;
}

204
cpu/mpc86xx/interrupts.c Normal file
View File

@@ -0,0 +1,204 @@
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2002 (440 port)
* Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
*
* (C) Copyright 2003 Motorola Inc. (MPC85xx port)
* Xianghua Xiao (X.Xiao@motorola.com)
*
* (C) Copyright 2004 Freescale Semiconductor. (MPC86xx Port)
* Jeff Brown
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc86xx.h>
#include <command.h>
#include <asm/processor.h>
#include <ppc_asm.tmpl>
unsigned long decrementer_count; /* count value for 1e6/HZ microseconds */
unsigned long timestamp;
static __inline__ unsigned long get_msr(void)
{
unsigned long msr;
asm volatile ("mfmsr %0":"=r" (msr):);
return msr;
}
static __inline__ void set_msr(unsigned long msr)
{
asm volatile ("mtmsr %0"::"r" (msr));
}
static __inline__ unsigned long get_dec(void)
{
unsigned long val;
asm volatile ("mfdec %0":"=r" (val):);
return val;
}
static __inline__ void set_dec(unsigned long val)
{
if (val)
asm volatile ("mtdec %0"::"r" (val));
}
/* interrupt is not supported yet */
int interrupt_init_cpu(unsigned *decrementer_count)
{
return 0;
}
int interrupt_init(void)
{
int ret;
/* call cpu specific function from $(CPU)/interrupts.c */
ret = interrupt_init_cpu(&decrementer_count);
if (ret)
return ret;
decrementer_count = get_tbclk() / CFG_HZ;
debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n",
(get_tbclk() / 1000000),
decrementer_count);
set_dec(decrementer_count);
set_msr(get_msr() | MSR_EE);
debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n",
get_msr(),
get_dec());
return 0;
}
void enable_interrupts(void)
{
set_msr(get_msr() | MSR_EE);
}
/* returns flag if MSR_EE was set before */
int disable_interrupts(void)
{
ulong msr = get_msr();
set_msr(msr & ~MSR_EE);
return (msr & MSR_EE) != 0;
}
void increment_timestamp(void)
{
timestamp++;
}
/*
* timer_interrupt - gets called when the decrementer overflows,
* with interrupts disabled.
* Trivial implementation - no need to be really accurate.
*/
void timer_interrupt_cpu(struct pt_regs *regs)
{
/* nothing to do here */
}
void timer_interrupt(struct pt_regs *regs)
{
/* call cpu specific function from $(CPU)/interrupts.c */
timer_interrupt_cpu(regs);
timestamp++;
ppcDcbf(&timestamp);
/* Restore Decrementer Count */
set_dec(decrementer_count);
#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0)
WATCHDOG_RESET();
#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
#ifdef CONFIG_STATUS_LED
status_led_tick(timestamp);
#endif /* CONFIG_STATUS_LED */
#ifdef CONFIG_SHOW_ACTIVITY
board_show_activity(timestamp);
#endif /* CONFIG_SHOW_ACTIVITY */
}
void reset_timer(void)
{
timestamp = 0;
}
ulong get_timer(ulong base)
{
return timestamp - base;
}
void set_timer(ulong t)
{
timestamp = t;
}
/*
* Install and free a interrupt handler. Not implemented yet.
*/
void irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
{
}
void irq_free_handler(int vec)
{
}
/*
* irqinfo - print information about PCI devices,not implemented.
*/
int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
printf("\nInterrupt-unsupported:\n");
return 0;
}
/*
* Handle external interrupts
*/
void external_interrupt(struct pt_regs *regs)
{
puts("external_interrupt (oops!)\n");
}

146
cpu/mpc86xx/pci.c Normal file
View File

@@ -0,0 +1,146 @@
/*
* Copyright (C) Freescale Semiconductor,Inc.
* 2005, 2006. All rights reserved.
*
* Ed Swarthout (ed.swarthout@freescale.com)
* Jason Jin (Jason.jin@freescale.com)
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* PCIE Configuration space access support for PCIE Bridge
*/
#include <common.h>
#include <pci.h>
#if defined(CONFIG_PCI)
void
pci_mpc86xx_init(struct pci_controller *hose)
{
volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
volatile ccsr_pex_t *pcie1 = &immap->im_pex1;
u16 temp16;
u32 temp32;
volatile ccsr_gur_t *gur = &immap->im_gur;
uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17;
uint pcie1_host = (host1_agent == 2) || (host1_agent == 3);
uint pcie1_agent = (host1_agent == 0) || (host1_agent == 1);
uint devdisr = gur->devdisr;
uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16;
if ((io_sel == 2 || io_sel == 3 || io_sel == 5 || io_sel == 6 ||
io_sel == 7 || io_sel == 0xf)
&& !(devdisr & MPC86xx_DEVDISR_PCIEX1)) {
printf("PCI-EXPRESS 1: Configured as %s \n",
pcie1_agent ? "Agent" : "Host");
if (pcie1_agent)
return; /*Don't scan bus when configured as agent */
printf(" Scanning PCIE bus");
debug("0x%08x=0x%08x ",
&pcie1->pme_msg_det,
pcie1->pme_msg_det);
if (pcie1->pme_msg_det) {
pcie1->pme_msg_det = 0xffffffff;
debug(" with errors. Clearing. Now 0x%08x",
pcie1->pme_msg_det);
}
debug("\n");
} else {
printf("PCI-EXPRESS 1 disabled!\n");
return;
}
/*
* Set first_bus=0 only skipped B0:D0:F0 which is
* a reserved device in M1575, but make it easy for
* most of the scan process.
*/
hose->first_busno = 0x00;
hose->last_busno = 0xfe;
pcie_setup_indirect(hose, (CFG_IMMR + 0x8000), (CFG_IMMR + 0x8004));
pci_hose_read_config_word(hose,
PCI_BDF(0, 0, 0), PCI_COMMAND, &temp16);
temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
pci_hose_write_config_word(hose,
PCI_BDF(0, 0, 0), PCI_COMMAND, temp16);
pci_hose_write_config_word(hose, PCI_BDF(0, 0, 0), PCI_STATUS, 0xffff);
pci_hose_write_config_byte(hose,
PCI_BDF(0, 0, 0), PCI_LATENCY_TIMER, 0x80);
pci_hose_read_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
&temp32);
temp32 = (temp32 & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
pci_hose_write_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
temp32);
pcie1->powar1 = 0;
pcie1->powar2 = 0;
pcie1->piwar1 = 0;
pcie1->piwar1 = 0;
pcie1->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcie1->powar1 = 0x8004401c; /* 512M MEM space */
pcie1->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcie1->potear1 = 0x00000000;
pcie1->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
pcie1->powar2 = 0x80088017; /* 16M IO space */
pcie1->potar2 = 0x00000000;
pcie1->potear2 = 0x00000000;
pcie1->pitar1 = 0x00000000;
pcie1->piwbar1 = 0x00000000;
/* Enable, Prefetch, Local Mem, * Snoop R/W, 2G */
pcie1->piwar1 = 0xa0f5501e;
pci_set_region(hose->regions + 0,
CFG_PCI_MEMORY_BUS,
CFG_PCI_MEMORY_PHYS,
CFG_PCI_MEMORY_SIZE,
PCI_REGION_MEM | PCI_REGION_MEMORY);
pci_set_region(hose->regions + 1,
CFG_PCI1_MEM_BASE,
CFG_PCI1_MEM_PHYS,
CFG_PCI1_MEM_SIZE,
PCI_REGION_MEM);
pci_set_region(hose->regions + 2,
CFG_PCI1_IO_BASE,
CFG_PCI1_IO_PHYS,
CFG_PCI1_IO_SIZE,
PCI_REGION_IO);
hose->region_count = 3;
pci_register_hose(hose);
hose->last_busno = pci_hose_scan(hose);
debug("pcie_mpc86xx_init: last_busno %x\n", hose->last_busno);
debug("pcie_mpc86xx init: current_busno %x\n ", hose->current_busno);
printf("....PCIE1 scan & enumeration done\n");
}
#endif /* CONFIG_PCI */

199
cpu/mpc86xx/pcie_indirect.c Normal file
View File

@@ -0,0 +1,199 @@
/*
* Support for indirect PCI bridges.
*
* Copyright (c) Freescale Semiconductor, Inc.
* 2006. All rights reserved.
*
* Jason Jin <Jason.jin@freescale.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* partly derived from
* arch/powerpc/platforms/86xx/mpc86xx_pcie.c
*/
#include <common.h>
#ifdef CONFIG_PCI
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
#define PCI_CFG_OUT out_be32
#define PEX_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff)
static int
indirect_read_config_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
int len,
u32 *val)
{
int bus = PCI_BUS(dev);
volatile unsigned char *cfg_data;
u32 temp;
PEX_FIX;
if (bus == 0xff) {
PCI_CFG_OUT(hose->cfg_addr,
dev | (offset & 0xfc) | 0x80000001);
} else {
PCI_CFG_OUT(hose->cfg_addr,
dev | (offset & 0xfc) | 0x80000000);
}
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
cfg_data = hose->cfg_data;
PEX_FIX;
temp = in_le32((u32 *) cfg_data);
switch (len) {
case 1:
*val = (temp >> (((offset & 3)) * 8)) & 0xff;
break;
case 2:
*val = (temp >> (((offset & 3)) * 8)) & 0xffff;
break;
default:
*val = temp;
break;
}
return 0;
}
static int
indirect_write_config_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
int len,
u32 val)
{
int bus = PCI_BUS(dev);
volatile unsigned char *cfg_data;
u32 temp;
PEX_FIX;
if (bus == 0xff) {
PCI_CFG_OUT(hose->cfg_addr,
dev | (offset & 0xfc) | 0x80000001);
} else {
PCI_CFG_OUT(hose->cfg_addr,
dev | (offset & 0xfc) | 0x80000000);
}
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
cfg_data = hose->cfg_data;
switch (len) {
case 1:
PEX_FIX;
temp = in_le32((u32 *) cfg_data);
temp = (temp & ~(0xff << ((offset & 3) * 8))) |
(val << ((offset & 3) * 8));
PEX_FIX;
out_le32((u32 *) cfg_data, temp);
break;
case 2:
PEX_FIX;
temp = in_le32((u32 *) cfg_data);
temp = (temp & ~(0xffff << ((offset & 3) * 8)));
temp |= (val << ((offset & 3) * 8));
PEX_FIX;
out_le32((u32 *) cfg_data, temp);
break;
default:
PEX_FIX;
out_le32((u32 *) cfg_data, val);
break;
}
PEX_FIX;
return 0;
}
static int
indirect_read_config_byte_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u8 *val)
{
u32 val32;
indirect_read_config_pcie(hose, dev, offset, 1, &val32);
*val = (u8) val32;
return 0;
}
static int
indirect_read_config_word_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u16 *val)
{
u32 val32;
indirect_read_config_pcie(hose, dev, offset, 2, &val32);
*val = (u16) val32;
return 0;
}
static int
indirect_read_config_dword_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u32 *val)
{
return indirect_read_config_pcie(hose, dev, offset, 4, val);
}
static int
indirect_write_config_byte_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u8 val)
{
return indirect_write_config_pcie(hose, dev, offset, 1, (u32) val);
}
static int
indirect_write_config_word_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
unsigned short val)
{
return indirect_write_config_pcie(hose, dev, offset, 2, (u32) val);
}
static int
indirect_write_config_dword_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u32 val)
{
return indirect_write_config_pcie(hose, dev, offset, 4, val);
}
void
pcie_setup_indirect(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data)
{
pci_set_ops(hose,
indirect_read_config_byte_pcie,
indirect_read_config_word_pcie,
indirect_read_config_dword_pcie,
indirect_write_config_byte_pcie,
indirect_write_config_word_pcie,
indirect_write_config_dword_pcie);
hose->cfg_addr = (unsigned int *)cfg_addr;
hose->cfg_data = (unsigned char *)cfg_data;
}
#endif /* CONFIG_PCI */

2
cpu/mpc86xx/resetvec.S Normal file
View File

@@ -0,0 +1,2 @@
.section .resetvec,"ax"
b _start

1320
cpu/mpc86xx/spd_sdram.c Normal file

File diff suppressed because it is too large Load Diff

127
cpu/mpc86xx/speed.c Normal file
View File

@@ -0,0 +1,127 @@
/*
* Copyright 2004 Freescale Semiconductor.
* Jeff Brown
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc86xx.h>
#include <asm/processor.h>
void get_sys_info(sys_info_t *sysInfo)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile ccsr_gur_t *gur = &immap->im_gur;
uint plat_ratio, e600_ratio;
plat_ratio = (gur->porpllsr) & 0x0000003e;
plat_ratio >>= 1;
switch (plat_ratio) {
case 0x0:
sysInfo->freqSystemBus = 16 * CONFIG_SYS_CLK_FREQ;
break;
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x08:
case 0x09:
case 0x0a:
case 0x0c:
case 0x10:
sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ;
break;
default:
sysInfo->freqSystemBus = 0;
break;
}
e600_ratio = (gur->porpllsr) & 0x003f0000;
e600_ratio >>= 16;
switch (e600_ratio) {
case 0x10:
sysInfo->freqProcessor = 2 * sysInfo->freqSystemBus;
break;
case 0x19:
sysInfo->freqProcessor = 5 * sysInfo->freqSystemBus / 2;
break;
case 0x20:
sysInfo->freqProcessor = 3 * sysInfo->freqSystemBus;
break;
case 0x39:
sysInfo->freqProcessor = 7 * sysInfo->freqSystemBus / 2;
break;
case 0x28:
sysInfo->freqProcessor = 4 * sysInfo->freqSystemBus;
break;
case 0x1d:
sysInfo->freqProcessor = 9 * sysInfo->freqSystemBus / 2;
break;
default:
sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus;
break;
}
}
/*
* Measure CPU clock speed (core clock GCLK1, GCLK2)
* (Approx. GCLK frequency in Hz)
*/
int get_clocks(void)
{
DECLARE_GLOBAL_DATA_PTR;
sys_info_t sys_info;
get_sys_info(&sys_info);
gd->cpu_clk = sys_info.freqProcessor;
gd->bus_clk = sys_info.freqSystemBus;
if (gd->cpu_clk != 0)
return 0;
else
return 1;
}
/*
* get_bus_freq
* Return system bus freq in Hz
*/
ulong get_bus_freq(ulong dummy)
{
ulong val;
sys_info_t sys_info;
get_sys_info(&sys_info);
val = sys_info.freqSystemBus;
return val;
}

1226
cpu/mpc86xx/start.S Normal file

File diff suppressed because it is too large Load Diff

226
cpu/mpc86xx/traps.c Normal file
View File

@@ -0,0 +1,226 @@
/*
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Modified by Cort Dougan (cort@cs.nmt.edu)
* and Paul Mackerras (paulus@cs.anu.edu.au)
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* This file handles the architecture-dependent parts of hardware exceptions
*/
#include <common.h>
#include <command.h>
#include <asm/processor.h>
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
int (*debugger_exception_handler)(struct pt_regs *) = 0;
#endif
/* Returns 0 if exception not found and fixup otherwise. */
extern unsigned long search_exception_table(unsigned long);
#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize)
/*
* Trap & Exception support
*/
void
print_backtrace(unsigned long *sp)
{
DECLARE_GLOBAL_DATA_PTR;
int cnt = 0;
unsigned long i;
printf("Call backtrace: ");
while (sp) {
if ((uint) sp > END_OF_MEM)
break;
i = sp[1];
if (cnt++ % 7 == 0)
printf("\n");
printf("%08lX ", i);
if (cnt > 32)
break;
sp = (unsigned long *)*sp;
}
printf("\n");
}
void
show_regs(struct pt_regs *regs)
{
int i;
printf("NIP: %08lX XER: %08lX LR: %08lX REGS:"
" %p TRAP: %04lx DAR: %08lX\n",
regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
printf("MSR: %08lx EE: %01x PR: %01x FP:"
" %01x ME: %01x IR/DR: %01x%01x\n",
regs->msr, regs->msr & MSR_EE ? 1 : 0,
regs->msr & MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,
regs->msr & MSR_ME ? 1 : 0, regs->msr & MSR_IR ? 1 : 0,
regs->msr & MSR_DR ? 1 : 0);
printf("\n");
for (i = 0; i < 32; i++) {
if ((i % 8) == 0) {
printf("GPR%02d: ", i);
}
printf("%08lX ", regs->gpr[i]);
if ((i % 8) == 7) {
printf("\n");
}
}
}
void
_exception(int signr, struct pt_regs *regs)
{
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Exception in kernel pc %lx signal %d", regs->nip, signr);
}
void
MachineCheckException(struct pt_regs *regs)
{
unsigned long fixup;
/* Probing PCI using config cycles cause this exception
* when a device is not present. Catch it and return to
* the PCI exception handler.
*/
if ((fixup = search_exception_table(regs->nip)) != 0) {
regs->nip = fixup;
return;
}
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler) (regs))
return;
#endif
printf("Machine check in kernel mode.\n");
printf("Caused by (from msr): ");
printf("regs %p ", regs);
switch (regs->msr & 0x000F0000) {
case (0x80000000 >> 12):
printf("Machine check signal - probably due to mm fault\n"
"with mmu off\n");
break;
case (0x80000000 >> 13):
printf("Transfer error ack signal\n");
break;
case (0x80000000 >> 14):
printf("Data parity signal\n");
break;
case (0x80000000 >> 15):
printf("Address parity signal\n");
break;
default:
printf("Unknown values in msr\n");
}
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("machine check");
}
void
AlignmentException(struct pt_regs *regs)
{
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler) (regs))
return;
#endif
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Alignment Exception");
}
void
ProgramCheckException(struct pt_regs *regs)
{
unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL;
int i, j;
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler) (regs))
return;
#endif
show_regs(regs);
p = (unsigned char *)((unsigned long)p & 0xFFFFFFE0);
p -= 32;
for (i = 0; i < 256; i += 16) {
printf("%08x: ", (unsigned int)p + i);
for (j = 0; j < 16; j++) {
printf("%02x ", p[i + j]);
}
printf("\n");
}
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Program Check Exception");
}
void
SoftEmuException(struct pt_regs *regs)
{
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler) (regs))
return;
#endif
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Software Emulation Exception");
}
void
UnknownException(struct pt_regs *regs)
{
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler) (regs))
return;
#endif
printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
regs->nip, regs->msr, regs->trap);
_exception(0, regs);
}
/*
* Probe an address by reading.
* If not present, return -1,
* otherwise return 0.
*/
int
addr_probe(uint *addr)
{
return 0;
}

View File

@@ -41,7 +41,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS) $(obj)kgdb.o
$(AR) $(ARFLAGS) $@ $(OBJS) $(obj)kgdb.o
#########################################################################

View File

@@ -36,7 +36,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -36,7 +36,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -41,7 +41,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -196,6 +196,7 @@ int checkcpu (void)
char buf[32];
#if !defined(CONFIG_IOP480)
char addstr[64] = "";
sys_info_t sys_info;
puts ("CPU: ");
@@ -312,19 +313,23 @@ int checkcpu (void)
#endif /* CONFIG_440 */
case PVR_440EPX1_RA:
puts("EPx Rev. A - Security/Kasumi support");
puts("EPx Rev. A");
strcpy(addstr, "Security/Kasumi support");
break;
case PVR_440EPX2_RA:
puts("EPx Rev. A - No Security/Kasumi support");
puts("EPx Rev. A");
strcpy(addstr, "No Security/Kasumi support");
break;
case PVR_440GRX1_RA:
puts("GRx Rev. A - Security/Kasumi support");
puts("GRx Rev. A");
strcpy(addstr, "Security/Kasumi support");
break;
case PVR_440GRX2_RA:
puts("GRx Rev. A - No Security/Kasumi support");
puts("GRx Rev. A");
strcpy(addstr, "No Security/Kasumi support");
break;
case PVR_440SP_RA:
@@ -353,13 +358,16 @@ int checkcpu (void)
sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
FREQ_EBC / 1000000);
if (addstr[0] != 0)
printf(" %s\n", addstr);
#if defined(I2C_BOOTROM)
printf (" I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
#if defined(SDR0_PINSTP_SHIFT)
printf (" Bootstrap Option %c - ", (char)bootstrap_option() + 'A');
printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
#endif
#endif
#endif /* SDR0_PINSTP_SHIFT */
#endif /* I2C_BOOTROM */
#if defined(CONFIG_PCI)
printf (" Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");

View File

@@ -226,13 +226,19 @@ cpu_init_f (void)
/*
* GPIO0 setup (select GPIO or alternate function)
*/
out32(GPIO0_OSRH, CFG_GPIO0_OSRH); /* output select */
#if defined(CFG_GPIO0_OR)
out32(GPIO0_OR, CFG_GPIO0_OR); /* set initial state of output pins */
#endif
#if defined(CFG_GPIO0_ODR)
out32(GPIO0_ODR, CFG_GPIO0_ODR); /* open-drain select */
#endif
out32(GPIO0_OSRH, CFG_GPIO0_OSRH); /* output select */
out32(GPIO0_OSRL, CFG_GPIO0_OSRL);
out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
out32(GPIO0_TSRH, CFG_GPIO0_TSRH); /* three-state select */
out32(GPIO0_TSRH, CFG_GPIO0_TSRH); /* three-state select */
out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
out32(GPIO0_TCR, CFG_GPIO0_TCR); /* enable output driver for outputs */
out32(GPIO0_TCR, CFG_GPIO0_TCR); /* enable output driver for outputs */
/*
* Set EMAC noise filter bits

View File

@@ -65,8 +65,8 @@ static void ndfc_hwcontrol(struct mtd_info *mtdinfo, int cmd)
static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
{
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W;
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
if (hwctl & 0x1)
out8(base + NDFC_CMD, byte);
@@ -78,16 +78,16 @@ static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
{
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W;
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
return (in8(base + NDFC_DATA));
}
static int ndfc_dev_ready(struct mtd_info *mtdinfo)
{
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W;
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY))
;
@@ -110,31 +110,31 @@ static int ndfc_dev_ready(struct mtd_info *mtdinfo)
*/
static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
{
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W;
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
uint32_t *p = (uint32_t *) buf;
for(;len > 0; len -= 4)
for (;len > 0; len -= 4)
*p++ = in32(base + NDFC_DATA);
}
static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
{
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W;
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
uint32_t *p = (uint32_t *) buf;
for(; len > 0; len -= 4)
for (; len > 0; len -= 4)
out32(base + NDFC_DATA, *p++);
}
static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
{
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W;
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
uint32_t *p = (uint32_t *) buf;
for(; len > 0; len -= 4)
for (; len > 0; len -= 4)
if (*p++ != in32(base + NDFC_DATA))
return -1;
@@ -142,8 +142,25 @@ static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len
}
#endif /* #ifndef CONFIG_NAND_SPL */
void board_nand_select_device(struct nand_chip *nand, int chip)
{
/*
* Don't use "chip" to address the NAND device,
* generate the cs from the address where it is encoded.
*/
int cs = (ulong)nand->IO_ADDR_W & 0x00000003;
ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
/* Set NandFlash Core Configuration Register */
/* 1col x 2 rows */
out32(base + NDFC_CCR, 0x00000000 | (cs << 24));
}
void board_nand_init(struct nand_chip *nand)
{
int cs = (ulong)nand->IO_ADDR_W & 0x00000003;
ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
nand->eccmode = NAND_ECC_SOFT;
nand->hwcontrol = ndfc_hwcontrol;
@@ -166,10 +183,11 @@ void board_nand_init(struct nand_chip *nand)
mtebc(pb0ap, CFG_EBC_PB0AP);
#endif
/* Set NandFlash Core Configuration Register */
/* Chip select 3, 1col x 2 rows */
out32(CFG_NAND_BASE + NDFC_CCR, 0x00000000 | (CFG_NAND_CS << 24));
out32(CFG_NAND_BASE + NDFC_BCFG0 + (CFG_NAND_CS << 2), 0x80002222);
/*
* Select required NAND chip in NDFC
*/
board_nand_select_device(nand, cs);
out32(base + NDFC_BCFG0 + (cs << 2), 0x80002222);
}
#endif

View File

@@ -173,9 +173,9 @@
/**************************************************************************/
_start_440:
/*--------------------------------------------------------------------+
| 440EPX BUP Change - Hardware team request
+--------------------------------------------------------------------*/
/*--------------------------------------------------------------------+
| 440EPX BUP Change - Hardware team request
+--------------------------------------------------------------------*/
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
sync
nop
@@ -1697,7 +1697,8 @@ ppc405ep_init:
mtdcr ebccfgd,r3
#endif
addi r3,0,CPC0_PCI_HOST_CFG_EN
#ifndef CFG_CPC0_PCI
li r3,CPC0_PCI_HOST_CFG_EN
#ifdef CONFIG_BUBINGA
/*
!-----------------------------------------------------------------------
@@ -1712,6 +1713,9 @@ ppc405ep_init:
beq ..pci_cfg_set /* if not set, then bypass reg write*/
#endif
ori r3,r3,CPC0_PCI_ARBIT_EN
#else /* CFG_CPC0_PCI */
li r3,CFG_CPC0_PCI
#endif /* CFG_CPC0_PCI */
..pci_cfg_set:
mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################

View File

@@ -35,7 +35,7 @@ START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################