mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-09 01:28:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
41
arch/m68k/coldfire/Makefile
Normal file
41
arch/m68k/coldfire/Makefile
Normal file
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# Makefile for the m68knommu kernel.
|
||||
#
|
||||
|
||||
#
|
||||
# If you want to play with the HW breakpoints then you will
|
||||
# need to add define this, which will give you a stack backtrace
|
||||
# on the console port whenever a DBG interrupt occurs. You have to
|
||||
# set up you HW breakpoints to trigger a DBG interrupt:
|
||||
#
|
||||
# ccflags-y := -DTRAP_DBG_INTERRUPT
|
||||
# asflags-y := -DTRAP_DBG_INTERRUPT
|
||||
#
|
||||
|
||||
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
|
||||
|
||||
obj-$(CONFIG_COLDFIRE) += cache.o clk.o device.o dma.o entry.o vectors.o
|
||||
obj-$(CONFIG_M5206) += m5206.o timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M5206e) += m5206.o timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M520x) += m520x.o pit.o intc-simr.o reset.o
|
||||
obj-$(CONFIG_M523x) += m523x.o pit.o dma_timer.o intc-2.o reset.o
|
||||
obj-$(CONFIG_M5249) += m5249.o timers.o intc.o intc-5249.o reset.o
|
||||
obj-$(CONFIG_M525x) += m525x.o timers.o intc.o intc-525x.o reset.o
|
||||
obj-$(CONFIG_M527x) += m527x.o pit.o intc-2.o reset.o
|
||||
obj-$(CONFIG_M5272) += m5272.o intc-5272.o timers.o
|
||||
obj-$(CONFIG_M528x) += m528x.o pit.o intc-2.o reset.o
|
||||
obj-$(CONFIG_M5307) += m5307.o timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M53xx) += m53xx.o timers.o intc-simr.o reset.o
|
||||
obj-$(CONFIG_M5407) += m5407.o timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M54xx) += m54xx.o sltimers.o intc-2.o
|
||||
obj-$(CONFIG_M5441x) += m5441x.o pit.o intc-simr.o reset.o
|
||||
|
||||
obj-$(CONFIG_NETtel) += nettel.o
|
||||
obj-$(CONFIG_CLEOPATRA) += nettel.o
|
||||
obj-$(CONFIG_FIREBEE) += firebee.o
|
||||
obj-$(CONFIG_MCF8390) += mcf8390.o
|
||||
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
|
||||
obj-y += gpio.o
|
||||
extra-y := head.o
|
48
arch/m68k/coldfire/cache.c
Normal file
48
arch/m68k/coldfire/cache.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* cache.c -- general ColdFire Cache maintenance code
|
||||
*
|
||||
* Copyright (C) 2010, Greg Ungerer (gerg@snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
/***************************************************************************/
|
||||
#ifdef CACHE_PUSH
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Use cpushl to push all dirty cache lines back to memory.
|
||||
* Older versions of GAS don't seem to know how to generate the
|
||||
* ColdFire cpushl instruction... Oh well, bit stuff it for now.
|
||||
*/
|
||||
|
||||
void mcf_cache_push(void)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"clrl %%d0\n\t"
|
||||
"1:\n\t"
|
||||
"movel %%d0,%%a0\n\t"
|
||||
"2:\n\t"
|
||||
".word 0xf468\n\t"
|
||||
"addl %0,%%a0\n\t"
|
||||
"cmpl %1,%%a0\n\t"
|
||||
"blt 2b\n\t"
|
||||
"addql #1,%%d0\n\t"
|
||||
"cmpil %2,%%d0\n\t"
|
||||
"bne 1b\n\t"
|
||||
: /* No output */
|
||||
: "i" (CACHE_LINE_SIZE),
|
||||
"i" (DCACHE_SIZE / CACHE_WAYS),
|
||||
"i" (CACHE_WAYS)
|
||||
: "d0", "a0" );
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
#endif /* CACHE_PUSH */
|
||||
/***************************************************************************/
|
124
arch/m68k/coldfire/clk.c
Normal file
124
arch/m68k/coldfire/clk.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* clk.c -- general ColdFire CPU kernel clk handling
|
||||
*
|
||||
* Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
static DEFINE_SPINLOCK(clk_lock);
|
||||
|
||||
#ifdef MCFPM_PPMCR0
|
||||
/*
|
||||
* For more advanced ColdFire parts that have clocks that can be enabled
|
||||
* we supply enable/disable functions. These must properly define their
|
||||
* clocks in their platform specific code.
|
||||
*/
|
||||
void __clk_init_enabled(struct clk *clk)
|
||||
{
|
||||
clk->enabled = 1;
|
||||
clk->clk_ops->enable(clk);
|
||||
}
|
||||
|
||||
void __clk_init_disabled(struct clk *clk)
|
||||
{
|
||||
clk->enabled = 0;
|
||||
clk->clk_ops->disable(clk);
|
||||
}
|
||||
|
||||
static void __clk_enable0(struct clk *clk)
|
||||
{
|
||||
__raw_writeb(clk->slot, MCFPM_PPMCR0);
|
||||
}
|
||||
|
||||
static void __clk_disable0(struct clk *clk)
|
||||
{
|
||||
__raw_writeb(clk->slot, MCFPM_PPMSR0);
|
||||
}
|
||||
|
||||
struct clk_ops clk_ops0 = {
|
||||
.enable = __clk_enable0,
|
||||
.disable = __clk_disable0,
|
||||
};
|
||||
|
||||
#ifdef MCFPM_PPMCR1
|
||||
static void __clk_enable1(struct clk *clk)
|
||||
{
|
||||
__raw_writeb(clk->slot, MCFPM_PPMCR1);
|
||||
}
|
||||
|
||||
static void __clk_disable1(struct clk *clk)
|
||||
{
|
||||
__raw_writeb(clk->slot, MCFPM_PPMSR1);
|
||||
}
|
||||
|
||||
struct clk_ops clk_ops1 = {
|
||||
.enable = __clk_enable1,
|
||||
.disable = __clk_disable1,
|
||||
};
|
||||
#endif /* MCFPM_PPMCR1 */
|
||||
#endif /* MCFPM_PPMCR0 */
|
||||
|
||||
struct clk *clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
const char *clk_name = dev ? dev_name(dev) : id ? id : NULL;
|
||||
struct clk *clk;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; (clk = mcf_clks[i]) != NULL; ++i)
|
||||
if (!strcmp(clk->name, clk_name))
|
||||
return clk;
|
||||
pr_warn("clk_get: didn't find clock %s\n", clk_name);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get);
|
||||
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
if ((clk->enabled++ == 0) && clk->clk_ops)
|
||||
clk->clk_ops->enable(clk);
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_enable);
|
||||
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
if ((--clk->enabled == 0) && clk->clk_ops)
|
||||
clk->clk_ops->disable(clk);
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_disable);
|
||||
|
||||
void clk_put(struct clk *clk)
|
||||
{
|
||||
if (clk->enabled != 0)
|
||||
pr_warn("clk_put %s still enabled\n", clk->name);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_put);
|
||||
|
||||
unsigned long clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return clk->rate;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_rate);
|
||||
|
||||
/***************************************************************************/
|
369
arch/m68k/coldfire/device.c
Normal file
369
arch/m68k/coldfire/device.c
Normal file
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* device.c -- common ColdFire SoC device support
|
||||
*
|
||||
* (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/fec.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/*
|
||||
* All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
|
||||
*/
|
||||
static struct mcf_platform_uart mcf_uart_platform_data[] = {
|
||||
{
|
||||
.mapbase = MCFUART_BASE0,
|
||||
.irq = MCF_IRQ_UART0,
|
||||
},
|
||||
{
|
||||
.mapbase = MCFUART_BASE1,
|
||||
.irq = MCF_IRQ_UART1,
|
||||
},
|
||||
#ifdef MCFUART_BASE2
|
||||
{
|
||||
.mapbase = MCFUART_BASE2,
|
||||
.irq = MCF_IRQ_UART2,
|
||||
},
|
||||
#endif
|
||||
#ifdef MCFUART_BASE3
|
||||
{
|
||||
.mapbase = MCFUART_BASE3,
|
||||
.irq = MCF_IRQ_UART3,
|
||||
},
|
||||
#endif
|
||||
#ifdef MCFUART_BASE4
|
||||
{
|
||||
.mapbase = MCFUART_BASE4,
|
||||
.irq = MCF_IRQ_UART4,
|
||||
},
|
||||
#endif
|
||||
#ifdef MCFUART_BASE5
|
||||
{
|
||||
.mapbase = MCFUART_BASE5,
|
||||
.irq = MCF_IRQ_UART5,
|
||||
},
|
||||
#endif
|
||||
#ifdef MCFUART_BASE6
|
||||
{
|
||||
.mapbase = MCFUART_BASE6,
|
||||
.irq = MCF_IRQ_UART6,
|
||||
},
|
||||
#endif
|
||||
#ifdef MCFUART_BASE7
|
||||
{
|
||||
.mapbase = MCFUART_BASE7,
|
||||
.irq = MCF_IRQ_UART7,
|
||||
},
|
||||
#endif
|
||||
#ifdef MCFUART_BASE8
|
||||
{
|
||||
.mapbase = MCFUART_BASE8,
|
||||
.irq = MCF_IRQ_UART8,
|
||||
},
|
||||
#endif
|
||||
#ifdef MCFUART_BASE9
|
||||
{
|
||||
.mapbase = MCFUART_BASE9,
|
||||
.irq = MCF_IRQ_UART9,
|
||||
},
|
||||
#endif
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device mcf_uart = {
|
||||
.name = "mcfuart",
|
||||
.id = 0,
|
||||
.dev.platform_data = mcf_uart_platform_data,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_FEC
|
||||
|
||||
#ifdef CONFIG_M5441x
|
||||
#define FEC_NAME "enet-fec"
|
||||
static struct fec_platform_data fec_pdata = {
|
||||
.phy = PHY_INTERFACE_MODE_RMII,
|
||||
};
|
||||
#define FEC_PDATA (&fec_pdata)
|
||||
#else
|
||||
#define FEC_NAME "fec"
|
||||
#define FEC_PDATA NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some ColdFire cores contain the Fast Ethernet Controller (FEC)
|
||||
* block. It is Freescale's own hardware block. Some ColdFires
|
||||
* have 2 of these.
|
||||
*/
|
||||
static struct resource mcf_fec0_resources[] = {
|
||||
{
|
||||
.start = MCFFEC_BASE0,
|
||||
.end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_FECRX0,
|
||||
.end = MCF_IRQ_FECRX0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_FECTX0,
|
||||
.end = MCF_IRQ_FECTX0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_FECENTC0,
|
||||
.end = MCF_IRQ_FECENTC0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mcf_fec0 = {
|
||||
.name = FEC_NAME,
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mcf_fec0_resources),
|
||||
.resource = mcf_fec0_resources,
|
||||
.dev.platform_data = FEC_PDATA,
|
||||
};
|
||||
|
||||
#ifdef MCFFEC_BASE1
|
||||
static struct resource mcf_fec1_resources[] = {
|
||||
{
|
||||
.start = MCFFEC_BASE1,
|
||||
.end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_FECRX1,
|
||||
.end = MCF_IRQ_FECRX1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_FECTX1,
|
||||
.end = MCF_IRQ_FECTX1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_FECENTC1,
|
||||
.end = MCF_IRQ_FECENTC1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mcf_fec1 = {
|
||||
.name = FEC_NAME,
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(mcf_fec1_resources),
|
||||
.resource = mcf_fec1_resources,
|
||||
.dev.platform_data = FEC_PDATA,
|
||||
};
|
||||
#endif /* MCFFEC_BASE1 */
|
||||
#endif /* CONFIG_FEC */
|
||||
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
/*
|
||||
* The ColdFire QSPI module is an SPI protocol hardware block used
|
||||
* on a number of different ColdFire CPUs.
|
||||
*/
|
||||
static struct resource mcf_qspi_resources[] = {
|
||||
{
|
||||
.start = MCFQSPI_BASE,
|
||||
.end = MCFQSPI_BASE + MCFQSPI_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_QSPI,
|
||||
.end = MCF_IRQ_QSPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
||||
goto fail0;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
#ifdef MCFQSPI_CS3
|
||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
goto fail3;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
fail3:
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
fail2:
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
fail1:
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
fail0:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
#ifdef MCFQSPI_CS3
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
#endif
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
}
|
||||
|
||||
static void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
||||
break;
|
||||
#ifdef MCFQSPI_CS3
|
||||
case 3:
|
||||
gpio_set_value(MCFQSPI_CS3, cs_high);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
||||
break;
|
||||
#ifdef MCFQSPI_CS3
|
||||
case 3:
|
||||
gpio_set_value(MCFQSPI_CS3, !cs_high);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static struct mcfqspi_cs_control mcf_cs_control = {
|
||||
.setup = mcf_cs_setup,
|
||||
.teardown = mcf_cs_teardown,
|
||||
.select = mcf_cs_select,
|
||||
.deselect = mcf_cs_deselect,
|
||||
};
|
||||
|
||||
static struct mcfqspi_platform_data mcf_qspi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 4,
|
||||
.cs_control = &mcf_cs_control,
|
||||
};
|
||||
|
||||
static struct platform_device mcf_qspi = {
|
||||
.name = "mcfqspi",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mcf_qspi_resources),
|
||||
.resource = mcf_qspi_resources,
|
||||
.dev.platform_data = &mcf_qspi_data,
|
||||
};
|
||||
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
|
||||
|
||||
static struct platform_device *mcf_devices[] __initdata = {
|
||||
&mcf_uart,
|
||||
#ifdef CONFIG_FEC
|
||||
&mcf_fec0,
|
||||
#ifdef MCFFEC_BASE1
|
||||
&mcf_fec1,
|
||||
#endif
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
&mcf_qspi,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Some ColdFire UARTs let you set the IRQ line to use.
|
||||
*/
|
||||
static void __init mcf_uart_set_irq(void)
|
||||
{
|
||||
#ifdef MCFUART_UIVR
|
||||
/* UART0 interrupt setup */
|
||||
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR);
|
||||
writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
|
||||
mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
|
||||
|
||||
/* UART1 interrupt setup */
|
||||
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR);
|
||||
writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
|
||||
mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __init mcf_init_devices(void)
|
||||
{
|
||||
mcf_uart_set_irq();
|
||||
platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(mcf_init_devices);
|
||||
|
42
arch/m68k/coldfire/dma.c
Normal file
42
arch/m68k/coldfire/dma.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* dma.c -- Freescale ColdFire DMA support
|
||||
*
|
||||
* Copyright (C) 2007, Greg Ungerer (gerg@snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfdma.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* DMA channel base address table.
|
||||
*/
|
||||
unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
|
||||
#ifdef MCFDMA_BASE0
|
||||
MCFDMA_BASE0,
|
||||
#endif
|
||||
#ifdef MCFDMA_BASE1
|
||||
MCFDMA_BASE1,
|
||||
#endif
|
||||
#ifdef MCFDMA_BASE2
|
||||
MCFDMA_BASE2,
|
||||
#endif
|
||||
#ifdef MCFDMA_BASE3
|
||||
MCFDMA_BASE3,
|
||||
#endif
|
||||
};
|
||||
EXPORT_SYMBOL(dma_base_addr);
|
||||
|
||||
unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
|
||||
EXPORT_SYMBOL(dma_device_address);
|
||||
|
||||
/***************************************************************************/
|
81
arch/m68k/coldfire/dma_timer.c
Normal file
81
arch/m68k/coldfire/dma_timer.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* dma_timer.c -- Freescale ColdFire DMA Timer.
|
||||
*
|
||||
* Copyright (C) 2007, Benedikt Spranger <b.spranger@linutronix.de>
|
||||
* Copyright (C) 2008. Sebastian Siewior, Linutronix
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfpit.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
#define DMA_TIMER_0 (0x00)
|
||||
#define DMA_TIMER_1 (0x40)
|
||||
#define DMA_TIMER_2 (0x80)
|
||||
#define DMA_TIMER_3 (0xc0)
|
||||
|
||||
#define DTMR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x400)
|
||||
#define DTXMR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x402)
|
||||
#define DTER0 (MCF_IPSBAR + DMA_TIMER_0 + 0x403)
|
||||
#define DTRR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x404)
|
||||
#define DTCR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x408)
|
||||
#define DTCN0 (MCF_IPSBAR + DMA_TIMER_0 + 0x40c)
|
||||
|
||||
#define DMA_FREQ ((MCF_CLK / 2) / 16)
|
||||
|
||||
/* DTMR */
|
||||
#define DMA_DTMR_RESTART (1 << 3)
|
||||
#define DMA_DTMR_CLK_DIV_1 (1 << 1)
|
||||
#define DMA_DTMR_CLK_DIV_16 (2 << 1)
|
||||
#define DMA_DTMR_ENABLE (1 << 0)
|
||||
|
||||
static cycle_t cf_dt_get_cycles(struct clocksource *cs)
|
||||
{
|
||||
return __raw_readl(DTCN0);
|
||||
}
|
||||
|
||||
static struct clocksource clocksource_cf_dt = {
|
||||
.name = "coldfire_dma_timer",
|
||||
.rating = 200,
|
||||
.read = cf_dt_get_cycles,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static int __init init_cf_dt_clocksource(void)
|
||||
{
|
||||
/*
|
||||
* We setup DMA timer 0 in free run mode. This incrementing counter is
|
||||
* used as a highly precious clock source. With MCF_CLOCK = 150 MHz we
|
||||
* get a ~213 ns resolution and the 32bit register will overflow almost
|
||||
* every 15 minutes.
|
||||
*/
|
||||
__raw_writeb(0x00, DTXMR0);
|
||||
__raw_writeb(0x00, DTER0);
|
||||
__raw_writel(0x00000000, DTRR0);
|
||||
__raw_writew(DMA_DTMR_CLK_DIV_16 | DMA_DTMR_ENABLE, DTMR0);
|
||||
return clocksource_register_hz(&clocksource_cf_dt, DMA_FREQ);
|
||||
}
|
||||
|
||||
arch_initcall(init_cf_dt_clocksource);
|
||||
|
||||
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
|
||||
#define CYC2NS_SCALE ((1000000 << CYC2NS_SCALE_FACTOR) / (DMA_FREQ / 1000))
|
||||
|
||||
static unsigned long long cycles2ns(unsigned long cycl)
|
||||
{
|
||||
return (unsigned long long) ((unsigned long long)cycl *
|
||||
CYC2NS_SCALE) >> CYC2NS_SCALE_FACTOR;
|
||||
}
|
||||
|
||||
unsigned long long sched_clock(void)
|
||||
{
|
||||
unsigned long cycl = __raw_readl(DTCN0);
|
||||
|
||||
return cycles2ns(cycl);
|
||||
}
|
203
arch/m68k/coldfire/entry.S
Normal file
203
arch/m68k/coldfire/entry.S
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* entry.S -- interrupt and exception processing for ColdFire
|
||||
*
|
||||
* Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
|
||||
* Kenneth Albanowski <kjahds@kjahds.com>,
|
||||
* Copyright (C) 2000 Lineo Inc. (www.lineo.com)
|
||||
* Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com)
|
||||
*
|
||||
* Based on:
|
||||
*
|
||||
* linux/arch/m68k/kernel/entry.S
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file README.legal in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Linux/m68k support by Hamish Macdonald
|
||||
*
|
||||
* 68060 fixes by Jesper Skov
|
||||
* ColdFire support by Greg Ungerer (gerg@snapgear.com)
|
||||
* 5307 fixes by David W. Miller
|
||||
* linux 2.4 support David McCullough <davidm@snapgear.com>
|
||||
* Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/entry.h>
|
||||
|
||||
#ifdef CONFIG_COLDFIRE_SW_A7
|
||||
/*
|
||||
* Define software copies of the supervisor and user stack pointers.
|
||||
*/
|
||||
.bss
|
||||
sw_ksp:
|
||||
.long 0
|
||||
sw_usp:
|
||||
.long 0
|
||||
#endif /* CONFIG_COLDFIRE_SW_A7 */
|
||||
|
||||
.text
|
||||
|
||||
.globl system_call
|
||||
.globl resume
|
||||
.globl ret_from_exception
|
||||
.globl ret_from_signal
|
||||
.globl sys_call_table
|
||||
.globl inthandler
|
||||
|
||||
enosys:
|
||||
mov.l #sys_ni_syscall,%d3
|
||||
bra 1f
|
||||
|
||||
ENTRY(system_call)
|
||||
SAVE_ALL_SYS
|
||||
move #0x2000,%sr /* enable intrs again */
|
||||
GET_CURRENT(%d2)
|
||||
|
||||
cmpl #NR_syscalls,%d0
|
||||
jcc enosys
|
||||
lea sys_call_table,%a0
|
||||
lsll #2,%d0 /* movel %a0@(%d0:l:4),%d3 */
|
||||
movel %a0@(%d0),%d3
|
||||
jeq enosys
|
||||
|
||||
1:
|
||||
movel %sp,%d2 /* get thread_info pointer */
|
||||
andl #-THREAD_SIZE,%d2 /* at start of kernel stack */
|
||||
movel %d2,%a0
|
||||
movel %a0@,%a1 /* save top of frame */
|
||||
movel %sp,%a1@(TASK_THREAD+THREAD_ESP0)
|
||||
btst #(TIF_SYSCALL_TRACE%8),%a0@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
|
||||
bnes 1f
|
||||
|
||||
movel %d3,%a0
|
||||
jbsr %a0@
|
||||
movel %d0,%sp@(PT_OFF_D0) /* save the return value */
|
||||
jra ret_from_exception
|
||||
1:
|
||||
movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_OFF_D0 */
|
||||
movel %d2,PT_OFF_D0(%sp) /* on syscall entry */
|
||||
subql #4,%sp
|
||||
SAVE_SWITCH_STACK
|
||||
jbsr syscall_trace_enter
|
||||
RESTORE_SWITCH_STACK
|
||||
addql #4,%sp
|
||||
movel %d3,%a0
|
||||
jbsr %a0@
|
||||
movel %d0,%sp@(PT_OFF_D0) /* save the return value */
|
||||
subql #4,%sp /* dummy return address */
|
||||
SAVE_SWITCH_STACK
|
||||
jbsr syscall_trace_leave
|
||||
|
||||
ret_from_signal:
|
||||
RESTORE_SWITCH_STACK
|
||||
addql #4,%sp
|
||||
|
||||
ret_from_exception:
|
||||
move #0x2700,%sr /* disable intrs */
|
||||
btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */
|
||||
jeq Luser_return /* if so, skip resched, signals */
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
movel %sp,%d1 /* get thread_info pointer */
|
||||
andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
|
||||
movel %d1,%a0
|
||||
movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
|
||||
andl #(1<<TIF_NEED_RESCHED),%d1
|
||||
jeq Lkernel_return
|
||||
|
||||
movel %a0@(TINFO_PREEMPT),%d1
|
||||
cmpl #0,%d1
|
||||
jne Lkernel_return
|
||||
|
||||
pea Lkernel_return
|
||||
jmp preempt_schedule_irq /* preempt the kernel */
|
||||
#endif
|
||||
|
||||
Lkernel_return:
|
||||
moveml %sp@,%d1-%d5/%a0-%a2
|
||||
lea %sp@(32),%sp /* space for 8 regs */
|
||||
movel %sp@+,%d0
|
||||
addql #4,%sp /* orig d0 */
|
||||
addl %sp@+,%sp /* stk adj */
|
||||
rte
|
||||
|
||||
Luser_return:
|
||||
movel %sp,%d1 /* get thread_info pointer */
|
||||
andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
|
||||
movel %d1,%a0
|
||||
moveb %a0@(TINFO_FLAGS+3),%d1 /* thread_info->flags (low 8 bits) */
|
||||
jne Lwork_to_do /* still work to do */
|
||||
|
||||
Lreturn:
|
||||
RESTORE_USER
|
||||
|
||||
Lwork_to_do:
|
||||
movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
|
||||
move #0x2000,%sr /* enable intrs again */
|
||||
btst #TIF_NEED_RESCHED,%d1
|
||||
jne reschedule
|
||||
|
||||
Lsignal_return:
|
||||
subql #4,%sp /* dummy return address */
|
||||
SAVE_SWITCH_STACK
|
||||
pea %sp@(SWITCH_STACK_SIZE)
|
||||
jsr do_notify_resume
|
||||
addql #4,%sp
|
||||
RESTORE_SWITCH_STACK
|
||||
addql #4,%sp
|
||||
jmp Luser_return
|
||||
|
||||
/*
|
||||
* This is the generic interrupt handler (for all hardware interrupt
|
||||
* sources). Calls up to high level code to do all the work.
|
||||
*/
|
||||
ENTRY(inthandler)
|
||||
SAVE_ALL_INT
|
||||
GET_CURRENT(%d2)
|
||||
|
||||
movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */
|
||||
andl #0x03fc,%d0 /* mask out vector only */
|
||||
|
||||
movel %sp,%sp@- /* push regs arg */
|
||||
lsrl #2,%d0 /* calculate real vector # */
|
||||
movel %d0,%sp@- /* push vector number */
|
||||
jbsr do_IRQ /* call high level irq handler */
|
||||
lea %sp@(8),%sp /* pop args off stack */
|
||||
|
||||
bra ret_from_exception
|
||||
|
||||
/*
|
||||
* Beware - when entering resume, prev (the current task) is
|
||||
* in a0, next (the new task) is in a1, so don't change these
|
||||
* registers until their contents are no longer needed.
|
||||
*/
|
||||
ENTRY(resume)
|
||||
movew %sr,%d1 /* save current status */
|
||||
movew %d1,%a0@(TASK_THREAD+THREAD_SR)
|
||||
movel %a0,%d1 /* get prev thread in d1 */
|
||||
SAVE_SWITCH_STACK
|
||||
movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
|
||||
RDUSP /* movel %usp,%a3 */
|
||||
movel %a3,%a0@(TASK_THREAD+THREAD_USP) /* save thread user stack */
|
||||
#ifdef CONFIG_MMU
|
||||
movel %a1,%a2 /* set new current */
|
||||
#endif
|
||||
movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore thread user stack */
|
||||
WRUSP /* movel %a3,%usp */
|
||||
movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new kernel stack */
|
||||
movew %a1@(TASK_THREAD+THREAD_SR),%d7 /* restore new status */
|
||||
movew %d7,%sr
|
||||
RESTORE_SWITCH_STACK
|
||||
rts
|
||||
|
86
arch/m68k/coldfire/firebee.c
Normal file
86
arch/m68k/coldfire/firebee.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* firebee.c -- extra startup code support for the FireBee boards
|
||||
*
|
||||
* Copyright (C) 2011, Greg Ungerer (gerg@snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* 8MB of NOR flash fitted to the FireBee board.
|
||||
*/
|
||||
#define FLASH_PHYS_ADDR 0xe0000000 /* Physical address of flash */
|
||||
#define FLASH_PHYS_SIZE 0x00800000 /* Size of flash */
|
||||
|
||||
#define PART_BOOT_START 0x00000000 /* Start at bottom of flash */
|
||||
#define PART_BOOT_SIZE 0x00040000 /* 256k in size */
|
||||
#define PART_IMAGE_START 0x00040000 /* Start after boot loader */
|
||||
#define PART_IMAGE_SIZE 0x006c0000 /* Most of flash */
|
||||
#define PART_FPGA_START 0x00700000 /* Start at offset 7MB */
|
||||
#define PART_FPGA_SIZE 0x00100000 /* 1MB in size */
|
||||
|
||||
static struct mtd_partition firebee_flash_parts[] = {
|
||||
{
|
||||
.name = "dBUG",
|
||||
.offset = PART_BOOT_START,
|
||||
.size = PART_BOOT_SIZE,
|
||||
},
|
||||
{
|
||||
.name = "FPGA",
|
||||
.offset = PART_FPGA_START,
|
||||
.size = PART_FPGA_SIZE,
|
||||
},
|
||||
{
|
||||
.name = "image",
|
||||
.offset = PART_IMAGE_START,
|
||||
.size = PART_IMAGE_SIZE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data firebee_flash_data = {
|
||||
.width = 2,
|
||||
.nr_parts = ARRAY_SIZE(firebee_flash_parts),
|
||||
.parts = firebee_flash_parts,
|
||||
};
|
||||
|
||||
static struct resource firebee_flash_resource = {
|
||||
.start = FLASH_PHYS_ADDR,
|
||||
.end = FLASH_PHYS_ADDR + FLASH_PHYS_SIZE,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device firebee_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &firebee_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &firebee_flash_resource,
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static int __init init_firebee(void)
|
||||
{
|
||||
platform_device_register(&firebee_flash);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(init_firebee);
|
||||
|
||||
/***************************************************************************/
|
186
arch/m68k/coldfire/gpio.c
Normal file
186
arch/m68k/coldfire/gpio.c
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Coldfire generic GPIO support.
|
||||
*
|
||||
* (C) Copyright 2009, Steven King <sfking@fdwdc.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; version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfgpio.h>
|
||||
|
||||
int __mcfgpio_get_value(unsigned gpio)
|
||||
{
|
||||
return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
|
||||
}
|
||||
EXPORT_SYMBOL(__mcfgpio_get_value);
|
||||
|
||||
void __mcfgpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
if (gpio < MCFGPIO_SCR_START) {
|
||||
unsigned long flags;
|
||||
MCFGPIO_PORTTYPE data;
|
||||
|
||||
local_irq_save(flags);
|
||||
data = mcfgpio_read(__mcfgpio_podr(gpio));
|
||||
if (value)
|
||||
data |= mcfgpio_bit(gpio);
|
||||
else
|
||||
data &= ~mcfgpio_bit(gpio);
|
||||
mcfgpio_write(data, __mcfgpio_podr(gpio));
|
||||
local_irq_restore(flags);
|
||||
} else {
|
||||
if (value)
|
||||
mcfgpio_write(mcfgpio_bit(gpio),
|
||||
MCFGPIO_SETR_PORT(gpio));
|
||||
else
|
||||
mcfgpio_write(~mcfgpio_bit(gpio),
|
||||
MCFGPIO_CLRR_PORT(gpio));
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(__mcfgpio_set_value);
|
||||
|
||||
int __mcfgpio_direction_input(unsigned gpio)
|
||||
{
|
||||
unsigned long flags;
|
||||
MCFGPIO_PORTTYPE dir;
|
||||
|
||||
local_irq_save(flags);
|
||||
dir = mcfgpio_read(__mcfgpio_pddr(gpio));
|
||||
dir &= ~mcfgpio_bit(gpio);
|
||||
mcfgpio_write(dir, __mcfgpio_pddr(gpio));
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__mcfgpio_direction_input);
|
||||
|
||||
int __mcfgpio_direction_output(unsigned gpio, int value)
|
||||
{
|
||||
unsigned long flags;
|
||||
MCFGPIO_PORTTYPE data;
|
||||
|
||||
local_irq_save(flags);
|
||||
data = mcfgpio_read(__mcfgpio_pddr(gpio));
|
||||
data |= mcfgpio_bit(gpio);
|
||||
mcfgpio_write(data, __mcfgpio_pddr(gpio));
|
||||
|
||||
/* now set the data to output */
|
||||
if (gpio < MCFGPIO_SCR_START) {
|
||||
data = mcfgpio_read(__mcfgpio_podr(gpio));
|
||||
if (value)
|
||||
data |= mcfgpio_bit(gpio);
|
||||
else
|
||||
data &= ~mcfgpio_bit(gpio);
|
||||
mcfgpio_write(data, __mcfgpio_podr(gpio));
|
||||
} else {
|
||||
if (value)
|
||||
mcfgpio_write(mcfgpio_bit(gpio),
|
||||
MCFGPIO_SETR_PORT(gpio));
|
||||
else
|
||||
mcfgpio_write(~mcfgpio_bit(gpio),
|
||||
MCFGPIO_CLRR_PORT(gpio));
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__mcfgpio_direction_output);
|
||||
|
||||
int __mcfgpio_request(unsigned gpio)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__mcfgpio_request);
|
||||
|
||||
void __mcfgpio_free(unsigned gpio)
|
||||
{
|
||||
__mcfgpio_direction_input(gpio);
|
||||
}
|
||||
EXPORT_SYMBOL(__mcfgpio_free);
|
||||
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
|
||||
static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return __mcfgpio_direction_input(offset);
|
||||
}
|
||||
|
||||
static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return __mcfgpio_get_value(offset);
|
||||
}
|
||||
|
||||
static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
return __mcfgpio_direction_output(offset, value);
|
||||
}
|
||||
|
||||
static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
__mcfgpio_set_value(offset, value);
|
||||
}
|
||||
|
||||
static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return __mcfgpio_request(offset);
|
||||
}
|
||||
|
||||
static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
__mcfgpio_free(offset);
|
||||
}
|
||||
|
||||
static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
#if defined(MCFGPIO_IRQ_MIN)
|
||||
if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
|
||||
#else
|
||||
if (offset < MCFGPIO_IRQ_MAX)
|
||||
#endif
|
||||
return MCFGPIO_IRQ_VECBASE + offset;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct bus_type mcfgpio_subsys = {
|
||||
.name = "gpio",
|
||||
.dev_name = "gpio",
|
||||
};
|
||||
|
||||
static struct gpio_chip mcfgpio_chip = {
|
||||
.label = "mcfgpio",
|
||||
.request = mcfgpio_request,
|
||||
.free = mcfgpio_free,
|
||||
.direction_input = mcfgpio_direction_input,
|
||||
.direction_output = mcfgpio_direction_output,
|
||||
.get = mcfgpio_get_value,
|
||||
.set = mcfgpio_set_value,
|
||||
.to_irq = mcfgpio_to_irq,
|
||||
.base = 0,
|
||||
.ngpio = MCFGPIO_PIN_MAX,
|
||||
};
|
||||
|
||||
static int __init mcfgpio_sysinit(void)
|
||||
{
|
||||
gpiochip_add(&mcfgpio_chip);
|
||||
return subsys_system_register(&mcfgpio_subsys, NULL);
|
||||
}
|
||||
|
||||
core_initcall(mcfgpio_sysinit);
|
||||
#endif
|
298
arch/m68k/coldfire/head.S
Normal file
298
arch/m68k/coldfire/head.S
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* head.S -- common startup code for ColdFire CPUs.
|
||||
*
|
||||
* (C) Copyright 1999-2011, Greg Ungerer <gerg@snapgear.com>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfmmu.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* If we don't have a fixed memory size, then lets build in code
|
||||
* to auto detect the DRAM size. Obviously this is the preferred
|
||||
* method, and should work for most boards. It won't work for those
|
||||
* that do not have their RAM starting at address 0, and it only
|
||||
* works on SDRAM (not boards fitted with SRAM).
|
||||
*/
|
||||
#if CONFIG_RAMSIZE != 0
|
||||
.macro GET_MEM_SIZE
|
||||
movel #CONFIG_RAMSIZE,%d0 /* hard coded memory size */
|
||||
.endm
|
||||
|
||||
#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
|
||||
defined(CONFIG_M5249) || defined(CONFIG_M525x) || \
|
||||
defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
|
||||
defined(CONFIG_M5307) || defined(CONFIG_M5407)
|
||||
/*
|
||||
* Not all these devices have exactly the same DRAM controller,
|
||||
* but the DCMR register is virtually identical - give or take
|
||||
* a couple of bits. The only exception is the 5272 devices, their
|
||||
* DRAM controller is quite different.
|
||||
*/
|
||||
.macro GET_MEM_SIZE
|
||||
movel MCFSIM_DMR0,%d0 /* get mask for 1st bank */
|
||||
btst #0,%d0 /* check if region enabled */
|
||||
beq 1f
|
||||
andl #0xfffc0000,%d0
|
||||
beq 1f
|
||||
addl #0x00040000,%d0 /* convert mask to size */
|
||||
1:
|
||||
movel MCFSIM_DMR1,%d1 /* get mask for 2nd bank */
|
||||
btst #0,%d1 /* check if region enabled */
|
||||
beq 2f
|
||||
andl #0xfffc0000,%d1
|
||||
beq 2f
|
||||
addl #0x00040000,%d1
|
||||
addl %d1,%d0 /* total mem size in d0 */
|
||||
2:
|
||||
.endm
|
||||
|
||||
#elif defined(CONFIG_M5272)
|
||||
.macro GET_MEM_SIZE
|
||||
movel MCFSIM_CSOR7,%d0 /* get SDRAM address mask */
|
||||
andil #0xfffff000,%d0 /* mask out chip select options */
|
||||
negl %d0 /* negate bits */
|
||||
.endm
|
||||
|
||||
#elif defined(CONFIG_M520x)
|
||||
.macro GET_MEM_SIZE
|
||||
clrl %d0
|
||||
movel MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */
|
||||
andl #0x1f, %d2 /* Get only the chip select size */
|
||||
beq 3f /* Check if it is enabled */
|
||||
addql #1, %d2 /* Form exponent */
|
||||
moveql #1, %d0
|
||||
lsll %d2, %d0 /* 2 ^ exponent */
|
||||
3:
|
||||
movel MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */
|
||||
andl #0x1f, %d2 /* Get only the chip select size */
|
||||
beq 4f /* Check if it is enabled */
|
||||
addql #1, %d2 /* Form exponent */
|
||||
moveql #1, %d1
|
||||
lsll %d2, %d1 /* 2 ^ exponent */
|
||||
addl %d1, %d0 /* Total size of SDRAM in d0 */
|
||||
4:
|
||||
.endm
|
||||
|
||||
#else
|
||||
#error "ERROR: I don't know how to probe your boards memory size?"
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Boards and platforms can do specific early hardware setup if
|
||||
* they need to. Most don't need this, define away if not required.
|
||||
*/
|
||||
#ifndef PLATFORM_SETUP
|
||||
#define PLATFORM_SETUP
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
.global _start
|
||||
.global _rambase
|
||||
.global _ramvec
|
||||
.global _ramstart
|
||||
.global _ramend
|
||||
#if defined(CONFIG_UBOOT)
|
||||
.global _init_sp
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
.data
|
||||
|
||||
/*
|
||||
* During startup we store away the RAM setup. These are not in the
|
||||
* bss, since their values are determined and written before the bss
|
||||
* has been cleared.
|
||||
*/
|
||||
_rambase:
|
||||
.long 0
|
||||
_ramvec:
|
||||
.long 0
|
||||
_ramstart:
|
||||
.long 0
|
||||
_ramend:
|
||||
.long 0
|
||||
#if defined(CONFIG_UBOOT)
|
||||
_init_sp:
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
__HEAD
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
_start0:
|
||||
jmp _start
|
||||
.global kernel_pg_dir
|
||||
.equ kernel_pg_dir,_start0
|
||||
.equ .,_start0+0x1000
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the codes first entry point. This is where it all
|
||||
* begins...
|
||||
*/
|
||||
|
||||
_start:
|
||||
nop /* filler */
|
||||
movew #0x2700, %sr /* no interrupts */
|
||||
movel #CACHE_INIT,%d0 /* disable cache */
|
||||
movec %d0,%CACR
|
||||
nop
|
||||
#if defined(CONFIG_UBOOT)
|
||||
movel %sp,_init_sp /* save initial stack pointer */
|
||||
#endif
|
||||
#ifdef CONFIG_MBAR
|
||||
movel #CONFIG_MBAR+1,%d0 /* configured MBAR address */
|
||||
movec %d0,%MBAR /* set it */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do any platform or board specific setup now. Most boards
|
||||
* don't need anything. Those exceptions are define this in
|
||||
* their board specific includes.
|
||||
*/
|
||||
PLATFORM_SETUP
|
||||
|
||||
/*
|
||||
* Create basic memory configuration. Set VBR accordingly,
|
||||
* and size memory.
|
||||
*/
|
||||
movel #CONFIG_VECTORBASE,%a7
|
||||
movec %a7,%VBR /* set vectors addr */
|
||||
movel %a7,_ramvec
|
||||
|
||||
movel #CONFIG_RAMBASE,%a7 /* mark the base of RAM */
|
||||
movel %a7,_rambase
|
||||
|
||||
GET_MEM_SIZE /* macro code determines size */
|
||||
addl %a7,%d0
|
||||
movel %d0,_ramend /* set end ram addr */
|
||||
|
||||
/*
|
||||
* Now that we know what the memory is, lets enable cache
|
||||
* and get things moving. This is Coldfire CPU specific. Not
|
||||
* all version cores have identical cache register setup. But
|
||||
* it is very similar. Define the exact settings in the headers
|
||||
* then the code here is the same for all.
|
||||
*/
|
||||
movel #ACR0_MODE,%d0 /* set RAM region for caching */
|
||||
movec %d0,%ACR0
|
||||
movel #ACR1_MODE,%d0 /* anything else to cache? */
|
||||
movec %d0,%ACR1
|
||||
#ifdef ACR2_MODE
|
||||
movel #ACR2_MODE,%d0
|
||||
movec %d0,%ACR2
|
||||
movel #ACR3_MODE,%d0
|
||||
movec %d0,%ACR3
|
||||
#endif
|
||||
movel #CACHE_MODE,%d0 /* enable cache */
|
||||
movec %d0,%CACR
|
||||
nop
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
/*
|
||||
* Identity mapping for the kernel region.
|
||||
*/
|
||||
movel #(MMUBASE+1),%d0 /* enable MMUBAR registers */
|
||||
movec %d0,%MMUBAR
|
||||
movel #MMUOR_CA,%d0 /* clear TLB entries */
|
||||
movel %d0,MMUOR
|
||||
movel #0,%d0 /* set ASID to 0 */
|
||||
movec %d0,%asid
|
||||
|
||||
movel #MMUCR_EN,%d0 /* Enable the identity map */
|
||||
movel %d0,MMUCR
|
||||
nop /* sync i-pipeline */
|
||||
|
||||
movel #_vstart,%a0 /* jump to "virtual" space */
|
||||
jmp %a0@
|
||||
_vstart:
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#ifdef CONFIG_ROMFS_FS
|
||||
/*
|
||||
* Move ROM filesystem above bss :-)
|
||||
*/
|
||||
lea __bss_start,%a0 /* get start of bss */
|
||||
lea __bss_stop,%a1 /* set up destination */
|
||||
movel %a0,%a2 /* copy of bss start */
|
||||
|
||||
movel 8(%a0),%d0 /* get size of ROMFS */
|
||||
addql #8,%d0 /* allow for rounding */
|
||||
andl #0xfffffffc, %d0 /* whole words */
|
||||
|
||||
addl %d0,%a0 /* copy from end */
|
||||
addl %d0,%a1 /* copy from end */
|
||||
movel %a1,_ramstart /* set start of ram */
|
||||
|
||||
_copy_romfs:
|
||||
movel -(%a0),%d0 /* copy dword */
|
||||
movel %d0,-(%a1)
|
||||
cmpl %a0,%a2 /* check if at end */
|
||||
bne _copy_romfs
|
||||
|
||||
#else /* CONFIG_ROMFS_FS */
|
||||
lea __bss_stop,%a1
|
||||
movel %a1,_ramstart
|
||||
#endif /* CONFIG_ROMFS_FS */
|
||||
|
||||
|
||||
/*
|
||||
* Zero out the bss region.
|
||||
*/
|
||||
lea __bss_start,%a0 /* get start of bss */
|
||||
lea __bss_stop,%a1 /* get end of bss */
|
||||
clrl %d0 /* set value */
|
||||
_clear_bss:
|
||||
movel %d0,(%a0)+ /* clear each word */
|
||||
cmpl %a0,%a1 /* check if at end */
|
||||
bne _clear_bss
|
||||
|
||||
/*
|
||||
* Load the current task pointer and stack.
|
||||
*/
|
||||
lea init_thread_union,%a0
|
||||
lea THREAD_SIZE(%a0),%sp
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
.global m68k_cputype
|
||||
.global m68k_mmutype
|
||||
.global m68k_fputype
|
||||
.global m68k_machtype
|
||||
movel #CPU_COLDFIRE,%d0
|
||||
movel %d0,m68k_cputype /* Mark us as a ColdFire */
|
||||
movel #MMU_COLDFIRE,%d0
|
||||
movel %d0,m68k_mmutype
|
||||
movel #FPU_COLDFIRE,%d0
|
||||
movel %d0,m68k_fputype
|
||||
movel #MACH_M54XX,%d0
|
||||
movel %d0,m68k_machtype /* Mark us as a 54xx machine */
|
||||
lea init_task,%a2 /* Set "current" init task */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assember start up done, start code proper.
|
||||
*/
|
||||
jsr start_kernel /* start Linux kernel */
|
||||
|
||||
_exit:
|
||||
jmp _exit /* should never get here */
|
||||
|
||||
/*****************************************************************************/
|
212
arch/m68k/coldfire/intc-2.c
Normal file
212
arch/m68k/coldfire/intc-2.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* intc-2.c
|
||||
*
|
||||
* General interrupt controller code for the many ColdFire cores that use
|
||||
* interrupt controllers with 63 interrupt sources, organized as 56 fully-
|
||||
* programmable + 7 fixed-level interrupt sources. This includes the 523x
|
||||
* family, the 5270, 5271, 5274, 5275, and the 528x family which have two such
|
||||
* controllers, and the 547x and 548x families which have only one of them.
|
||||
*
|
||||
* The external 7 fixed interrupts are part the the Edge Port unit of these
|
||||
* ColdFire parts. They can be configured as level or edge triggered.
|
||||
*
|
||||
* (C) Copyright 2009-2011, Greg Ungerer <gerg@snapgear.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
/*
|
||||
* Bit definitions for the ICR family of registers.
|
||||
*/
|
||||
#define MCFSIM_ICR_LEVEL(l) ((l)<<3) /* Level l intr */
|
||||
#define MCFSIM_ICR_PRI(p) (p) /* Priority p intr */
|
||||
|
||||
/*
|
||||
* The EDGE Port interrupts are the fixed 7 external interrupts.
|
||||
* They need some special treatment, for example they need to be acked.
|
||||
*/
|
||||
#define EINT0 64 /* Is not actually used, but spot reserved for it */
|
||||
#define EINT1 65 /* EDGE Port interrupt 1 */
|
||||
#define EINT7 71 /* EDGE Port interrupt 7 */
|
||||
|
||||
#ifdef MCFICM_INTC1
|
||||
#define NR_VECS 128
|
||||
#else
|
||||
#define NR_VECS 64
|
||||
#endif
|
||||
|
||||
static void intc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - MCFINT_VECBASE;
|
||||
unsigned long imraddr;
|
||||
u32 val, imrbit;
|
||||
|
||||
#ifdef MCFICM_INTC1
|
||||
imraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
|
||||
#else
|
||||
imraddr = MCFICM_INTC0;
|
||||
#endif
|
||||
imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL;
|
||||
imrbit = 0x1 << (irq & 0x1f);
|
||||
|
||||
val = __raw_readl(imraddr);
|
||||
__raw_writel(val | imrbit, imraddr);
|
||||
}
|
||||
|
||||
static void intc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - MCFINT_VECBASE;
|
||||
unsigned long imraddr;
|
||||
u32 val, imrbit;
|
||||
|
||||
#ifdef MCFICM_INTC1
|
||||
imraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
|
||||
#else
|
||||
imraddr = MCFICM_INTC0;
|
||||
#endif
|
||||
imraddr += ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
|
||||
imrbit = 0x1 << (irq & 0x1f);
|
||||
|
||||
/* Don't set the "maskall" bit! */
|
||||
if ((irq & 0x20) == 0)
|
||||
imrbit |= 0x1;
|
||||
|
||||
val = __raw_readl(imraddr);
|
||||
__raw_writel(val & ~imrbit, imraddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only the external (or EDGE Port) interrupts need to be acknowledged
|
||||
* here, as part of the IRQ handler. They only really need to be ack'ed
|
||||
* if they are in edge triggered mode, but there is no harm in doing it
|
||||
* for all types.
|
||||
*/
|
||||
static void intc_irq_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
__raw_writeb(0x1 << (irq - EINT0), MCFEPORT_EPFR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Each vector needs a unique priority and level associated with it.
|
||||
* We don't really care so much what they are, we don't rely on the
|
||||
* traditional priority interrupt scheme of the m68k/ColdFire. This
|
||||
* only needs to be set once for an interrupt, and we will never change
|
||||
* these values once we have set them.
|
||||
*/
|
||||
static u8 intc_intpri = MCFSIM_ICR_LEVEL(6) | MCFSIM_ICR_PRI(6);
|
||||
|
||||
static unsigned int intc_irq_startup(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - MCFINT_VECBASE;
|
||||
unsigned long icraddr;
|
||||
|
||||
#ifdef MCFICM_INTC1
|
||||
icraddr = (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
|
||||
#else
|
||||
icraddr = MCFICM_INTC0;
|
||||
#endif
|
||||
icraddr += MCFINTC_ICR0 + (irq & 0x3f);
|
||||
if (__raw_readb(icraddr) == 0)
|
||||
__raw_writeb(intc_intpri--, icraddr);
|
||||
|
||||
irq = d->irq;
|
||||
if ((irq >= EINT1) && (irq <= EINT7)) {
|
||||
u8 v;
|
||||
|
||||
irq -= EINT0;
|
||||
|
||||
/* Set EPORT line as input */
|
||||
v = __raw_readb(MCFEPORT_EPDDR);
|
||||
__raw_writeb(v & ~(0x1 << irq), MCFEPORT_EPDDR);
|
||||
|
||||
/* Set EPORT line as interrupt source */
|
||||
v = __raw_readb(MCFEPORT_EPIER);
|
||||
__raw_writeb(v | (0x1 << irq), MCFEPORT_EPIER);
|
||||
}
|
||||
|
||||
intc_irq_unmask(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intc_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
u16 pa, tb;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
tb = 0x1;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
tb = 0x2;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
tb = 0x3;
|
||||
break;
|
||||
default:
|
||||
/* Level triggered */
|
||||
tb = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tb)
|
||||
irq_set_handler(irq, handle_edge_irq);
|
||||
|
||||
irq -= EINT0;
|
||||
pa = __raw_readw(MCFEPORT_EPPAR);
|
||||
pa = (pa & ~(0x3 << (irq * 2))) | (tb << (irq * 2));
|
||||
__raw_writew(pa, MCFEPORT_EPPAR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip intc_irq_chip = {
|
||||
.name = "CF-INTC",
|
||||
.irq_startup = intc_irq_startup,
|
||||
.irq_mask = intc_irq_mask,
|
||||
.irq_unmask = intc_irq_unmask,
|
||||
};
|
||||
|
||||
static struct irq_chip intc_irq_chip_edge_port = {
|
||||
.name = "CF-INTC-EP",
|
||||
.irq_startup = intc_irq_startup,
|
||||
.irq_mask = intc_irq_mask,
|
||||
.irq_unmask = intc_irq_unmask,
|
||||
.irq_ack = intc_irq_ack,
|
||||
.irq_set_type = intc_irq_set_type,
|
||||
};
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
/* Mask all interrupt sources */
|
||||
__raw_writel(0x1, MCFICM_INTC0 + MCFINTC_IMRL);
|
||||
#ifdef MCFICM_INTC1
|
||||
__raw_writel(0x1, MCFICM_INTC1 + MCFINTC_IMRL);
|
||||
#endif
|
||||
|
||||
for (irq = MCFINT_VECBASE; (irq < MCFINT_VECBASE + NR_VECS); irq++) {
|
||||
if ((irq >= EINT1) && (irq <=EINT7))
|
||||
irq_set_chip(irq, &intc_irq_chip_edge_port);
|
||||
else
|
||||
irq_set_chip(irq, &intc_irq_chip);
|
||||
irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
|
||||
irq_set_handler(irq, handle_level_irq);
|
||||
}
|
||||
}
|
||||
|
61
arch/m68k/coldfire/intc-5249.c
Normal file
61
arch/m68k/coldfire/intc-5249.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* intc2.c -- support for the 2nd INTC controller of the 5249
|
||||
*
|
||||
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
static void intc2_irq_gpio_mask(struct irq_data *d)
|
||||
{
|
||||
u32 imr;
|
||||
imr = readl(MCFSIM2_GPIOINTENABLE);
|
||||
imr &= ~(0x1 << (d->irq - MCF_IRQ_GPIO0));
|
||||
writel(imr, MCFSIM2_GPIOINTENABLE);
|
||||
}
|
||||
|
||||
static void intc2_irq_gpio_unmask(struct irq_data *d)
|
||||
{
|
||||
u32 imr;
|
||||
imr = readl(MCFSIM2_GPIOINTENABLE);
|
||||
imr |= (0x1 << (d->irq - MCF_IRQ_GPIO0));
|
||||
writel(imr, MCFSIM2_GPIOINTENABLE);
|
||||
}
|
||||
|
||||
static void intc2_irq_gpio_ack(struct irq_data *d)
|
||||
{
|
||||
writel(0x1 << (d->irq - MCF_IRQ_GPIO0), MCFSIM2_GPIOINTCLEAR);
|
||||
}
|
||||
|
||||
static struct irq_chip intc2_irq_gpio_chip = {
|
||||
.name = "CF-INTC2",
|
||||
.irq_mask = intc2_irq_gpio_mask,
|
||||
.irq_unmask = intc2_irq_gpio_unmask,
|
||||
.irq_ack = intc2_irq_gpio_ack,
|
||||
};
|
||||
|
||||
static int __init mcf_intc2_init(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
/* GPIO interrupt sources */
|
||||
for (irq = MCF_IRQ_GPIO0; (irq <= MCF_IRQ_GPIO7); irq++) {
|
||||
irq_set_chip(irq, &intc2_irq_gpio_chip);
|
||||
irq_set_handler(irq, handle_edge_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(mcf_intc2_init);
|
91
arch/m68k/coldfire/intc-525x.c
Normal file
91
arch/m68k/coldfire/intc-525x.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* intc2.c -- support for the 2nd INTC controller of the 525x
|
||||
*
|
||||
* (C) Copyright 2012, Steven King <sfking@fdwdc.com>
|
||||
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
static void intc2_irq_gpio_mask(struct irq_data *d)
|
||||
{
|
||||
u32 imr = readl(MCFSIM2_GPIOINTENABLE);
|
||||
u32 type = irqd_get_trigger_type(d);
|
||||
int irq = d->irq - MCF_IRQ_GPIO0;
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
imr &= ~(0x001 << irq);
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
imr &= ~(0x100 << irq);
|
||||
writel(imr, MCFSIM2_GPIOINTENABLE);
|
||||
}
|
||||
|
||||
static void intc2_irq_gpio_unmask(struct irq_data *d)
|
||||
{
|
||||
u32 imr = readl(MCFSIM2_GPIOINTENABLE);
|
||||
u32 type = irqd_get_trigger_type(d);
|
||||
int irq = d->irq - MCF_IRQ_GPIO0;
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
imr |= (0x001 << irq);
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
imr |= (0x100 << irq);
|
||||
writel(imr, MCFSIM2_GPIOINTENABLE);
|
||||
}
|
||||
|
||||
static void intc2_irq_gpio_ack(struct irq_data *d)
|
||||
{
|
||||
u32 imr = 0;
|
||||
u32 type = irqd_get_trigger_type(d);
|
||||
int irq = d->irq - MCF_IRQ_GPIO0;
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
imr |= (0x001 << irq);
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
imr |= (0x100 << irq);
|
||||
writel(imr, MCFSIM2_GPIOINTCLEAR);
|
||||
}
|
||||
|
||||
static int intc2_irq_gpio_set_type(struct irq_data *d, unsigned int f)
|
||||
{
|
||||
if (f & ~IRQ_TYPE_EDGE_BOTH)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip intc2_irq_gpio_chip = {
|
||||
.name = "CF-INTC2",
|
||||
.irq_mask = intc2_irq_gpio_mask,
|
||||
.irq_unmask = intc2_irq_gpio_unmask,
|
||||
.irq_ack = intc2_irq_gpio_ack,
|
||||
.irq_set_type = intc2_irq_gpio_set_type,
|
||||
};
|
||||
|
||||
static int __init mcf_intc2_init(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
/* set the interrupt base for the second interrupt controller */
|
||||
writel(MCFINTC2_VECBASE, MCFINTC2_INTBASE);
|
||||
|
||||
/* GPIO interrupt sources */
|
||||
for (irq = MCF_IRQ_GPIO0; (irq <= MCF_IRQ_GPIO6); irq++) {
|
||||
irq_set_chip(irq, &intc2_irq_gpio_chip);
|
||||
irq_set_handler(irq, handle_edge_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(mcf_intc2_init);
|
185
arch/m68k/coldfire/intc-5272.c
Normal file
185
arch/m68k/coldfire/intc-5272.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* intc.c -- interrupt controller or ColdFire 5272 SoC
|
||||
*
|
||||
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
/*
|
||||
* The 5272 ColdFire interrupt controller is nothing like any other
|
||||
* ColdFire interrupt controller - it truly is completely different.
|
||||
* Given its age it is unlikely to be used on any other ColdFire CPU.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The masking and priproty setting of interrupts on the 5272 is done
|
||||
* via a set of 4 "Interrupt Controller Registers" (ICR). There is a
|
||||
* loose mapping of vector number to register and internal bits, but
|
||||
* a table is the easiest and quickest way to map them.
|
||||
*
|
||||
* Note that the external interrupts are edge triggered (unlike the
|
||||
* internal interrupt sources which are level triggered). Which means
|
||||
* they also need acknowledging via acknowledge bits.
|
||||
*/
|
||||
struct irqmap {
|
||||
unsigned int icr;
|
||||
unsigned char index;
|
||||
unsigned char ack;
|
||||
};
|
||||
|
||||
static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
|
||||
/*MCF_IRQ_SPURIOUS*/ { .icr = 0, .index = 0, .ack = 0, },
|
||||
/*MCF_IRQ_EINT1*/ { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, },
|
||||
/*MCF_IRQ_EINT2*/ { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, },
|
||||
/*MCF_IRQ_EINT3*/ { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, },
|
||||
/*MCF_IRQ_EINT4*/ { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, },
|
||||
/*MCF_IRQ_TIMER1*/ { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, },
|
||||
/*MCF_IRQ_TIMER2*/ { .icr = MCFSIM_ICR1, .index = 8, .ack = 0, },
|
||||
/*MCF_IRQ_TIMER3*/ { .icr = MCFSIM_ICR1, .index = 4, .ack = 0, },
|
||||
/*MCF_IRQ_TIMER4*/ { .icr = MCFSIM_ICR1, .index = 0, .ack = 0, },
|
||||
/*MCF_IRQ_UART1*/ { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, },
|
||||
/*MCF_IRQ_UART2*/ { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, },
|
||||
/*MCF_IRQ_PLIP*/ { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, },
|
||||
/*MCF_IRQ_PLIA*/ { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, },
|
||||
/*MCF_IRQ_USB0*/ { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, },
|
||||
/*MCF_IRQ_USB1*/ { .icr = MCFSIM_ICR2, .index = 8, .ack = 0, },
|
||||
/*MCF_IRQ_USB2*/ { .icr = MCFSIM_ICR2, .index = 4, .ack = 0, },
|
||||
/*MCF_IRQ_USB3*/ { .icr = MCFSIM_ICR2, .index = 0, .ack = 0, },
|
||||
/*MCF_IRQ_USB4*/ { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, },
|
||||
/*MCF_IRQ_USB5*/ { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, },
|
||||
/*MCF_IRQ_USB6*/ { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, },
|
||||
/*MCF_IRQ_USB7*/ { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, },
|
||||
/*MCF_IRQ_DMA*/ { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, },
|
||||
/*MCF_IRQ_ERX*/ { .icr = MCFSIM_ICR3, .index = 8, .ack = 0, },
|
||||
/*MCF_IRQ_ETX*/ { .icr = MCFSIM_ICR3, .index = 4, .ack = 0, },
|
||||
/*MCF_IRQ_ENTC*/ { .icr = MCFSIM_ICR3, .index = 0, .ack = 0, },
|
||||
/*MCF_IRQ_QSPI*/ { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, },
|
||||
/*MCF_IRQ_EINT5*/ { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, },
|
||||
/*MCF_IRQ_EINT6*/ { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, },
|
||||
/*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
|
||||
};
|
||||
|
||||
/*
|
||||
* The act of masking the interrupt also has a side effect of 'ack'ing
|
||||
* an interrupt on this irq (for the external irqs). So this mask function
|
||||
* is also an ack_mask function.
|
||||
*/
|
||||
static void intc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
|
||||
u32 v;
|
||||
irq -= MCFINT_VECBASE;
|
||||
v = 0x8 << intc_irqmap[irq].index;
|
||||
writel(v, intc_irqmap[irq].icr);
|
||||
}
|
||||
}
|
||||
|
||||
static void intc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
|
||||
u32 v;
|
||||
irq -= MCFINT_VECBASE;
|
||||
v = 0xd << intc_irqmap[irq].index;
|
||||
writel(v, intc_irqmap[irq].icr);
|
||||
}
|
||||
}
|
||||
|
||||
static void intc_irq_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
/* Only external interrupts are acked */
|
||||
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
|
||||
irq -= MCFINT_VECBASE;
|
||||
if (intc_irqmap[irq].ack) {
|
||||
u32 v;
|
||||
v = readl(intc_irqmap[irq].icr);
|
||||
v &= (0x7 << intc_irqmap[irq].index);
|
||||
v |= (0x8 << intc_irqmap[irq].index);
|
||||
writel(v, intc_irqmap[irq].icr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int intc_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
|
||||
irq -= MCFINT_VECBASE;
|
||||
if (intc_irqmap[irq].ack) {
|
||||
u32 v;
|
||||
v = readl(MCFSIM_PITR);
|
||||
if (type == IRQ_TYPE_EDGE_FALLING)
|
||||
v &= ~(0x1 << (32 - irq));
|
||||
else
|
||||
v |= (0x1 << (32 - irq));
|
||||
writel(v, MCFSIM_PITR);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple flow handler to deal with the external edge triggered interrupts.
|
||||
* We need to be careful with the masking/acking due to the side effects
|
||||
* of masking an interrupt.
|
||||
*/
|
||||
static void intc_external_irq(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
irq_desc_get_chip(desc)->irq_ack(&desc->irq_data);
|
||||
handle_simple_irq(irq, desc);
|
||||
}
|
||||
|
||||
static struct irq_chip intc_irq_chip = {
|
||||
.name = "CF-INTC",
|
||||
.irq_mask = intc_irq_mask,
|
||||
.irq_unmask = intc_irq_unmask,
|
||||
.irq_mask_ack = intc_irq_mask,
|
||||
.irq_ack = intc_irq_ack,
|
||||
.irq_set_type = intc_irq_set_type,
|
||||
};
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
int irq, edge;
|
||||
|
||||
/* Mask all interrupt sources */
|
||||
writel(0x88888888, MCFSIM_ICR1);
|
||||
writel(0x88888888, MCFSIM_ICR2);
|
||||
writel(0x88888888, MCFSIM_ICR3);
|
||||
writel(0x88888888, MCFSIM_ICR4);
|
||||
|
||||
for (irq = 0; (irq < NR_IRQS); irq++) {
|
||||
irq_set_chip(irq, &intc_irq_chip);
|
||||
edge = 0;
|
||||
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX))
|
||||
edge = intc_irqmap[irq - MCFINT_VECBASE].ack;
|
||||
if (edge) {
|
||||
irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
|
||||
irq_set_handler(irq, intc_external_irq);
|
||||
} else {
|
||||
irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
|
||||
irq_set_handler(irq, handle_level_irq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
199
arch/m68k/coldfire/intc-simr.c
Normal file
199
arch/m68k/coldfire/intc-simr.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* intc-simr.c
|
||||
*
|
||||
* Interrupt controller code for the ColdFire 5208, 5207 & 532x parts.
|
||||
*
|
||||
* (C) Copyright 2009-2011, Greg Ungerer <gerg@snapgear.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
/*
|
||||
* The EDGE Port interrupts are the fixed 7 external interrupts.
|
||||
* They need some special treatment, for example they need to be acked.
|
||||
*/
|
||||
#ifdef CONFIG_M520x
|
||||
/*
|
||||
* The 520x parts only support a limited range of these external
|
||||
* interrupts, only 1, 4 and 7 (as interrupts 65, 66 and 67).
|
||||
*/
|
||||
#define EINT0 64 /* Is not actually used, but spot reserved for it */
|
||||
#define EINT1 65 /* EDGE Port interrupt 1 */
|
||||
#define EINT4 66 /* EDGE Port interrupt 4 */
|
||||
#define EINT7 67 /* EDGE Port interrupt 7 */
|
||||
|
||||
static unsigned int irqebitmap[] = { 0, 1, 4, 7 };
|
||||
static unsigned int inline irq2ebit(unsigned int irq)
|
||||
{
|
||||
return irqebitmap[irq - EINT0];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Most of the ColdFire parts with the EDGE Port module just have
|
||||
* a strait direct mapping of the 7 external interrupts. Although
|
||||
* there is a bit reserved for 0, it is not used.
|
||||
*/
|
||||
#define EINT0 64 /* Is not actually used, but spot reserved for it */
|
||||
#define EINT1 65 /* EDGE Port interrupt 1 */
|
||||
#define EINT7 71 /* EDGE Port interrupt 7 */
|
||||
|
||||
static unsigned int inline irq2ebit(unsigned int irq)
|
||||
{
|
||||
return irq - EINT0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* There maybe one, two or three interrupt control units, each has 64
|
||||
* interrupts. If there is no second or third unit then MCFINTC1_* or
|
||||
* MCFINTC2_* defines will be 0 (and code for them optimized away).
|
||||
*/
|
||||
|
||||
static void intc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - MCFINT_VECBASE;
|
||||
|
||||
if (MCFINTC2_SIMR && (irq > 128))
|
||||
__raw_writeb(irq - 128, MCFINTC2_SIMR);
|
||||
else if (MCFINTC1_SIMR && (irq > 64))
|
||||
__raw_writeb(irq - 64, MCFINTC1_SIMR);
|
||||
else
|
||||
__raw_writeb(irq, MCFINTC0_SIMR);
|
||||
}
|
||||
|
||||
static void intc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - MCFINT_VECBASE;
|
||||
|
||||
if (MCFINTC2_CIMR && (irq > 128))
|
||||
__raw_writeb(irq - 128, MCFINTC2_CIMR);
|
||||
else if (MCFINTC1_CIMR && (irq > 64))
|
||||
__raw_writeb(irq - 64, MCFINTC1_CIMR);
|
||||
else
|
||||
__raw_writeb(irq, MCFINTC0_CIMR);
|
||||
}
|
||||
|
||||
static void intc_irq_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int ebit = irq2ebit(d->irq);
|
||||
|
||||
__raw_writeb(0x1 << ebit, MCFEPORT_EPFR);
|
||||
}
|
||||
|
||||
static unsigned int intc_irq_startup(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
if ((irq >= EINT1) && (irq <= EINT7)) {
|
||||
unsigned int ebit = irq2ebit(irq);
|
||||
u8 v;
|
||||
|
||||
#if defined(MCFEPORT_EPDDR)
|
||||
/* Set EPORT line as input */
|
||||
v = __raw_readb(MCFEPORT_EPDDR);
|
||||
__raw_writeb(v & ~(0x1 << ebit), MCFEPORT_EPDDR);
|
||||
#endif
|
||||
|
||||
/* Set EPORT line as interrupt source */
|
||||
v = __raw_readb(MCFEPORT_EPIER);
|
||||
__raw_writeb(v | (0x1 << ebit), MCFEPORT_EPIER);
|
||||
}
|
||||
|
||||
irq -= MCFINT_VECBASE;
|
||||
if (MCFINTC2_ICR0 && (irq > 128))
|
||||
__raw_writeb(5, MCFINTC2_ICR0 + irq - 128);
|
||||
else if (MCFINTC1_ICR0 && (irq > 64))
|
||||
__raw_writeb(5, MCFINTC1_ICR0 + irq - 64);
|
||||
else
|
||||
__raw_writeb(5, MCFINTC0_ICR0 + irq);
|
||||
|
||||
intc_irq_unmask(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intc_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
unsigned int ebit, irq = d->irq;
|
||||
u16 pa, tb;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
tb = 0x1;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
tb = 0x2;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
tb = 0x3;
|
||||
break;
|
||||
default:
|
||||
/* Level triggered */
|
||||
tb = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tb)
|
||||
irq_set_handler(irq, handle_edge_irq);
|
||||
|
||||
ebit = irq2ebit(irq) * 2;
|
||||
pa = __raw_readw(MCFEPORT_EPPAR);
|
||||
pa = (pa & ~(0x3 << ebit)) | (tb << ebit);
|
||||
__raw_writew(pa, MCFEPORT_EPPAR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip intc_irq_chip = {
|
||||
.name = "CF-INTC",
|
||||
.irq_startup = intc_irq_startup,
|
||||
.irq_mask = intc_irq_mask,
|
||||
.irq_unmask = intc_irq_unmask,
|
||||
};
|
||||
|
||||
static struct irq_chip intc_irq_chip_edge_port = {
|
||||
.name = "CF-INTC-EP",
|
||||
.irq_startup = intc_irq_startup,
|
||||
.irq_mask = intc_irq_mask,
|
||||
.irq_unmask = intc_irq_unmask,
|
||||
.irq_ack = intc_irq_ack,
|
||||
.irq_set_type = intc_irq_set_type,
|
||||
};
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
int irq, eirq;
|
||||
|
||||
/* Mask all interrupt sources */
|
||||
__raw_writeb(0xff, MCFINTC0_SIMR);
|
||||
if (MCFINTC1_SIMR)
|
||||
__raw_writeb(0xff, MCFINTC1_SIMR);
|
||||
if (MCFINTC2_SIMR)
|
||||
__raw_writeb(0xff, MCFINTC2_SIMR);
|
||||
|
||||
eirq = MCFINT_VECBASE + 64 + (MCFINTC1_ICR0 ? 64 : 0) +
|
||||
(MCFINTC2_ICR0 ? 64 : 0);
|
||||
for (irq = MCFINT_VECBASE; (irq < eirq); irq++) {
|
||||
if ((irq >= EINT1) && (irq <= EINT7))
|
||||
irq_set_chip(irq, &intc_irq_chip_edge_port);
|
||||
else
|
||||
irq_set_chip(irq, &intc_irq_chip);
|
||||
irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
|
||||
irq_set_handler(irq, handle_level_irq);
|
||||
}
|
||||
}
|
||||
|
150
arch/m68k/coldfire/intc.c
Normal file
150
arch/m68k/coldfire/intc.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* intc.c -- support for the old ColdFire interrupt controller
|
||||
*
|
||||
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
/*
|
||||
* The mapping of irq number to a mask register bit is not one-to-one.
|
||||
* The irq numbers are either based on "level" of interrupt or fixed
|
||||
* for an autovector-able interrupt. So we keep a local data structure
|
||||
* that maps from irq to mask register. Not all interrupts will have
|
||||
* an IMR bit.
|
||||
*/
|
||||
unsigned char mcf_irq2imr[NR_IRQS];
|
||||
|
||||
/*
|
||||
* Define the miniumun and maximum external interrupt numbers.
|
||||
* This is also used as the "level" interrupt numbers.
|
||||
*/
|
||||
#define EIRQ1 25
|
||||
#define EIRQ7 31
|
||||
|
||||
/*
|
||||
* In the early version 2 core ColdFire parts the IMR register was 16 bits
|
||||
* in size. Version 3 (and later version 2) core parts have a 32 bit
|
||||
* sized IMR register. Provide some size independent methods to access the
|
||||
* IMR register.
|
||||
*/
|
||||
#ifdef MCFSIM_IMR_IS_16BITS
|
||||
|
||||
void mcf_setimr(int index)
|
||||
{
|
||||
u16 imr;
|
||||
imr = __raw_readw(MCFSIM_IMR);
|
||||
__raw_writew(imr | (0x1 << index), MCFSIM_IMR);
|
||||
}
|
||||
|
||||
void mcf_clrimr(int index)
|
||||
{
|
||||
u16 imr;
|
||||
imr = __raw_readw(MCFSIM_IMR);
|
||||
__raw_writew(imr & ~(0x1 << index), MCFSIM_IMR);
|
||||
}
|
||||
|
||||
void mcf_maskimr(unsigned int mask)
|
||||
{
|
||||
u16 imr;
|
||||
imr = __raw_readw(MCFSIM_IMR);
|
||||
imr |= mask;
|
||||
__raw_writew(imr, MCFSIM_IMR);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void mcf_setimr(int index)
|
||||
{
|
||||
u32 imr;
|
||||
imr = __raw_readl(MCFSIM_IMR);
|
||||
__raw_writel(imr | (0x1 << index), MCFSIM_IMR);
|
||||
}
|
||||
|
||||
void mcf_clrimr(int index)
|
||||
{
|
||||
u32 imr;
|
||||
imr = __raw_readl(MCFSIM_IMR);
|
||||
__raw_writel(imr & ~(0x1 << index), MCFSIM_IMR);
|
||||
}
|
||||
|
||||
void mcf_maskimr(unsigned int mask)
|
||||
{
|
||||
u32 imr;
|
||||
imr = __raw_readl(MCFSIM_IMR);
|
||||
imr |= mask;
|
||||
__raw_writel(imr, MCFSIM_IMR);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interrupts can be "vectored" on the ColdFire cores that support this old
|
||||
* interrupt controller. That is, the device raising the interrupt can also
|
||||
* supply the vector number to interrupt through. The AVR register of the
|
||||
* interrupt controller enables or disables this for each external interrupt,
|
||||
* so provide generic support for this. Setting this up is out-of-band for
|
||||
* the interrupt system API's, and needs to be done by the driver that
|
||||
* supports this device. Very few devices actually use this.
|
||||
*/
|
||||
void mcf_autovector(int irq)
|
||||
{
|
||||
#ifdef MCFSIM_AVR
|
||||
if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
|
||||
u8 avec;
|
||||
avec = __raw_readb(MCFSIM_AVR);
|
||||
avec |= (0x1 << (irq - EIRQ1 + 1));
|
||||
__raw_writeb(avec, MCFSIM_AVR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void intc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
if (mcf_irq2imr[d->irq])
|
||||
mcf_setimr(mcf_irq2imr[d->irq]);
|
||||
}
|
||||
|
||||
static void intc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
if (mcf_irq2imr[d->irq])
|
||||
mcf_clrimr(mcf_irq2imr[d->irq]);
|
||||
}
|
||||
|
||||
static int intc_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip intc_irq_chip = {
|
||||
.name = "CF-INTC",
|
||||
.irq_mask = intc_irq_mask,
|
||||
.irq_unmask = intc_irq_unmask,
|
||||
.irq_set_type = intc_irq_set_type,
|
||||
};
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
mcf_maskimr(0xffffffff);
|
||||
|
||||
for (irq = 0; (irq < NR_IRQS); irq++) {
|
||||
irq_set_chip(irq, &intc_irq_chip);
|
||||
irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
|
||||
irq_set_handler(irq, handle_level_irq);
|
||||
}
|
||||
}
|
||||
|
58
arch/m68k/coldfire/m5206.c
Normal file
58
arch/m68k/coldfire/m5206.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m5206.c -- platform support for ColdFire 5206 based boards
|
||||
*
|
||||
* Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2000-2001, Lineo Inc. (www.lineo.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcftmr0,
|
||||
&clk_mcftmr1,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
#if defined(CONFIG_NETtel)
|
||||
/* Copy command line from FLASH to local buffer... */
|
||||
memcpy(commandp, (char *) 0xf0004000, size);
|
||||
commandp[size-1] = 0;
|
||||
#endif /* CONFIG_NETtel */
|
||||
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
/* Only support the external interrupts on their primary level */
|
||||
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
||||
mcf_mapirq2imr(28, MCFINTC_EINT4);
|
||||
mcf_mapirq2imr(31, MCFINTC_EINT7);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
180
arch/m68k/coldfire/m520x.c
Normal file
180
arch/m68k/coldfire/m520x.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m520x.c -- platform support for ColdFire 520x based boards
|
||||
*
|
||||
* Copyright (C) 2005, Freescale (www.freescale.com)
|
||||
* Copyright (C) 2005, Intec Automation (mike@steroidmicros.com)
|
||||
* Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
|
||||
DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
|
||||
DEFINE_CLK(0, "edma", 17, MCF_CLK);
|
||||
DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
|
||||
DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
|
||||
|
||||
DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfeport.0", 34, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfwdt.0", 35, MCF_CLK);
|
||||
DEFINE_CLK(0, "pll.0", 36, MCF_CLK);
|
||||
DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "sdram.0", 42, MCF_CLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&__clk_0_2, /* flexbus */
|
||||
&__clk_0_12, /* fec.0 */
|
||||
&__clk_0_17, /* edma */
|
||||
&__clk_0_18, /* intc.0 */
|
||||
&__clk_0_21, /* iack.0 */
|
||||
&__clk_0_22, /* mcfi2c.0 */
|
||||
&__clk_0_23, /* mcfqspi.0 */
|
||||
&__clk_0_24, /* mcfuart.0 */
|
||||
&__clk_0_25, /* mcfuart.1 */
|
||||
&__clk_0_26, /* mcfuart.2 */
|
||||
&__clk_0_28, /* mcftmr.0 */
|
||||
&__clk_0_29, /* mcftmr.1 */
|
||||
&__clk_0_30, /* mcftmr.2 */
|
||||
&__clk_0_31, /* mcftmr.3 */
|
||||
|
||||
&__clk_0_32, /* mcfpit.0 */
|
||||
&__clk_0_33, /* mcfpit.1 */
|
||||
&__clk_0_34, /* mcfeport.0 */
|
||||
&__clk_0_35, /* mcfwdt.0 */
|
||||
&__clk_0_36, /* pll.0 */
|
||||
&__clk_0_40, /* sys.0 */
|
||||
&__clk_0_41, /* gpio.0 */
|
||||
&__clk_0_42, /* sdram.0 */
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct clk * const enable_clks[] __initconst = {
|
||||
&__clk_0_2, /* flexbus */
|
||||
&__clk_0_18, /* intc.0 */
|
||||
&__clk_0_21, /* iack.0 */
|
||||
&__clk_0_24, /* mcfuart.0 */
|
||||
&__clk_0_25, /* mcfuart.1 */
|
||||
&__clk_0_26, /* mcfuart.2 */
|
||||
|
||||
&__clk_0_32, /* mcfpit.0 */
|
||||
&__clk_0_33, /* mcfpit.1 */
|
||||
&__clk_0_34, /* mcfeport.0 */
|
||||
&__clk_0_36, /* pll.0 */
|
||||
&__clk_0_40, /* sys.0 */
|
||||
&__clk_0_41, /* gpio.0 */
|
||||
&__clk_0_42, /* sdram.0 */
|
||||
};
|
||||
|
||||
static struct clk * const disable_clks[] __initconst = {
|
||||
&__clk_0_12, /* fec.0 */
|
||||
&__clk_0_17, /* edma */
|
||||
&__clk_0_22, /* mcfi2c.0 */
|
||||
&__clk_0_23, /* mcfqspi.0 */
|
||||
&__clk_0_28, /* mcftmr.0 */
|
||||
&__clk_0_29, /* mcftmr.1 */
|
||||
&__clk_0_30, /* mcftmr.2 */
|
||||
&__clk_0_31, /* mcftmr.3 */
|
||||
&__clk_0_35, /* mcfwdt.0 */
|
||||
};
|
||||
|
||||
|
||||
static void __init m520x_clk_init(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* make sure these clocks are enabled */
|
||||
for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
|
||||
__clk_init_enabled(enable_clks[i]);
|
||||
/* make sure these clocks are disabled */
|
||||
for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
|
||||
__clk_init_disabled(disable_clks[i]);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m520x_qspi_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
u16 par;
|
||||
/* setup Port QS for QSPI with gpio CS control */
|
||||
writeb(0x3f, MCF_GPIO_PAR_QSPI);
|
||||
/* make U1CTS and U2RTS gpio for cs_control */
|
||||
par = readw(MCF_GPIO_PAR_UART);
|
||||
par &= 0x00ff;
|
||||
writew(par, MCF_GPIO_PAR_UART);
|
||||
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m520x_uarts_init(void)
|
||||
{
|
||||
u16 par;
|
||||
u8 par2;
|
||||
|
||||
/* UART0 and UART1 GPIO pin setup */
|
||||
par = readw(MCF_GPIO_PAR_UART);
|
||||
par |= MCF_GPIO_PAR_UART_PAR_UTXD0 | MCF_GPIO_PAR_UART_PAR_URXD0;
|
||||
par |= MCF_GPIO_PAR_UART_PAR_UTXD1 | MCF_GPIO_PAR_UART_PAR_URXD1;
|
||||
writew(par, MCF_GPIO_PAR_UART);
|
||||
|
||||
/* UART1 GPIO pin setup */
|
||||
par2 = readb(MCF_GPIO_PAR_FECI2C);
|
||||
par2 &= ~0x0F;
|
||||
par2 |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 |
|
||||
MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
|
||||
writeb(par2, MCF_GPIO_PAR_FECI2C);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m520x_fec_init(void)
|
||||
{
|
||||
u8 v;
|
||||
|
||||
/* Set multi-function pins to ethernet mode */
|
||||
v = readb(MCF_GPIO_PAR_FEC);
|
||||
writeb(v | 0xf0, MCF_GPIO_PAR_FEC);
|
||||
|
||||
v = readb(MCF_GPIO_PAR_FECI2C);
|
||||
writeb(v | 0x0f, MCF_GPIO_PAR_FECI2C);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
mach_sched_init = hw_timer_init;
|
||||
m520x_clk_init();
|
||||
m520x_uarts_init();
|
||||
m520x_fec_init();
|
||||
m520x_qspi_init();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
86
arch/m68k/coldfire/m523x.c
Normal file
86
arch/m68k/coldfire/m523x.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m523x.c -- platform support for ColdFire 523x based boards
|
||||
*
|
||||
* Sub-architcture dependent initialization code for the Freescale
|
||||
* 523x CPUs.
|
||||
*
|
||||
* Copyright (C) 1999-2005, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcfpit0,
|
||||
&clk_mcfpit1,
|
||||
&clk_mcfpit2,
|
||||
&clk_mcfpit3,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
&clk_mcfuart2,
|
||||
&clk_mcfqspi0,
|
||||
&clk_fec0,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m523x_qspi_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
u16 par;
|
||||
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writeb(0x1f, MCFGPIO_PAR_QSPI);
|
||||
/* and CS2 & CS3 as gpio */
|
||||
par = readw(MCFGPIO_PAR_TIMER);
|
||||
par &= 0x3f3f;
|
||||
writew(par, MCFGPIO_PAR_TIMER);
|
||||
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m523x_fec_init(void)
|
||||
{
|
||||
/* Set multi-function pins to ethernet use */
|
||||
writeb(readb(MCFGPIO_PAR_FECI2C) | 0xf0, MCFGPIO_PAR_FECI2C);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
mach_sched_init = hw_timer_init;
|
||||
m523x_fec_init();
|
||||
m523x_qspi_init();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
126
arch/m68k/coldfire/m5249.c
Normal file
126
arch/m68k/coldfire/m5249.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m5249.c -- platform support for ColdFire 5249 based boards
|
||||
*
|
||||
* Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcftmr0,
|
||||
&clk_mcftmr1,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
&clk_mcfqspi0,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef CONFIG_M5249C3
|
||||
|
||||
static struct resource m5249_smc91x_resources[] = {
|
||||
{
|
||||
.start = 0xe0000300,
|
||||
.end = 0xe0000300 + 0x100,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_GPIO6,
|
||||
.end = MCF_IRQ_GPIO6,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device m5249_smc91x = {
|
||||
.name = "smc91x",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(m5249_smc91x_resources),
|
||||
.resource = m5249_smc91x_resources,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_M5249C3 */
|
||||
|
||||
static struct platform_device *m5249_devices[] __initdata = {
|
||||
#ifdef CONFIG_M5249C3
|
||||
&m5249_smc91x,
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m5249_qspi_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
/* QSPI irq setup */
|
||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
|
||||
MCFSIM_QSPIICR);
|
||||
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
|
||||
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef CONFIG_M5249C3
|
||||
|
||||
static void __init m5249_smc91x_init(void)
|
||||
{
|
||||
u32 gpio;
|
||||
|
||||
/* Set the GPIO line as interrupt source for smc91x device */
|
||||
gpio = readl(MCFSIM2_GPIOINTENABLE);
|
||||
writel(gpio | 0x40, MCFSIM2_GPIOINTENABLE);
|
||||
|
||||
gpio = readl(MCFINTC2_INTPRI5);
|
||||
writel(gpio | 0x04000000, MCFINTC2_INTPRI5);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_M5249C3 */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
#ifdef CONFIG_M5249C3
|
||||
m5249_smc91x_init();
|
||||
#endif
|
||||
m5249_qspi_init();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static int __init init_BSP(void)
|
||||
{
|
||||
platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(init_BSP);
|
||||
|
||||
/***************************************************************************/
|
88
arch/m68k/coldfire/m525x.c
Normal file
88
arch/m68k/coldfire/m525x.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* 525x.c -- platform support for ColdFire 525x based boards
|
||||
*
|
||||
* Copyright (C) 2012, Steven King <sfking@fdwdc.com>
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcftmr0,
|
||||
&clk_mcftmr1,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
&clk_mcfqspi0,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m525x_qspi_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
/* set the GPIO function for the qspi cs gpios */
|
||||
/* FIXME: replace with pinmux/pinctl support */
|
||||
u32 f = readl(MCFSIM2_GPIOFUNC);
|
||||
f |= (1 << MCFQSPI_CS2) | (1 << MCFQSPI_CS1) | (1 << MCFQSPI_CS0);
|
||||
writel(f, MCFSIM2_GPIOFUNC);
|
||||
|
||||
/* QSPI irq setup */
|
||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
|
||||
MCFSIM_QSPIICR);
|
||||
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
|
||||
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
|
||||
}
|
||||
|
||||
static void __init m525x_i2c_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_I2C_COLDFIRE)
|
||||
u32 r;
|
||||
|
||||
/* first I2C controller uses regular irq setup */
|
||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0,
|
||||
MCFSIM_I2CICR);
|
||||
mcf_mapirq2imr(MCF_IRQ_I2C0, MCFINTC_I2C);
|
||||
|
||||
/* second I2C controller is completely different */
|
||||
r = readl(MCFINTC2_INTPRI_REG(MCF_IRQ_I2C1));
|
||||
r &= ~MCFINTC2_INTPRI_BITS(0xf, MCF_IRQ_I2C1);
|
||||
r |= MCFINTC2_INTPRI_BITS(0x5, MCF_IRQ_I2C1);
|
||||
writel(r, MCFINTC2_INTPRI_REG(MCF_IRQ_I2C1));
|
||||
#endif /* IS_ENABLED(CONFIG_I2C_COLDFIRE) */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
m525x_qspi_init();
|
||||
m525x_i2c_init();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
135
arch/m68k/coldfire/m5272.c
Normal file
135
arch/m68k/coldfire/m5272.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m5272.c -- platform support for ColdFire 5272 based boards
|
||||
*
|
||||
* Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2001-2002, SnapGear Inc. (www.snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/phy_fixed.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Some platforms need software versions of the GPIO data registers.
|
||||
*/
|
||||
unsigned short ppdata;
|
||||
unsigned char ledbank = 0xff;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr2, "mcftmr.2", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr3, "mcftmr.3", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcftmr0,
|
||||
&clk_mcftmr1,
|
||||
&clk_mcftmr2,
|
||||
&clk_mcftmr3,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
&clk_mcfqspi0,
|
||||
&clk_fec0,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m5272_uarts_init(void)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
/* Enable the output lines for the serial ports */
|
||||
v = readl(MCFSIM_PBCNT);
|
||||
v = (v & ~0x000000ff) | 0x00000055;
|
||||
writel(v, MCFSIM_PBCNT);
|
||||
|
||||
v = readl(MCFSIM_PDCNT);
|
||||
v = (v & ~0x000003fc) | 0x000002a8;
|
||||
writel(v, MCFSIM_PDCNT);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void m5272_cpu_reset(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
/* Set watchdog to reset, and enabled */
|
||||
__raw_writew(0, MCFSIM_WIRR);
|
||||
__raw_writew(1, MCFSIM_WRRR);
|
||||
__raw_writew(0, MCFSIM_WCR);
|
||||
for (;;)
|
||||
/* wait for watchdog to timeout */;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
#if defined (CONFIG_MOD5272)
|
||||
/* Set base of device vectors to be 64 */
|
||||
writeb(0x40, MCFSIM_PIVR);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NETtel) || defined(CONFIG_SCALES)
|
||||
/* Copy command line from FLASH to local buffer... */
|
||||
memcpy(commandp, (char *) 0xf0004000, size);
|
||||
commandp[size-1] = 0;
|
||||
#elif defined(CONFIG_CANCam)
|
||||
/* Copy command line from FLASH to local buffer... */
|
||||
memcpy(commandp, (char *) 0xf0010000, size);
|
||||
commandp[size-1] = 0;
|
||||
#endif
|
||||
|
||||
mach_reset = m5272_cpu_reset;
|
||||
mach_sched_init = hw_timer_init;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Some 5272 based boards have the FEC ethernet diectly connected to
|
||||
* an ethernet switch. In this case we need to use the fixed phy type,
|
||||
* and we need to declare it early in boot.
|
||||
*/
|
||||
static struct fixed_phy_status nettel_fixed_phy_status __initdata = {
|
||||
.link = 1,
|
||||
.speed = 100,
|
||||
.duplex = 0,
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static int __init init_BSP(void)
|
||||
{
|
||||
m5272_uarts_init();
|
||||
fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(init_BSP);
|
||||
|
||||
/***************************************************************************/
|
126
arch/m68k/coldfire/m527x.c
Normal file
126
arch/m68k/coldfire/m527x.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m527x.c -- platform support for ColdFire 527x based boards
|
||||
*
|
||||
* Sub-architcture dependent initialization code for the Freescale
|
||||
* 5270/5271 and 5274/5275 CPUs.
|
||||
*
|
||||
* Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(fec1, "fec.1", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcfpit0,
|
||||
&clk_mcfpit1,
|
||||
&clk_mcfpit2,
|
||||
&clk_mcfpit3,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
&clk_mcfuart2,
|
||||
&clk_mcfqspi0,
|
||||
&clk_fec0,
|
||||
&clk_fec1,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m527x_qspi_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
#if defined(CONFIG_M5271)
|
||||
u16 par;
|
||||
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writeb(0x1f, MCFGPIO_PAR_QSPI);
|
||||
/* and CS2 & CS3 as gpio */
|
||||
par = readw(MCFGPIO_PAR_TIMER);
|
||||
par &= 0x3f3f;
|
||||
writew(par, MCFGPIO_PAR_TIMER);
|
||||
#elif defined(CONFIG_M5275)
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writew(0x003e, MCFGPIO_PAR_QSPI);
|
||||
#endif
|
||||
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m527x_uarts_init(void)
|
||||
{
|
||||
u16 sepmask;
|
||||
|
||||
/*
|
||||
* External Pin Mask Setting & Enable External Pin for Interface
|
||||
*/
|
||||
sepmask = readw(MCFGPIO_PAR_UART);
|
||||
sepmask |= UART0_ENABLE_MASK | UART1_ENABLE_MASK | UART2_ENABLE_MASK;
|
||||
writew(sepmask, MCFGPIO_PAR_UART);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m527x_fec_init(void)
|
||||
{
|
||||
u16 par;
|
||||
u8 v;
|
||||
|
||||
/* Set multi-function pins to ethernet mode for fec0 */
|
||||
#if defined(CONFIG_M5271)
|
||||
v = readb(MCFGPIO_PAR_FECI2C);
|
||||
writeb(v | 0xf0, MCFGPIO_PAR_FECI2C);
|
||||
#else
|
||||
par = readw(MCFGPIO_PAR_FECI2C);
|
||||
writew(par | 0xf00, MCFGPIO_PAR_FECI2C);
|
||||
v = readb(MCFGPIO_PAR_FEC0HL);
|
||||
writeb(v | 0xc0, MCFGPIO_PAR_FEC0HL);
|
||||
|
||||
/* Set multi-function pins to ethernet mode for fec1 */
|
||||
par = readw(MCFGPIO_PAR_FECI2C);
|
||||
writew(par | 0xa0, MCFGPIO_PAR_FECI2C);
|
||||
v = readb(MCFGPIO_PAR_FEC1HL);
|
||||
writeb(v | 0xc0, MCFGPIO_PAR_FEC1HL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
mach_sched_init = hw_timer_init;
|
||||
m527x_uarts_init();
|
||||
m527x_fec_init();
|
||||
m527x_qspi_init();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
132
arch/m68k/coldfire/m528x.c
Normal file
132
arch/m68k/coldfire/m528x.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m528x.c -- platform support for ColdFire 528x based boards
|
||||
*
|
||||
* Sub-architcture dependent initialization code for the Freescale
|
||||
* 5280, 5281 and 5282 CPUs.
|
||||
*
|
||||
* Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK);
|
||||
DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcfpit0,
|
||||
&clk_mcfpit1,
|
||||
&clk_mcfpit2,
|
||||
&clk_mcfpit3,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
&clk_mcfuart2,
|
||||
&clk_mcfqspi0,
|
||||
&clk_fec0,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m528x_qspi_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
/* setup Port QS for QSPI with gpio CS control */
|
||||
__raw_writeb(0x07, MCFGPIO_PQSPAR);
|
||||
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m528x_uarts_init(void)
|
||||
{
|
||||
u8 port;
|
||||
|
||||
/* make sure PUAPAR is set for UART0 and UART1 */
|
||||
port = readb(MCFGPIO_PUAPAR);
|
||||
port |= 0x03 | (0x03 << 2);
|
||||
writeb(port, MCFGPIO_PUAPAR);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m528x_fec_init(void)
|
||||
{
|
||||
u16 v16;
|
||||
|
||||
/* Set multi-function pins to ethernet mode for fec0 */
|
||||
v16 = readw(MCFGPIO_PASPAR);
|
||||
writew(v16 | 0xf00, MCFGPIO_PASPAR);
|
||||
writeb(0xc0, MCFGPIO_PEHLPAR);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef CONFIG_WILDFIRE
|
||||
void wildfire_halt(void)
|
||||
{
|
||||
writeb(0, 0x30000007);
|
||||
writeb(0x2, 0x30000007);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WILDFIREMOD
|
||||
void wildfiremod_halt(void)
|
||||
{
|
||||
printk(KERN_INFO "WildFireMod hibernating...\n");
|
||||
|
||||
/* Set portE.5 to Digital IO */
|
||||
MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));
|
||||
|
||||
/* Make portE.5 an output */
|
||||
MCF5282_GPIO_DDRE |= (1 << 5);
|
||||
|
||||
/* Now toggle portE.5 from low to high */
|
||||
MCF5282_GPIO_PORTE &= ~(1 << 5);
|
||||
MCF5282_GPIO_PORTE |= (1 << 5);
|
||||
|
||||
printk(KERN_EMERG "Failed to hibernate. Halting!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
#ifdef CONFIG_WILDFIRE
|
||||
mach_halt = wildfire_halt;
|
||||
#endif
|
||||
#ifdef CONFIG_WILDFIREMOD
|
||||
mach_halt = wildfiremod_halt;
|
||||
#endif
|
||||
mach_sched_init = hw_timer_init;
|
||||
m528x_uarts_init();
|
||||
m528x_fec_init();
|
||||
m528x_qspi_init();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
78
arch/m68k/coldfire/m5307.c
Normal file
78
arch/m68k/coldfire/m5307.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m5307.c -- platform support for ColdFire 5307 based boards
|
||||
*
|
||||
* Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2000, Lineo (www.lineo.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfwdebug.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Some platforms need software versions of the GPIO data registers.
|
||||
*/
|
||||
unsigned short ppdata;
|
||||
unsigned char ledbank = 0xff;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcftmr0,
|
||||
&clk_mcftmr1,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
#if defined(CONFIG_NETtel) || \
|
||||
defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
|
||||
/* Copy command line from FLASH to local buffer... */
|
||||
memcpy(commandp, (char *) 0xf0004000, size);
|
||||
commandp[size-1] = 0;
|
||||
#endif
|
||||
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
/* Only support the external interrupts on their primary level */
|
||||
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
||||
mcf_mapirq2imr(27, MCFINTC_EINT3);
|
||||
mcf_mapirq2imr(29, MCFINTC_EINT5);
|
||||
mcf_mapirq2imr(31, MCFINTC_EINT7);
|
||||
|
||||
#ifdef CONFIG_BDM_DISABLE
|
||||
/*
|
||||
* Disable the BDM clocking. This also turns off most of the rest of
|
||||
* the BDM device. This is good for EMC reasons. This option is not
|
||||
* incompatible with the memory protection option.
|
||||
*/
|
||||
wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
588
arch/m68k/coldfire/m53xx.c
Normal file
588
arch/m68k/coldfire/m53xx.c
Normal file
|
@ -0,0 +1,588 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m53xx.c -- platform support for ColdFire 53xx based boards
|
||||
*
|
||||
* Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2000, Lineo (www.lineo.com)
|
||||
* Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
|
||||
* Copyright Freescale Semiconductor, Inc 2006
|
||||
* Copyright (c) 2006, emlix, Sebastian Hess <shess@hessware.de>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfdma.h>
|
||||
#include <asm/mcfwdebug.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
|
||||
DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
|
||||
DEFINE_CLK(0, "edma", 17, MCF_CLK);
|
||||
DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
|
||||
DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
|
||||
DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
|
||||
|
||||
DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK);
|
||||
DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
|
||||
DEFINE_CLK(0, "sdram.0", 46, MCF_CLK);
|
||||
DEFINE_CLK(0, "ssi.0", 47, MCF_CLK);
|
||||
DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
|
||||
|
||||
DEFINE_CLK(1, "mdha.0", 32, MCF_CLK);
|
||||
DEFINE_CLK(1, "skha.0", 33, MCF_CLK);
|
||||
DEFINE_CLK(1, "rng.0", 34, MCF_CLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&__clk_0_2, /* flexbus */
|
||||
&__clk_0_8, /* mcfcan.0 */
|
||||
&__clk_0_12, /* fec.0 */
|
||||
&__clk_0_17, /* edma */
|
||||
&__clk_0_18, /* intc.0 */
|
||||
&__clk_0_19, /* intc.1 */
|
||||
&__clk_0_21, /* iack.0 */
|
||||
&__clk_0_22, /* mcfi2c.0 */
|
||||
&__clk_0_23, /* mcfqspi.0 */
|
||||
&__clk_0_24, /* mcfuart.0 */
|
||||
&__clk_0_25, /* mcfuart.1 */
|
||||
&__clk_0_26, /* mcfuart.2 */
|
||||
&__clk_0_28, /* mcftmr.0 */
|
||||
&__clk_0_29, /* mcftmr.1 */
|
||||
&__clk_0_30, /* mcftmr.2 */
|
||||
&__clk_0_31, /* mcftmr.3 */
|
||||
|
||||
&__clk_0_32, /* mcfpit.0 */
|
||||
&__clk_0_33, /* mcfpit.1 */
|
||||
&__clk_0_34, /* mcfpit.2 */
|
||||
&__clk_0_35, /* mcfpit.3 */
|
||||
&__clk_0_36, /* mcfpwm.0 */
|
||||
&__clk_0_37, /* mcfeport.0 */
|
||||
&__clk_0_38, /* mcfwdt.0 */
|
||||
&__clk_0_40, /* sys.0 */
|
||||
&__clk_0_41, /* gpio.0 */
|
||||
&__clk_0_42, /* mcfrtc.0 */
|
||||
&__clk_0_43, /* mcflcd.0 */
|
||||
&__clk_0_44, /* mcfusb-otg.0 */
|
||||
&__clk_0_45, /* mcfusb-host.0 */
|
||||
&__clk_0_46, /* sdram.0 */
|
||||
&__clk_0_47, /* ssi.0 */
|
||||
&__clk_0_48, /* pll.0 */
|
||||
|
||||
&__clk_1_32, /* mdha.0 */
|
||||
&__clk_1_33, /* skha.0 */
|
||||
&__clk_1_34, /* rng.0 */
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct clk * const enable_clks[] __initconst = {
|
||||
&__clk_0_2, /* flexbus */
|
||||
&__clk_0_18, /* intc.0 */
|
||||
&__clk_0_19, /* intc.1 */
|
||||
&__clk_0_21, /* iack.0 */
|
||||
&__clk_0_24, /* mcfuart.0 */
|
||||
&__clk_0_25, /* mcfuart.1 */
|
||||
&__clk_0_26, /* mcfuart.2 */
|
||||
&__clk_0_28, /* mcftmr.0 */
|
||||
&__clk_0_29, /* mcftmr.1 */
|
||||
&__clk_0_32, /* mcfpit.0 */
|
||||
&__clk_0_33, /* mcfpit.1 */
|
||||
&__clk_0_37, /* mcfeport.0 */
|
||||
&__clk_0_40, /* sys.0 */
|
||||
&__clk_0_41, /* gpio.0 */
|
||||
&__clk_0_46, /* sdram.0 */
|
||||
&__clk_0_48, /* pll.0 */
|
||||
};
|
||||
|
||||
static struct clk * const disable_clks[] __initconst = {
|
||||
&__clk_0_8, /* mcfcan.0 */
|
||||
&__clk_0_12, /* fec.0 */
|
||||
&__clk_0_17, /* edma */
|
||||
&__clk_0_22, /* mcfi2c.0 */
|
||||
&__clk_0_23, /* mcfqspi.0 */
|
||||
&__clk_0_30, /* mcftmr.2 */
|
||||
&__clk_0_31, /* mcftmr.3 */
|
||||
&__clk_0_34, /* mcfpit.2 */
|
||||
&__clk_0_35, /* mcfpit.3 */
|
||||
&__clk_0_36, /* mcfpwm.0 */
|
||||
&__clk_0_38, /* mcfwdt.0 */
|
||||
&__clk_0_42, /* mcfrtc.0 */
|
||||
&__clk_0_43, /* mcflcd.0 */
|
||||
&__clk_0_44, /* mcfusb-otg.0 */
|
||||
&__clk_0_45, /* mcfusb-host.0 */
|
||||
&__clk_0_47, /* ssi.0 */
|
||||
&__clk_1_32, /* mdha.0 */
|
||||
&__clk_1_33, /* skha.0 */
|
||||
&__clk_1_34, /* rng.0 */
|
||||
};
|
||||
|
||||
|
||||
static void __init m53xx_clk_init(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* make sure these clocks are enabled */
|
||||
for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
|
||||
__clk_init_enabled(enable_clks[i]);
|
||||
/* make sure these clocks are disabled */
|
||||
for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
|
||||
__clk_init_disabled(disable_clks[i]);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m53xx_qspi_init(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writew(0x01f0, MCFGPIO_PAR_QSPI);
|
||||
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m53xx_uarts_init(void)
|
||||
{
|
||||
/* UART GPIO initialization */
|
||||
writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m53xx_fec_init(void)
|
||||
{
|
||||
u8 v;
|
||||
|
||||
/* Set multi-function pins to ethernet mode for fec0 */
|
||||
v = readb(MCFGPIO_PAR_FECI2C);
|
||||
v |= MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
|
||||
MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO;
|
||||
writeb(v, MCFGPIO_PAR_FECI2C);
|
||||
|
||||
v = readb(MCFGPIO_PAR_FEC);
|
||||
v = MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC;
|
||||
writeb(v, MCFGPIO_PAR_FEC);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
#if !defined(CONFIG_BOOTPARAM)
|
||||
/* Copy command line from FLASH to local buffer... */
|
||||
memcpy(commandp, (char *) 0x4000, 4);
|
||||
if(strncmp(commandp, "kcl ", 4) == 0){
|
||||
memcpy(commandp, (char *) 0x4004, size);
|
||||
commandp[size-1] = 0;
|
||||
} else {
|
||||
memset(commandp, 0, size);
|
||||
}
|
||||
#endif
|
||||
mach_sched_init = hw_timer_init;
|
||||
m53xx_clk_init();
|
||||
m53xx_uarts_init();
|
||||
m53xx_fec_init();
|
||||
m53xx_qspi_init();
|
||||
|
||||
#ifdef CONFIG_BDM_DISABLE
|
||||
/*
|
||||
* Disable the BDM clocking. This also turns off most of the rest of
|
||||
* the BDM device. This is good for EMC reasons. This option is not
|
||||
* incompatible with the memory protection option.
|
||||
*/
|
||||
wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Board initialization */
|
||||
/***************************************************************************/
|
||||
/*
|
||||
* PLL min/max specifications
|
||||
*/
|
||||
#define MAX_FVCO 500000 /* KHz */
|
||||
#define MAX_FSYS 80000 /* KHz */
|
||||
#define MIN_FSYS 58333 /* KHz */
|
||||
#define FREF 16000 /* KHz */
|
||||
|
||||
|
||||
#define MAX_MFD 135 /* Multiplier */
|
||||
#define MIN_MFD 88 /* Multiplier */
|
||||
#define BUSDIV 6 /* Divider */
|
||||
|
||||
/*
|
||||
* Low Power Divider specifications
|
||||
*/
|
||||
#define MIN_LPD (1 << 0) /* Divider (not encoded) */
|
||||
#define MAX_LPD (1 << 15) /* Divider (not encoded) */
|
||||
#define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */
|
||||
|
||||
#define SYS_CLK_KHZ 80000
|
||||
#define SYSTEM_PERIOD 12.5
|
||||
/*
|
||||
* SDRAM Timing Parameters
|
||||
*/
|
||||
#define SDRAM_BL 8 /* # of beats in a burst */
|
||||
#define SDRAM_TWR 2 /* in clocks */
|
||||
#define SDRAM_CASL 2.5 /* CASL in clocks */
|
||||
#define SDRAM_TRCD 2 /* in clocks */
|
||||
#define SDRAM_TRP 2 /* in clocks */
|
||||
#define SDRAM_TRFC 7 /* in clocks */
|
||||
#define SDRAM_TREFI 7800 /* in ns */
|
||||
|
||||
#define EXT_SRAM_ADDRESS (0xC0000000)
|
||||
#define FLASH_ADDRESS (0x00000000)
|
||||
#define SDRAM_ADDRESS (0x40000000)
|
||||
|
||||
#define NAND_FLASH_ADDRESS (0xD0000000)
|
||||
|
||||
int sys_clk_khz = 0;
|
||||
int sys_clk_mhz = 0;
|
||||
|
||||
void wtm_init(void);
|
||||
void scm_init(void);
|
||||
void gpio_init(void);
|
||||
void fbcs_init(void);
|
||||
void sdramc_init(void);
|
||||
int clock_pll (int fsys, int flags);
|
||||
int clock_limp (int);
|
||||
int clock_exit_limp (void);
|
||||
int get_sys_clock (void);
|
||||
|
||||
asmlinkage void __init sysinit(void)
|
||||
{
|
||||
sys_clk_khz = clock_pll(0, 0);
|
||||
sys_clk_mhz = sys_clk_khz/1000;
|
||||
|
||||
wtm_init();
|
||||
scm_init();
|
||||
gpio_init();
|
||||
fbcs_init();
|
||||
sdramc_init();
|
||||
}
|
||||
|
||||
void wtm_init(void)
|
||||
{
|
||||
/* Disable watchdog timer */
|
||||
writew(0, MCF_WTM_WCR);
|
||||
}
|
||||
|
||||
#define MCF_SCM_BCR_GBW (0x00000100)
|
||||
#define MCF_SCM_BCR_GBR (0x00000200)
|
||||
|
||||
void scm_init(void)
|
||||
{
|
||||
/* All masters are trusted */
|
||||
writel(0x77777777, MCF_SCM_MPR);
|
||||
|
||||
/* Allow supervisor/user, read/write, and trusted/untrusted
|
||||
access to all slaves */
|
||||
writel(0, MCF_SCM_PACRA);
|
||||
writel(0, MCF_SCM_PACRB);
|
||||
writel(0, MCF_SCM_PACRC);
|
||||
writel(0, MCF_SCM_PACRD);
|
||||
writel(0, MCF_SCM_PACRE);
|
||||
writel(0, MCF_SCM_PACRF);
|
||||
|
||||
/* Enable bursts */
|
||||
writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
|
||||
}
|
||||
|
||||
|
||||
void fbcs_init(void)
|
||||
{
|
||||
writeb(0x3E, MCFGPIO_PAR_CS);
|
||||
|
||||
/* Latch chip select */
|
||||
writel(0x10080000, MCF_FBCS1_CSAR);
|
||||
|
||||
writel(0x002A3780, MCF_FBCS1_CSCR);
|
||||
writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
|
||||
|
||||
/* Initialize latch to drive signals to inactive states */
|
||||
writew(0xffff, 0x10080000);
|
||||
|
||||
/* External SRAM */
|
||||
writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
|
||||
writel(MCF_FBCS_CSCR_PS_16 |
|
||||
MCF_FBCS_CSCR_AA |
|
||||
MCF_FBCS_CSCR_SBM |
|
||||
MCF_FBCS_CSCR_WS(1),
|
||||
MCF_FBCS1_CSCR);
|
||||
writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
|
||||
|
||||
/* Boot Flash connected to FBCS0 */
|
||||
writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
|
||||
writel(MCF_FBCS_CSCR_PS_16 |
|
||||
MCF_FBCS_CSCR_BEM |
|
||||
MCF_FBCS_CSCR_AA |
|
||||
MCF_FBCS_CSCR_SBM |
|
||||
MCF_FBCS_CSCR_WS(7),
|
||||
MCF_FBCS0_CSCR);
|
||||
writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
|
||||
}
|
||||
|
||||
void sdramc_init(void)
|
||||
{
|
||||
/*
|
||||
* Check to see if the SDRAM has already been initialized
|
||||
* by a run control tool
|
||||
*/
|
||||
if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
|
||||
/* SDRAM chip select initialization */
|
||||
|
||||
/* Initialize SDRAM chip select */
|
||||
writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
|
||||
MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
|
||||
MCF_SDRAMC_SDCS0);
|
||||
|
||||
/*
|
||||
* Basic configuration and initialization
|
||||
*/
|
||||
writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
|
||||
MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
|
||||
MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
|
||||
MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
|
||||
MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
|
||||
MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
|
||||
MCF_SDRAMC_SDCFG1_WTLAT(3),
|
||||
MCF_SDRAMC_SDCFG1);
|
||||
writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
|
||||
MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
|
||||
MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
|
||||
MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
|
||||
MCF_SDRAMC_SDCFG2);
|
||||
|
||||
|
||||
/*
|
||||
* Precharge and enable write to SDMR
|
||||
*/
|
||||
writel(MCF_SDRAMC_SDCR_MODE_EN |
|
||||
MCF_SDRAMC_SDCR_CKE |
|
||||
MCF_SDRAMC_SDCR_DDR |
|
||||
MCF_SDRAMC_SDCR_MUX(1) |
|
||||
MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
|
||||
MCF_SDRAMC_SDCR_PS_16 |
|
||||
MCF_SDRAMC_SDCR_IPALL,
|
||||
MCF_SDRAMC_SDCR);
|
||||
|
||||
/*
|
||||
* Write extended mode register
|
||||
*/
|
||||
writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
|
||||
MCF_SDRAMC_SDMR_AD(0x0) |
|
||||
MCF_SDRAMC_SDMR_CMD,
|
||||
MCF_SDRAMC_SDMR);
|
||||
|
||||
/*
|
||||
* Write mode register and reset DLL
|
||||
*/
|
||||
writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
|
||||
MCF_SDRAMC_SDMR_AD(0x163) |
|
||||
MCF_SDRAMC_SDMR_CMD,
|
||||
MCF_SDRAMC_SDMR);
|
||||
|
||||
/*
|
||||
* Execute a PALL command
|
||||
*/
|
||||
writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
|
||||
|
||||
/*
|
||||
* Perform two REF cycles
|
||||
*/
|
||||
writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
|
||||
writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
|
||||
|
||||
/*
|
||||
* Write mode register and clear reset DLL
|
||||
*/
|
||||
writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
|
||||
MCF_SDRAMC_SDMR_AD(0x063) |
|
||||
MCF_SDRAMC_SDMR_CMD,
|
||||
MCF_SDRAMC_SDMR);
|
||||
|
||||
/*
|
||||
* Enable auto refresh and lock SDMR
|
||||
*/
|
||||
writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
|
||||
MCF_SDRAMC_SDCR);
|
||||
writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
|
||||
MCF_SDRAMC_SDCR);
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_init(void)
|
||||
{
|
||||
/* Enable UART0 pins */
|
||||
writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
|
||||
MCFGPIO_PAR_UART);
|
||||
|
||||
/*
|
||||
* Initialize TIN3 as a GPIO output to enable the write
|
||||
* half of the latch.
|
||||
*/
|
||||
writeb(0x00, MCFGPIO_PAR_TIMER);
|
||||
writeb(0x08, MCFGPIO_PDDR_TIMER);
|
||||
writeb(0x00, MCFGPIO_PCLRR_TIMER);
|
||||
}
|
||||
|
||||
int clock_pll(int fsys, int flags)
|
||||
{
|
||||
int fref, temp, fout, mfd;
|
||||
u32 i;
|
||||
|
||||
fref = FREF;
|
||||
|
||||
if (fsys == 0) {
|
||||
/* Return current PLL output */
|
||||
mfd = readb(MCF_PLL_PFDR);
|
||||
|
||||
return (fref * mfd / (BUSDIV * 4));
|
||||
}
|
||||
|
||||
/* Check bounds of requested system clock */
|
||||
if (fsys > MAX_FSYS)
|
||||
fsys = MAX_FSYS;
|
||||
if (fsys < MIN_FSYS)
|
||||
fsys = MIN_FSYS;
|
||||
|
||||
/* Multiplying by 100 when calculating the temp value,
|
||||
and then dividing by 100 to calculate the mfd allows
|
||||
for exact values without needing to include floating
|
||||
point libraries. */
|
||||
temp = 100 * fsys / fref;
|
||||
mfd = 4 * BUSDIV * temp / 100;
|
||||
|
||||
/* Determine the output frequency for selected values */
|
||||
fout = (fref * mfd / (BUSDIV * 4));
|
||||
|
||||
/*
|
||||
* Check to see if the SDRAM has already been initialized.
|
||||
* If it has then the SDRAM needs to be put into self refresh
|
||||
* mode before reprogramming the PLL.
|
||||
*/
|
||||
if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
|
||||
/* Put SDRAM into self refresh mode */
|
||||
writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
|
||||
MCF_SDRAMC_SDCR);
|
||||
|
||||
/*
|
||||
* Initialize the PLL to generate the new system clock frequency.
|
||||
* The device must be put into LIMP mode to reprogram the PLL.
|
||||
*/
|
||||
|
||||
/* Enter LIMP mode */
|
||||
clock_limp(DEFAULT_LPD);
|
||||
|
||||
/* Reprogram PLL for desired fsys */
|
||||
writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
|
||||
MCF_PLL_PODR);
|
||||
|
||||
writeb(mfd, MCF_PLL_PFDR);
|
||||
|
||||
/* Exit LIMP mode */
|
||||
clock_exit_limp();
|
||||
|
||||
/*
|
||||
* Return the SDRAM to normal operation if it is in use.
|
||||
*/
|
||||
if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
|
||||
/* Exit self refresh mode */
|
||||
writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
|
||||
MCF_SDRAMC_SDCR);
|
||||
|
||||
/* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
|
||||
writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
|
||||
|
||||
/* wait for DQS logic to relock */
|
||||
for (i = 0; i < 0x200; i++)
|
||||
;
|
||||
|
||||
return fout;
|
||||
}
|
||||
|
||||
int clock_limp(int div)
|
||||
{
|
||||
u32 temp;
|
||||
|
||||
/* Check bounds of divider */
|
||||
if (div < MIN_LPD)
|
||||
div = MIN_LPD;
|
||||
if (div > MAX_LPD)
|
||||
div = MAX_LPD;
|
||||
|
||||
/* Save of the current value of the SSIDIV so we don't
|
||||
overwrite the value*/
|
||||
temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
|
||||
|
||||
/* Apply the divider to the system clock */
|
||||
writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
|
||||
|
||||
writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
|
||||
|
||||
return (FREF/(3*(1 << div)));
|
||||
}
|
||||
|
||||
int clock_exit_limp(void)
|
||||
{
|
||||
int fout;
|
||||
|
||||
/* Exit LIMP mode */
|
||||
writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
|
||||
|
||||
/* Wait for PLL to lock */
|
||||
while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
|
||||
;
|
||||
|
||||
fout = get_sys_clock();
|
||||
|
||||
return fout;
|
||||
}
|
||||
|
||||
int get_sys_clock(void)
|
||||
{
|
||||
int divider;
|
||||
|
||||
/* Test to see if device is in LIMP mode */
|
||||
if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
|
||||
divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
|
||||
return (FREF/(2 << divider));
|
||||
}
|
||||
else
|
||||
return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
|
||||
}
|
53
arch/m68k/coldfire/m5407.c
Normal file
53
arch/m68k/coldfire/m5407.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m5407.c -- platform support for ColdFire 5407 based boards
|
||||
*
|
||||
* Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2000, Lineo (www.lineo.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcftmr0,
|
||||
&clk_mcftmr1,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
/* Only support the external interrupts on their primary level */
|
||||
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
||||
mcf_mapirq2imr(27, MCFINTC_EINT3);
|
||||
mcf_mapirq2imr(29, MCFINTC_EINT5);
|
||||
mcf_mapirq2imr(31, MCFINTC_EINT7);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
261
arch/m68k/coldfire/m5441x.c
Normal file
261
arch/m68k/coldfire/m5441x.c
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* m5441x.c -- support for Coldfire m5441x processors
|
||||
*
|
||||
* (C) Copyright Steven King <sfking@fdwdc.com>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfdma.h>
|
||||
#include <asm/mcfclk.h>
|
||||
|
||||
DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfcan.1", 9, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfi2c.1", 14, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfdspi.1", 15, MCF_CLK);
|
||||
DEFINE_CLK(0, "edma", 17, MCF_CLK);
|
||||
DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
|
||||
DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
|
||||
DEFINE_CLK(0, "intc.2", 20, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfdspi.0", 23, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcfuart.3", 27, MCF_BUSCLK);
|
||||
DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfadc.0", 38, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfdac.0", 39, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfsim.0", 43, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfddr-sram.0", 46, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfssi.0", 47, MCF_CLK);
|
||||
DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfrng.0", 49, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfssi.1", 50, MCF_CLK);
|
||||
DEFINE_CLK(0, "mcfsdhc.0", 51, MCF_CLK);
|
||||
DEFINE_CLK(0, "enet-fec.0", 53, MCF_CLK);
|
||||
DEFINE_CLK(0, "enet-fec.1", 54, MCF_CLK);
|
||||
DEFINE_CLK(0, "switch.0", 55, MCF_CLK);
|
||||
DEFINE_CLK(0, "switch.1", 56, MCF_CLK);
|
||||
DEFINE_CLK(0, "nand.0", 63, MCF_CLK);
|
||||
|
||||
DEFINE_CLK(1, "mcfow.0", 2, MCF_CLK);
|
||||
DEFINE_CLK(1, "mcfi2c.2", 4, MCF_CLK);
|
||||
DEFINE_CLK(1, "mcfi2c.3", 5, MCF_CLK);
|
||||
DEFINE_CLK(1, "mcfi2c.4", 6, MCF_CLK);
|
||||
DEFINE_CLK(1, "mcfi2c.5", 7, MCF_CLK);
|
||||
DEFINE_CLK(1, "mcfuart.4", 24, MCF_BUSCLK);
|
||||
DEFINE_CLK(1, "mcfuart.5", 25, MCF_BUSCLK);
|
||||
DEFINE_CLK(1, "mcfuart.6", 26, MCF_BUSCLK);
|
||||
DEFINE_CLK(1, "mcfuart.7", 27, MCF_BUSCLK);
|
||||
DEFINE_CLK(1, "mcfuart.8", 28, MCF_BUSCLK);
|
||||
DEFINE_CLK(1, "mcfuart.9", 29, MCF_BUSCLK);
|
||||
DEFINE_CLK(1, "mcfpwm.0", 34, MCF_BUSCLK);
|
||||
DEFINE_CLK(1, "sys.0", 36, MCF_BUSCLK);
|
||||
DEFINE_CLK(1, "gpio.0", 37, MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&__clk_0_2,
|
||||
&__clk_0_8,
|
||||
&__clk_0_9,
|
||||
&__clk_0_14,
|
||||
&__clk_0_15,
|
||||
&__clk_0_17,
|
||||
&__clk_0_18,
|
||||
&__clk_0_19,
|
||||
&__clk_0_20,
|
||||
&__clk_0_22,
|
||||
&__clk_0_23,
|
||||
&__clk_0_24,
|
||||
&__clk_0_25,
|
||||
&__clk_0_26,
|
||||
&__clk_0_27,
|
||||
&__clk_0_28,
|
||||
&__clk_0_29,
|
||||
&__clk_0_30,
|
||||
&__clk_0_31,
|
||||
&__clk_0_32,
|
||||
&__clk_0_33,
|
||||
&__clk_0_34,
|
||||
&__clk_0_35,
|
||||
&__clk_0_37,
|
||||
&__clk_0_38,
|
||||
&__clk_0_39,
|
||||
&__clk_0_42,
|
||||
&__clk_0_43,
|
||||
&__clk_0_44,
|
||||
&__clk_0_45,
|
||||
&__clk_0_46,
|
||||
&__clk_0_47,
|
||||
&__clk_0_48,
|
||||
&__clk_0_49,
|
||||
&__clk_0_50,
|
||||
&__clk_0_51,
|
||||
&__clk_0_53,
|
||||
&__clk_0_54,
|
||||
&__clk_0_55,
|
||||
&__clk_0_56,
|
||||
&__clk_0_63,
|
||||
|
||||
&__clk_1_2,
|
||||
&__clk_1_4,
|
||||
&__clk_1_5,
|
||||
&__clk_1_6,
|
||||
&__clk_1_7,
|
||||
&__clk_1_24,
|
||||
&__clk_1_25,
|
||||
&__clk_1_26,
|
||||
&__clk_1_27,
|
||||
&__clk_1_28,
|
||||
&__clk_1_29,
|
||||
&__clk_1_34,
|
||||
&__clk_1_36,
|
||||
&__clk_1_37,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
static struct clk * const enable_clks[] __initconst = {
|
||||
/* make sure these clocks are enabled */
|
||||
&__clk_0_18, /* intc0 */
|
||||
&__clk_0_19, /* intc0 */
|
||||
&__clk_0_20, /* intc0 */
|
||||
&__clk_0_24, /* uart0 */
|
||||
&__clk_0_25, /* uart1 */
|
||||
&__clk_0_26, /* uart2 */
|
||||
&__clk_0_27, /* uart3 */
|
||||
|
||||
&__clk_0_33, /* pit.1 */
|
||||
&__clk_0_37, /* eport */
|
||||
&__clk_0_48, /* pll */
|
||||
|
||||
&__clk_1_36, /* CCM/reset module/Power management */
|
||||
&__clk_1_37, /* gpio */
|
||||
};
|
||||
static struct clk * const disable_clks[] __initconst = {
|
||||
&__clk_0_8, /* can.0 */
|
||||
&__clk_0_9, /* can.1 */
|
||||
&__clk_0_14, /* i2c.1 */
|
||||
&__clk_0_15, /* dspi.1 */
|
||||
&__clk_0_17, /* eDMA */
|
||||
&__clk_0_22, /* i2c.0 */
|
||||
&__clk_0_23, /* dspi.0 */
|
||||
&__clk_0_28, /* tmr.1 */
|
||||
&__clk_0_29, /* tmr.2 */
|
||||
&__clk_0_30, /* tmr.2 */
|
||||
&__clk_0_31, /* tmr.3 */
|
||||
&__clk_0_32, /* pit.0 */
|
||||
&__clk_0_34, /* pit.2 */
|
||||
&__clk_0_35, /* pit.3 */
|
||||
&__clk_0_38, /* adc */
|
||||
&__clk_0_39, /* dac */
|
||||
&__clk_0_44, /* usb otg */
|
||||
&__clk_0_45, /* usb host */
|
||||
&__clk_0_47, /* ssi.0 */
|
||||
&__clk_0_49, /* rng */
|
||||
&__clk_0_50, /* ssi.1 */
|
||||
&__clk_0_51, /* eSDHC */
|
||||
&__clk_0_53, /* enet-fec */
|
||||
&__clk_0_54, /* enet-fec */
|
||||
&__clk_0_55, /* switch.0 */
|
||||
&__clk_0_56, /* switch.1 */
|
||||
|
||||
&__clk_1_2, /* 1-wire */
|
||||
&__clk_1_4, /* i2c.2 */
|
||||
&__clk_1_5, /* i2c.3 */
|
||||
&__clk_1_6, /* i2c.4 */
|
||||
&__clk_1_7, /* i2c.5 */
|
||||
&__clk_1_24, /* uart 4 */
|
||||
&__clk_1_25, /* uart 5 */
|
||||
&__clk_1_26, /* uart 6 */
|
||||
&__clk_1_27, /* uart 7 */
|
||||
&__clk_1_28, /* uart 8 */
|
||||
&__clk_1_29, /* uart 9 */
|
||||
};
|
||||
|
||||
static void __init m5441x_clk_init(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
|
||||
__clk_init_enabled(enable_clks[i]);
|
||||
/* make sure these clocks are disabled */
|
||||
for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
|
||||
__clk_init_disabled(disable_clks[i]);
|
||||
}
|
||||
|
||||
static void __init m5441x_uarts_init(void)
|
||||
{
|
||||
__raw_writeb(0x0f, MCFGPIO_PAR_UART0);
|
||||
__raw_writeb(0x00, MCFGPIO_PAR_UART1);
|
||||
__raw_writeb(0x00, MCFGPIO_PAR_UART2);
|
||||
}
|
||||
|
||||
static void __init m5441x_fec_init(void)
|
||||
{
|
||||
__raw_writeb(0x03, MCFGPIO_PAR_FEC);
|
||||
}
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
m5441x_clk_init();
|
||||
mach_sched_init = hw_timer_init;
|
||||
m5441x_uarts_init();
|
||||
m5441x_fec_init();
|
||||
}
|
||||
|
||||
|
||||
#if IS_ENABLED(CONFIG_RTC_DRV_M5441x)
|
||||
static struct resource m5441x_rtc_resources[] = {
|
||||
{
|
||||
.start = MCFRTC_BASE,
|
||||
.end = MCFRTC_BASE + MCFRTC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_RTC,
|
||||
.end = MCF_IRQ_RTC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device m5441x_rtc = {
|
||||
.name = "mcfrtc",
|
||||
.id = 0,
|
||||
.resource = m5441x_rtc_resources,
|
||||
.num_resources = ARRAY_SIZE(m5441x_rtc_resources),
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_device *m5441x_devices[] __initdata = {
|
||||
#if IS_ENABLED(CONFIG_RTC_DRV_M5441x)
|
||||
&m5441x_rtc,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init init_BSP(void)
|
||||
{
|
||||
platform_add_devices(m5441x_devices, ARRAY_SIZE(m5441x_devices));
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(init_BSP);
|
128
arch/m68k/coldfire/m54xx.c
Normal file
128
arch/m68k/coldfire/m54xx.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* m54xx.c -- platform support for ColdFire 54xx based boards
|
||||
*
|
||||
* Copyright (C) 2010, Philippe De Muyter <phdm@macqel.be>
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/m54xxsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfclk.h>
|
||||
#include <asm/m54xxgpt.h>
|
||||
#ifdef CONFIG_MMU
|
||||
#include <asm/mmu_context.h>
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
DEFINE_CLK(pll, "pll.0", MCF_CLK);
|
||||
DEFINE_CLK(sys, "sys.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfslt0, "mcfslt.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfslt1, "mcfslt.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK);
|
||||
DEFINE_CLK(mcfuart3, "mcfuart.3", MCF_BUSCLK);
|
||||
|
||||
struct clk *mcf_clks[] = {
|
||||
&clk_pll,
|
||||
&clk_sys,
|
||||
&clk_mcfslt0,
|
||||
&clk_mcfslt1,
|
||||
&clk_mcfuart0,
|
||||
&clk_mcfuart1,
|
||||
&clk_mcfuart2,
|
||||
&clk_mcfuart3,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m54xx_uarts_init(void)
|
||||
{
|
||||
/* enable io pins */
|
||||
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD, MCFGPIO_PAR_PSC0);
|
||||
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS,
|
||||
MCFGPIO_PAR_PSC1);
|
||||
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS |
|
||||
MCF_PAR_PSC_CTS_CTS, MCFGPIO_PAR_PSC2);
|
||||
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD, MCFGPIO_PAR_PSC3);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void mcf54xx_reset(void)
|
||||
{
|
||||
/* disable interrupts and enable the watchdog */
|
||||
asm("movew #0x2700, %sr\n");
|
||||
__raw_writel(0, MCF_GPT_GMS0);
|
||||
__raw_writel(MCF_GPT_GCIR_CNT(1), MCF_GPT_GCIR0);
|
||||
__raw_writel(MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS(4),
|
||||
MCF_GPT_GMS0);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
unsigned long num_pages;
|
||||
|
||||
static void __init mcf54xx_bootmem_alloc(void)
|
||||
{
|
||||
unsigned long start_pfn;
|
||||
unsigned long memstart;
|
||||
|
||||
/* _rambase and _ramend will be naturally page aligned */
|
||||
m68k_memory[0].addr = _rambase;
|
||||
m68k_memory[0].size = _ramend - _rambase;
|
||||
|
||||
/* compute total pages in system */
|
||||
num_pages = (_ramend - _rambase) >> PAGE_SHIFT;
|
||||
|
||||
/* page numbers */
|
||||
memstart = PAGE_ALIGN(_ramstart);
|
||||
min_low_pfn = _rambase >> PAGE_SHIFT;
|
||||
start_pfn = memstart >> PAGE_SHIFT;
|
||||
max_low_pfn = _ramend >> PAGE_SHIFT;
|
||||
high_memory = (void *)_ramend;
|
||||
|
||||
m68k_virt_to_node_shift = fls(_ramend - _rambase - 1) - 6;
|
||||
module_fixup(NULL, __start_fixup, __stop_fixup);
|
||||
|
||||
/* setup bootmem data */
|
||||
m68k_setup_node(0);
|
||||
memstart += init_bootmem_node(NODE_DATA(0), start_pfn,
|
||||
min_low_pfn, max_low_pfn);
|
||||
free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void __init config_BSP(char *commandp, int size)
|
||||
{
|
||||
#ifdef CONFIG_MMU
|
||||
mcf54xx_bootmem_alloc();
|
||||
mmu_context_init();
|
||||
#endif
|
||||
mach_reset = mcf54xx_reset;
|
||||
mach_sched_init = hw_timer_init;
|
||||
m54xx_uarts_init();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
38
arch/m68k/coldfire/mcf8390.c
Normal file
38
arch/m68k/coldfire/mcf8390.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* mcf8390.c -- platform support for 8390 ethernet on many boards
|
||||
*
|
||||
* (C) Copyright 2012, Greg Ungerer <gerg@uclinux.org>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/resource.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/mcf8390.h>
|
||||
|
||||
static struct resource mcf8390_resources[] = {
|
||||
{
|
||||
.start = NE2000_ADDR,
|
||||
.end = NE2000_ADDR + NE2000_ADDRSIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = NE2000_IRQ_VECTOR,
|
||||
.end = NE2000_IRQ_VECTOR,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mcf8390_platform_init(void)
|
||||
{
|
||||
platform_device_register_simple("mcf8390", -1, mcf8390_resources,
|
||||
ARRAY_SIZE(mcf8390_resources));
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(mcf8390_platform_init);
|
153
arch/m68k/coldfire/nettel.c
Normal file
153
arch/m68k/coldfire/nettel.c
Normal file
|
@ -0,0 +1,153 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* nettel.c -- startup code support for the NETtel boards
|
||||
*
|
||||
* Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/nettel.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Define the IO and interrupt resources of the 2 SMC9196 interfaces.
|
||||
*/
|
||||
#define NETTEL_SMC0_ADDR 0x30600300
|
||||
#define NETTEL_SMC0_IRQ 29
|
||||
|
||||
#define NETTEL_SMC1_ADDR 0x30600000
|
||||
#define NETTEL_SMC1_IRQ 27
|
||||
|
||||
/*
|
||||
* We need some access into the SMC9196 registers. Define those registers
|
||||
* we will need here (including the smc91x.h doesn't seem to give us these
|
||||
* in a simple form).
|
||||
*/
|
||||
#define SMC91xx_BANKSELECT 14
|
||||
#define SMC91xx_BASEADDR 2
|
||||
#define SMC91xx_BASEMAC 4
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct resource nettel_smc91x_0_resources[] = {
|
||||
{
|
||||
.start = NETTEL_SMC0_ADDR,
|
||||
.end = NETTEL_SMC0_ADDR + 0x20,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = NETTEL_SMC0_IRQ,
|
||||
.end = NETTEL_SMC0_IRQ,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource nettel_smc91x_1_resources[] = {
|
||||
{
|
||||
.start = NETTEL_SMC1_ADDR,
|
||||
.end = NETTEL_SMC1_ADDR + 0x20,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = NETTEL_SMC1_IRQ,
|
||||
.end = NETTEL_SMC1_IRQ,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device nettel_smc91x[] = {
|
||||
{
|
||||
.name = "smc91x",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(nettel_smc91x_0_resources),
|
||||
.resource = nettel_smc91x_0_resources,
|
||||
},
|
||||
{
|
||||
.name = "smc91x",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(nettel_smc91x_1_resources),
|
||||
.resource = nettel_smc91x_1_resources,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *nettel_devices[] __initdata = {
|
||||
&nettel_smc91x[0],
|
||||
&nettel_smc91x[1],
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static u8 nettel_macdefault[] __initdata = {
|
||||
0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set flash contained MAC address into SMC9196 core. Make sure the flash
|
||||
* MAC address is sane, and not an empty flash. If no good use the Moreton
|
||||
* Bay default MAC address instead.
|
||||
*/
|
||||
|
||||
static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr)
|
||||
{
|
||||
u16 *macp;
|
||||
|
||||
macp = (u16 *) flashaddr;
|
||||
if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff))
|
||||
macp = (u16 *) &nettel_macdefault[0];
|
||||
|
||||
writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
|
||||
writew(macp[0], ioaddr + SMC91xx_BASEMAC);
|
||||
writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2);
|
||||
writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Re-map the address space of at least one of the SMC ethernet
|
||||
* parts. Both parts power up decoding the same address, so we
|
||||
* need to move one of them first, before doing anything else.
|
||||
*/
|
||||
|
||||
static void __init nettel_smc91x_init(void)
|
||||
{
|
||||
writew(0x00ec, MCFSIM_PADDR);
|
||||
mcf_setppdata(0, 0x0080);
|
||||
writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
|
||||
writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR);
|
||||
mcf_setppdata(0x0080, 0);
|
||||
|
||||
/* Set correct chip select timing for SMC9196 accesses */
|
||||
writew(0x1180, MCFSIM_CSCR3);
|
||||
|
||||
/* Set the SMC interrupts to be auto-vectored */
|
||||
mcf_autovector(NETTEL_SMC0_IRQ);
|
||||
mcf_autovector(NETTEL_SMC1_IRQ);
|
||||
|
||||
/* Set MAC addresses from flash for both interfaces */
|
||||
nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000);
|
||||
nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static int __init init_nettel(void)
|
||||
{
|
||||
nettel_smc91x_init();
|
||||
platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices));
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(init_nettel);
|
||||
|
||||
/***************************************************************************/
|
325
arch/m68k/coldfire/pci.c
Normal file
325
arch/m68k/coldfire/pci.c
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* pci.c -- PCI bus support for ColdFire processors
|
||||
*
|
||||
* (C) Copyright 2012, Greg Ungerer <gerg@uclinux.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/m54xxpci.h>
|
||||
|
||||
/*
|
||||
* Memory and IO mappings. We use a 1:1 mapping for local host memory to
|
||||
* PCI bus memory (no reason not to really). IO space doesn't matter, we
|
||||
* always use access functions for that. The device configuration space is
|
||||
* mapped over the IO map space when we enable it in the PCICAR register.
|
||||
*/
|
||||
#define PCI_MEM_PA 0xf0000000 /* Host physical address */
|
||||
#define PCI_MEM_BA 0xf0000000 /* Bus physical address */
|
||||
#define PCI_MEM_SIZE 0x08000000 /* 128 MB */
|
||||
#define PCI_MEM_MASK (PCI_MEM_SIZE - 1)
|
||||
|
||||
#define PCI_IO_PA 0xf8000000 /* Host physical address */
|
||||
#define PCI_IO_BA 0x00000000 /* Bus physical address */
|
||||
#define PCI_IO_SIZE 0x00010000 /* 64k */
|
||||
#define PCI_IO_MASK (PCI_IO_SIZE - 1)
|
||||
|
||||
static struct pci_bus *rootbus;
|
||||
static unsigned long iospace;
|
||||
|
||||
/*
|
||||
* We need to be carefull probing on bus 0 (directly connected to host
|
||||
* bridge). We should only acccess the well defined possible devices in
|
||||
* use, ignore aliases and the like.
|
||||
*/
|
||||
static unsigned char mcf_host_slot2sid[32] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 0, 3, 4, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static unsigned char mcf_host_irq[] = {
|
||||
0, 69, 69, 71, 71,
|
||||
};
|
||||
|
||||
|
||||
static inline void syncio(void)
|
||||
{
|
||||
/* The ColdFire "nop" instruction waits for all bus IO to complete */
|
||||
__asm__ __volatile__ ("nop");
|
||||
}
|
||||
|
||||
/*
|
||||
* Configuration space access functions. Configuration space access is
|
||||
* through the IO mapping window, enabling it via the PCICAR register.
|
||||
*/
|
||||
static unsigned long mcf_mk_pcicar(int bus, unsigned int devfn, int where)
|
||||
{
|
||||
return (bus << PCICAR_BUSN) | (devfn << PCICAR_DEVFNN) | (where & 0xfc);
|
||||
}
|
||||
|
||||
static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *value)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
*value = 0xffffffff;
|
||||
|
||||
if (bus->number == 0) {
|
||||
if (mcf_host_slot2sid[PCI_SLOT(devfn)] == 0)
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
syncio();
|
||||
addr = mcf_mk_pcicar(bus->number, devfn, where);
|
||||
__raw_writel(PCICAR_E | addr, PCICAR);
|
||||
addr = iospace + (where & 0x3);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
*value = __raw_readb(addr);
|
||||
break;
|
||||
case 2:
|
||||
*value = le16_to_cpu(__raw_readw(addr));
|
||||
break;
|
||||
default:
|
||||
*value = le32_to_cpu(__raw_readl(addr));
|
||||
break;
|
||||
}
|
||||
|
||||
syncio();
|
||||
__raw_writel(0, PCICAR);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 value)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
if (bus->number == 0) {
|
||||
if (mcf_host_slot2sid[PCI_SLOT(devfn)] == 0)
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
syncio();
|
||||
addr = mcf_mk_pcicar(bus->number, devfn, where);
|
||||
__raw_writel(PCICAR_E | addr, PCICAR);
|
||||
addr = iospace + (where & 0x3);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
__raw_writeb(value, addr);
|
||||
break;
|
||||
case 2:
|
||||
__raw_writew(cpu_to_le16(value), addr);
|
||||
break;
|
||||
default:
|
||||
__raw_writel(cpu_to_le32(value), addr);
|
||||
break;
|
||||
}
|
||||
|
||||
syncio();
|
||||
__raw_writel(0, PCICAR);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops mcf_pci_ops = {
|
||||
.read = mcf_pci_readconfig,
|
||||
.write = mcf_pci_writeconfig,
|
||||
};
|
||||
|
||||
/*
|
||||
* IO address space access functions. Pretty strait forward, these are
|
||||
* directly mapped in to the IO mapping window. And that is mapped into
|
||||
* virtual address space.
|
||||
*/
|
||||
u8 mcf_pci_inb(u32 addr)
|
||||
{
|
||||
return __raw_readb(iospace + (addr & PCI_IO_MASK));
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_inb);
|
||||
|
||||
u16 mcf_pci_inw(u32 addr)
|
||||
{
|
||||
return le16_to_cpu(__raw_readw(iospace + (addr & PCI_IO_MASK)));
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_inw);
|
||||
|
||||
u32 mcf_pci_inl(u32 addr)
|
||||
{
|
||||
return le32_to_cpu(__raw_readl(iospace + (addr & PCI_IO_MASK)));
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_inl);
|
||||
|
||||
void mcf_pci_insb(u32 addr, u8 *buf, u32 len)
|
||||
{
|
||||
for (; len; len--)
|
||||
*buf++ = mcf_pci_inb(addr);
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_insb);
|
||||
|
||||
void mcf_pci_insw(u32 addr, u16 *buf, u32 len)
|
||||
{
|
||||
for (; len; len--)
|
||||
*buf++ = mcf_pci_inw(addr);
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_insw);
|
||||
|
||||
void mcf_pci_insl(u32 addr, u32 *buf, u32 len)
|
||||
{
|
||||
for (; len; len--)
|
||||
*buf++ = mcf_pci_inl(addr);
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_insl);
|
||||
|
||||
void mcf_pci_outb(u8 v, u32 addr)
|
||||
{
|
||||
__raw_writeb(v, iospace + (addr & PCI_IO_MASK));
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_outb);
|
||||
|
||||
void mcf_pci_outw(u16 v, u32 addr)
|
||||
{
|
||||
__raw_writew(cpu_to_le16(v), iospace + (addr & PCI_IO_MASK));
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_outw);
|
||||
|
||||
void mcf_pci_outl(u32 v, u32 addr)
|
||||
{
|
||||
__raw_writel(cpu_to_le32(v), iospace + (addr & PCI_IO_MASK));
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_outl);
|
||||
|
||||
void mcf_pci_outsb(u32 addr, const u8 *buf, u32 len)
|
||||
{
|
||||
for (; len; len--)
|
||||
mcf_pci_outb(*buf++, addr);
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_outsb);
|
||||
|
||||
void mcf_pci_outsw(u32 addr, const u16 *buf, u32 len)
|
||||
{
|
||||
for (; len; len--)
|
||||
mcf_pci_outw(*buf++, addr);
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_outsw);
|
||||
|
||||
void mcf_pci_outsl(u32 addr, const u32 *buf, u32 len)
|
||||
{
|
||||
for (; len; len--)
|
||||
mcf_pci_outl(*buf++, addr);
|
||||
}
|
||||
EXPORT_SYMBOL(mcf_pci_outsl);
|
||||
|
||||
/*
|
||||
* Initialize the PCI bus registers, and scan the bus.
|
||||
*/
|
||||
static struct resource mcf_pci_mem = {
|
||||
.name = "PCI Memory space",
|
||||
.start = PCI_MEM_PA,
|
||||
.end = PCI_MEM_PA + PCI_MEM_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct resource mcf_pci_io = {
|
||||
.name = "PCI IO space",
|
||||
.start = 0x400,
|
||||
.end = 0x10000 - 1,
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
|
||||
/*
|
||||
* Interrupt mapping and setting.
|
||||
*/
|
||||
static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
int sid;
|
||||
|
||||
sid = mcf_host_slot2sid[slot];
|
||||
if (sid)
|
||||
return mcf_host_irq[sid];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init mcf_pci_init(void)
|
||||
{
|
||||
pr_info("ColdFire: PCI bus initialization...\n");
|
||||
|
||||
/* Reset the external PCI bus */
|
||||
__raw_writel(PCIGSCR_RESET, PCIGSCR);
|
||||
__raw_writel(0, PCITCR);
|
||||
|
||||
request_resource(&iomem_resource, &mcf_pci_mem);
|
||||
request_resource(&iomem_resource, &mcf_pci_io);
|
||||
|
||||
/* Configure PCI arbiter */
|
||||
__raw_writel(PACR_INTMPRI | PACR_INTMINTE | PACR_EXTMPRI(0x1f) |
|
||||
PACR_EXTMINTE(0x1f), PACR);
|
||||
|
||||
/* Set required multi-function pins for PCI bus use */
|
||||
__raw_writew(0x3ff, MCFGPIO_PAR_PCIBG);
|
||||
__raw_writew(0x3ff, MCFGPIO_PAR_PCIBR);
|
||||
|
||||
/* Set up config space for local host bus controller */
|
||||
__raw_writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
|
||||
PCI_COMMAND_INVALIDATE, PCISCR);
|
||||
__raw_writel(PCICR1_LT(32) | PCICR1_CL(8), PCICR1);
|
||||
__raw_writel(0, PCICR2);
|
||||
|
||||
/*
|
||||
* Set up the initiator windows for memory and IO mapping.
|
||||
* These give the CPU bus access onto the PCI bus. One for each of
|
||||
* PCI memory and IO address spaces.
|
||||
*/
|
||||
__raw_writel(WXBTAR(PCI_MEM_PA, PCI_MEM_BA, PCI_MEM_SIZE),
|
||||
PCIIW0BTAR);
|
||||
__raw_writel(WXBTAR(PCI_IO_PA, PCI_IO_BA, PCI_IO_SIZE),
|
||||
PCIIW1BTAR);
|
||||
__raw_writel(PCIIWCR_W0_MEM /*| PCIIWCR_W0_MRDL*/ | PCIIWCR_W0_E |
|
||||
PCIIWCR_W1_IO | PCIIWCR_W1_E, PCIIWCR);
|
||||
|
||||
/*
|
||||
* Set up the target windows for access from the PCI bus back to the
|
||||
* CPU bus. All we need is access to system RAM (for mastering).
|
||||
*/
|
||||
__raw_writel(CONFIG_RAMBASE, PCIBAR1);
|
||||
__raw_writel(CONFIG_RAMBASE | PCITBATR1_E, PCITBATR1);
|
||||
|
||||
/* Keep a virtual mapping to IO/config space active */
|
||||
iospace = (unsigned long) ioremap(PCI_IO_PA, PCI_IO_SIZE);
|
||||
if (iospace == 0)
|
||||
return -ENODEV;
|
||||
pr_info("Coldfire: PCI IO/config window mapped to 0x%x\n",
|
||||
(u32) iospace);
|
||||
|
||||
/* Turn of PCI reset, and wait for devices to settle */
|
||||
__raw_writel(0, PCIGSCR);
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(msecs_to_jiffies(200));
|
||||
|
||||
rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL);
|
||||
rootbus->resource[0] = &mcf_pci_io;
|
||||
rootbus->resource[1] = &mcf_pci_mem;
|
||||
|
||||
pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq);
|
||||
pci_bus_size_bridges(rootbus);
|
||||
pci_bus_assign_resources(rootbus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(mcf_pci_init);
|
167
arch/m68k/coldfire/pit.c
Normal file
167
arch/m68k/coldfire/pit.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* pit.c -- Freescale ColdFire PIT timer. Currently this type of
|
||||
* hardware timer only exists in the Freescale ColdFire
|
||||
* 5270/5271, 5282 and 5208 CPUs. No doubt newer ColdFire
|
||||
* family members will probably use it too.
|
||||
*
|
||||
* Copyright (C) 1999-2008, Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfpit.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* By default use timer1 as the system clock timer.
|
||||
*/
|
||||
#define FREQ ((MCF_CLK / 2) / 64)
|
||||
#define TA(a) (MCFPIT_BASE1 + (a))
|
||||
#define PIT_CYCLES_PER_JIFFY (FREQ / HZ)
|
||||
|
||||
static u32 pit_cnt;
|
||||
|
||||
/*
|
||||
* Initialize the PIT timer.
|
||||
*
|
||||
* This is also called after resume to bring the PIT into operation again.
|
||||
*/
|
||||
|
||||
static void init_cf_pit_timer(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
|
||||
__raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR));
|
||||
__raw_writew(PIT_CYCLES_PER_JIFFY, TA(MCFPIT_PMR));
|
||||
__raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | \
|
||||
MCFPIT_PCSR_OVW | MCFPIT_PCSR_RLD | \
|
||||
MCFPIT_PCSR_CLK64, TA(MCFPIT_PCSR));
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
|
||||
__raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR));
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
|
||||
__raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR));
|
||||
__raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | \
|
||||
MCFPIT_PCSR_OVW | MCFPIT_PCSR_CLK64, \
|
||||
TA(MCFPIT_PCSR));
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
/* Nothing to do here */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Program the next event in oneshot mode
|
||||
*
|
||||
* Delta is given in PIT ticks
|
||||
*/
|
||||
static int cf_pit_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
__raw_writew(delta, TA(MCFPIT_PMR));
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct clock_event_device cf_pit_clockevent = {
|
||||
.name = "pit",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_mode = init_cf_pit_timer,
|
||||
.set_next_event = cf_pit_next_event,
|
||||
.shift = 32,
|
||||
.irq = MCF_IRQ_PIT1,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static irqreturn_t pit_tick(int irq, void *dummy)
|
||||
{
|
||||
struct clock_event_device *evt = &cf_pit_clockevent;
|
||||
u16 pcsr;
|
||||
|
||||
/* Reset the ColdFire timer */
|
||||
pcsr = __raw_readw(TA(MCFPIT_PCSR));
|
||||
__raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR));
|
||||
|
||||
pit_cnt += PIT_CYCLES_PER_JIFFY;
|
||||
evt->event_handler(evt);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct irqaction pit_irq = {
|
||||
.name = "timer",
|
||||
.flags = IRQF_TIMER,
|
||||
.handler = pit_tick,
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static cycle_t pit_read_clk(struct clocksource *cs)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 cycles;
|
||||
u16 pcntr;
|
||||
|
||||
local_irq_save(flags);
|
||||
pcntr = __raw_readw(TA(MCFPIT_PCNTR));
|
||||
cycles = pit_cnt;
|
||||
local_irq_restore(flags);
|
||||
|
||||
return cycles + PIT_CYCLES_PER_JIFFY - pcntr;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct clocksource pit_clk = {
|
||||
.name = "pit",
|
||||
.rating = 100,
|
||||
.read = pit_read_clk,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void hw_timer_init(irq_handler_t handler)
|
||||
{
|
||||
cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id());
|
||||
cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
|
||||
cf_pit_clockevent.max_delta_ns =
|
||||
clockevent_delta2ns(0xFFFF, &cf_pit_clockevent);
|
||||
cf_pit_clockevent.min_delta_ns =
|
||||
clockevent_delta2ns(0x3f, &cf_pit_clockevent);
|
||||
clockevents_register_device(&cf_pit_clockevent);
|
||||
|
||||
setup_irq(MCF_IRQ_PIT1, &pit_irq);
|
||||
|
||||
clocksource_register_hz(&pit_clk, FREQ);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
50
arch/m68k/coldfire/reset.c
Normal file
50
arch/m68k/coldfire/reset.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* reset.c -- common ColdFire SoC reset support
|
||||
*
|
||||
* (C) Copyright 2012, Greg Ungerer <gerg@uclinux.org>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
/*
|
||||
* There are 2 common methods amongst the ColdFure parts for reseting
|
||||
* the CPU. But there are couple of exceptions, the 5272 and the 547x
|
||||
* have something completely special to them, and we let their specific
|
||||
* subarch code handle them.
|
||||
*/
|
||||
|
||||
#ifdef MCFSIM_SYPCR
|
||||
static void mcf_cpu_reset(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
/* Set watchdog to soft reset, and enabled */
|
||||
__raw_writeb(0xc0, MCFSIM_SYPCR);
|
||||
for (;;)
|
||||
/* wait for watchdog to timeout */;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MCF_RCR
|
||||
static void mcf_cpu_reset(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
__raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init mcf_setup_reset(void)
|
||||
{
|
||||
mach_reset = mcf_cpu_reset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(mcf_setup_reset);
|
149
arch/m68k/coldfire/sltimers.c
Normal file
149
arch/m68k/coldfire/sltimers.c
Normal file
|
@ -0,0 +1,149 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* sltimers.c -- generic ColdFire slice timer support.
|
||||
*
|
||||
* Copyright (C) 2009-2010, Philippe De Muyter <phdm@macqel.be>
|
||||
* based on
|
||||
* timers.c -- generic ColdFire hardware timer support.
|
||||
* Copyright (C) 1999-2008, Greg Ungerer <gerg@snapgear.com>
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfslt.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef CONFIG_HIGHPROFILE
|
||||
|
||||
/*
|
||||
* By default use Slice Timer 1 as the profiler clock timer.
|
||||
*/
|
||||
#define PA(a) (MCFSLT_TIMER1 + (a))
|
||||
|
||||
/*
|
||||
* Choose a reasonably fast profile timer. Make it an odd value to
|
||||
* try and get good coverage of kernel operations.
|
||||
*/
|
||||
#define PROFILEHZ 1013
|
||||
|
||||
irqreturn_t mcfslt_profile_tick(int irq, void *dummy)
|
||||
{
|
||||
/* Reset Slice Timer 1 */
|
||||
__raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, PA(MCFSLT_SSR));
|
||||
if (current->pid)
|
||||
profile_tick(CPU_PROFILING);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction mcfslt_profile_irq = {
|
||||
.name = "profile timer",
|
||||
.flags = IRQF_TIMER,
|
||||
.handler = mcfslt_profile_tick,
|
||||
};
|
||||
|
||||
void mcfslt_profile_init(void)
|
||||
{
|
||||
printk(KERN_INFO "PROFILE: lodging TIMER 1 @ %dHz as profile timer\n",
|
||||
PROFILEHZ);
|
||||
|
||||
setup_irq(MCF_IRQ_PROFILER, &mcfslt_profile_irq);
|
||||
|
||||
/* Set up TIMER 2 as high speed profile clock */
|
||||
__raw_writel(MCF_BUSCLK / PROFILEHZ - 1, PA(MCFSLT_STCNT));
|
||||
__raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN,
|
||||
PA(MCFSLT_SCR));
|
||||
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HIGHPROFILE */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* By default use Slice Timer 0 as the system clock timer.
|
||||
*/
|
||||
#define TA(a) (MCFSLT_TIMER0 + (a))
|
||||
|
||||
static u32 mcfslt_cycles_per_jiffy;
|
||||
static u32 mcfslt_cnt;
|
||||
|
||||
static irq_handler_t timer_interrupt;
|
||||
|
||||
static irqreturn_t mcfslt_tick(int irq, void *dummy)
|
||||
{
|
||||
/* Reset Slice Timer 0 */
|
||||
__raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, TA(MCFSLT_SSR));
|
||||
mcfslt_cnt += mcfslt_cycles_per_jiffy;
|
||||
return timer_interrupt(irq, dummy);
|
||||
}
|
||||
|
||||
static struct irqaction mcfslt_timer_irq = {
|
||||
.name = "timer",
|
||||
.flags = IRQF_TIMER,
|
||||
.handler = mcfslt_tick,
|
||||
};
|
||||
|
||||
static cycle_t mcfslt_read_clk(struct clocksource *cs)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 cycles, scnt;
|
||||
|
||||
local_irq_save(flags);
|
||||
scnt = __raw_readl(TA(MCFSLT_SCNT));
|
||||
cycles = mcfslt_cnt;
|
||||
if (__raw_readl(TA(MCFSLT_SSR)) & MCFSLT_SSR_TE) {
|
||||
cycles += mcfslt_cycles_per_jiffy;
|
||||
scnt = __raw_readl(TA(MCFSLT_SCNT));
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
|
||||
/* subtract because slice timers count down */
|
||||
return cycles + ((mcfslt_cycles_per_jiffy - 1) - scnt);
|
||||
}
|
||||
|
||||
static struct clocksource mcfslt_clk = {
|
||||
.name = "slt",
|
||||
.rating = 250,
|
||||
.read = mcfslt_read_clk,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
void hw_timer_init(irq_handler_t handler)
|
||||
{
|
||||
mcfslt_cycles_per_jiffy = MCF_BUSCLK / HZ;
|
||||
/*
|
||||
* The coldfire slice timer (SLT) runs from STCNT to 0 included,
|
||||
* then STCNT again and so on. It counts thus actually
|
||||
* STCNT + 1 steps for 1 tick, not STCNT. So if you want
|
||||
* n cycles, initialize STCNT with n - 1.
|
||||
*/
|
||||
__raw_writel(mcfslt_cycles_per_jiffy - 1, TA(MCFSLT_STCNT));
|
||||
__raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN,
|
||||
TA(MCFSLT_SCR));
|
||||
/* initialize mcfslt_cnt knowing that slice timers count down */
|
||||
mcfslt_cnt = mcfslt_cycles_per_jiffy;
|
||||
|
||||
timer_interrupt = handler;
|
||||
setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq);
|
||||
|
||||
clocksource_register_hz(&mcfslt_clk, MCF_BUSCLK);
|
||||
|
||||
#ifdef CONFIG_HIGHPROFILE
|
||||
mcfslt_profile_init();
|
||||
#endif
|
||||
}
|
195
arch/m68k/coldfire/timers.c
Normal file
195
arch/m68k/coldfire/timers.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* timers.c -- generic ColdFire hardware timer support.
|
||||
*
|
||||
* Copyright (C) 1999-2008, Greg Ungerer <gerg@snapgear.com>
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcftimer.h>
|
||||
#include <asm/mcfsim.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* By default use timer1 as the system clock timer.
|
||||
*/
|
||||
#define FREQ (MCF_BUSCLK / 16)
|
||||
#define TA(a) (MCFTIMER_BASE1 + (a))
|
||||
|
||||
/*
|
||||
* These provide the underlying interrupt vector support.
|
||||
* Unfortunately it is a little different on each ColdFire.
|
||||
*/
|
||||
void coldfire_profile_init(void);
|
||||
|
||||
#if defined(CONFIG_M53xx) || defined(CONFIG_M5441x)
|
||||
#define __raw_readtrr __raw_readl
|
||||
#define __raw_writetrr __raw_writel
|
||||
#else
|
||||
#define __raw_readtrr __raw_readw
|
||||
#define __raw_writetrr __raw_writew
|
||||
#endif
|
||||
|
||||
static u32 mcftmr_cycles_per_jiffy;
|
||||
static u32 mcftmr_cnt;
|
||||
|
||||
static irq_handler_t timer_interrupt;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void init_timer_irq(void)
|
||||
{
|
||||
#ifdef MCFSIM_ICR_AUTOVEC
|
||||
/* Timer1 is always used as system timer */
|
||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
|
||||
MCFSIM_TIMER1ICR);
|
||||
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
|
||||
|
||||
#ifdef CONFIG_HIGHPROFILE
|
||||
/* Timer2 is to be used as a high speed profile timer */
|
||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
|
||||
MCFSIM_TIMER2ICR);
|
||||
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
|
||||
#endif
|
||||
#endif /* MCFSIM_ICR_AUTOVEC */
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static irqreturn_t mcftmr_tick(int irq, void *dummy)
|
||||
{
|
||||
/* Reset the ColdFire timer */
|
||||
__raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
|
||||
|
||||
mcftmr_cnt += mcftmr_cycles_per_jiffy;
|
||||
return timer_interrupt(irq, dummy);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct irqaction mcftmr_timer_irq = {
|
||||
.name = "timer",
|
||||
.flags = IRQF_TIMER,
|
||||
.handler = mcftmr_tick,
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static cycle_t mcftmr_read_clk(struct clocksource *cs)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 cycles;
|
||||
u16 tcn;
|
||||
|
||||
local_irq_save(flags);
|
||||
tcn = __raw_readw(TA(MCFTIMER_TCN));
|
||||
cycles = mcftmr_cnt;
|
||||
local_irq_restore(flags);
|
||||
|
||||
return cycles + tcn;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct clocksource mcftmr_clk = {
|
||||
.name = "tmr",
|
||||
.rating = 250,
|
||||
.read = mcftmr_read_clk,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void hw_timer_init(irq_handler_t handler)
|
||||
{
|
||||
__raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
|
||||
mcftmr_cycles_per_jiffy = FREQ / HZ;
|
||||
/*
|
||||
* The coldfire timer runs from 0 to TRR included, then 0
|
||||
* again and so on. It counts thus actually TRR + 1 steps
|
||||
* for 1 tick, not TRR. So if you want n cycles,
|
||||
* initialize TRR with n - 1.
|
||||
*/
|
||||
__raw_writetrr(mcftmr_cycles_per_jiffy - 1, TA(MCFTIMER_TRR));
|
||||
__raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
|
||||
MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR));
|
||||
|
||||
clocksource_register_hz(&mcftmr_clk, FREQ);
|
||||
|
||||
timer_interrupt = handler;
|
||||
init_timer_irq();
|
||||
setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq);
|
||||
|
||||
#ifdef CONFIG_HIGHPROFILE
|
||||
coldfire_profile_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
#ifdef CONFIG_HIGHPROFILE
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* By default use timer2 as the profiler clock timer.
|
||||
*/
|
||||
#define PA(a) (MCFTIMER_BASE2 + (a))
|
||||
|
||||
/*
|
||||
* Choose a reasonably fast profile timer. Make it an odd value to
|
||||
* try and get good coverage of kernel operations.
|
||||
*/
|
||||
#define PROFILEHZ 1013
|
||||
|
||||
/*
|
||||
* Use the other timer to provide high accuracy profiling info.
|
||||
*/
|
||||
irqreturn_t coldfire_profile_tick(int irq, void *dummy)
|
||||
{
|
||||
/* Reset ColdFire timer2 */
|
||||
__raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER));
|
||||
if (current->pid)
|
||||
profile_tick(CPU_PROFILING);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct irqaction coldfire_profile_irq = {
|
||||
.name = "profile timer",
|
||||
.flags = IRQF_TIMER,
|
||||
.handler = coldfire_profile_tick,
|
||||
};
|
||||
|
||||
void coldfire_profile_init(void)
|
||||
{
|
||||
printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n",
|
||||
PROFILEHZ);
|
||||
|
||||
/* Set up TIMER 2 as high speed profile clock */
|
||||
__raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
|
||||
|
||||
__raw_writetrr(((MCF_BUSCLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
|
||||
__raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
|
||||
MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
|
||||
|
||||
setup_irq(MCF_IRQ_PROFILER, &coldfire_profile_irq);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
#endif /* CONFIG_HIGHPROFILE */
|
||||
/***************************************************************************/
|
70
arch/m68k/coldfire/vectors.c
Normal file
70
arch/m68k/coldfire/vectors.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* vectors.c -- high level trap setup for ColdFire
|
||||
*
|
||||
* Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com>
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfwdebug.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef TRAP_DBG_INTERRUPT
|
||||
|
||||
asmlinkage void dbginterrupt_c(struct frame *fp)
|
||||
{
|
||||
extern void dump(struct pt_regs *fp);
|
||||
printk(KERN_DEBUG "%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
|
||||
dump((struct pt_regs *) fp);
|
||||
asm("halt");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/* Assembler routines */
|
||||
asmlinkage void buserr(void);
|
||||
asmlinkage void trap(void);
|
||||
asmlinkage void system_call(void);
|
||||
asmlinkage void inthandler(void);
|
||||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* There is a common trap handler and common interrupt
|
||||
* handler that handle almost every vector. We treat
|
||||
* the system call and bus error special, they get their
|
||||
* own first level handlers.
|
||||
*/
|
||||
for (i = 3; (i <= 23); i++)
|
||||
_ramvec[i] = trap;
|
||||
for (i = 33; (i <= 63); i++)
|
||||
_ramvec[i] = trap;
|
||||
for (i = 24; (i <= 31); i++)
|
||||
_ramvec[i] = inthandler;
|
||||
for (i = 64; (i < 255); i++)
|
||||
_ramvec[i] = inthandler;
|
||||
_ramvec[255] = 0;
|
||||
|
||||
_ramvec[2] = buserr;
|
||||
_ramvec[32] = system_call;
|
||||
|
||||
#ifdef TRAP_DBG_INTERRUPT
|
||||
_ramvec[12] = dbginterrupt;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
Loading…
Add table
Add a link
Reference in a new issue