Commit f0006314 authored by Russell King's avatar Russell King Committed by Russell King

Merge branch 'imx' into devel

Conflicts:

	arch/arm/mm/Kconfig
parents a177ba3b 1bd55a43
...@@ -401,7 +401,11 @@ config ARCH_MV78XX0 ...@@ -401,7 +401,11 @@ config ARCH_MV78XX0
config ARCH_MXC config ARCH_MXC
bool "Freescale MXC/iMX-based" bool "Freescale MXC/iMX-based"
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select ARCH_MTD_XIP select ARCH_MTD_XIP
select GENERIC_GPIO
select HAVE_GPIO_LIB
help help
Support for Freescale MXC/iMX-based family of processors Support for Freescale MXC/iMX-based family of processors
......
...@@ -136,6 +136,7 @@ endif ...@@ -136,6 +136,7 @@ endif
machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
machine-$(CONFIG_ARCH_KS8695) := ks8695 machine-$(CONFIG_ARCH_KS8695) := ks8695
incdir-$(CONFIG_ARCH_MXC) := mxc incdir-$(CONFIG_ARCH_MXC) := mxc
machine-$(CONFIG_ARCH_MX2) := mx2
machine-$(CONFIG_ARCH_MX3) := mx3 machine-$(CONFIG_ARCH_MX3) := mx3
machine-$(CONFIG_ARCH_ORION5X) := orion5x machine-$(CONFIG_ARCH_ORION5X) := orion5x
machine-$(CONFIG_ARCH_MSM7X00A) := msm machine-$(CONFIG_ARCH_MSM7X00A) := msm
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Object file lists. # Object file lists.
obj-y += irq.o time.o dma.o generic.o obj-y += irq.o time.o dma.o generic.o clock.o
obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
......
/*
* Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/math64.h>
#include <linux/err.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
/*
* Very simple approach: We can't disable clocks, so we do
* not need refcounting
*/
struct clk {
struct list_head node;
const char *name;
unsigned long (*get_rate)(void);
};
/*
* get the system pll clock in Hz
*
* mfi + mfn / (mfd +1)
* f = 2 * f_ref * --------------------
* pd + 1
*/
static unsigned long imx_decode_pll(unsigned int pll, u32 f_ref)
{
unsigned long long ll;
unsigned long quot;
u32 mfi = (pll >> 10) & 0xf;
u32 mfn = pll & 0x3ff;
u32 mfd = (pll >> 16) & 0x3ff;
u32 pd = (pll >> 26) & 0xf;
mfi = mfi <= 5 ? 5 : mfi;
ll = 2 * (unsigned long long)f_ref *
((mfi << 16) + (mfn << 16) / (mfd + 1));
quot = (pd + 1) * (1 << 16);
ll += quot / 2;
do_div(ll, quot);
return (unsigned long)ll;
}
static unsigned long imx_get_system_clk(void)
{
u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
return imx_decode_pll(SPCTL0, f_ref);
}
static unsigned long imx_get_mcu_clk(void)
{
return imx_decode_pll(MPCTL0, CLK32 * 512);
}
/*
* get peripheral clock 1 ( UART[12], Timer[12], PWM )
*/
static unsigned long imx_get_perclk1(void)
{
return imx_get_system_clk() / (((PCDR) & 0xf)+1);
}
/*
* get peripheral clock 2 ( LCD, SD, SPI[12] )
*/
static unsigned long imx_get_perclk2(void)
{
return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1);
}
/*
* get peripheral clock 3 ( SSI )
*/
static unsigned long imx_get_perclk3(void)
{
return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1);
}
/*
* get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
*/
static unsigned long imx_get_hclk(void)
{
return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1);
}
static struct clk clk_system_clk = {
.name = "system_clk",
.get_rate = imx_get_system_clk,
};
static struct clk clk_hclk = {
.name = "hclk",
.get_rate = imx_get_hclk,
};
static struct clk clk_mcu_clk = {
.name = "mcu_clk",
.get_rate = imx_get_mcu_clk,
};
static struct clk clk_perclk1 = {
.name = "perclk1",
.get_rate = imx_get_perclk1,
};
static struct clk clk_uart_clk = {
.name = "uart_clk",
.get_rate = imx_get_perclk1,
};
static struct clk clk_perclk2 = {
.name = "perclk2",
.get_rate = imx_get_perclk2,
};
static struct clk clk_perclk3 = {
.name = "perclk3",
.get_rate = imx_get_perclk3,
};
static struct clk *clks[] = {
&clk_perclk1,
&clk_perclk2,
&clk_perclk3,
&clk_system_clk,
&clk_hclk,
&clk_mcu_clk,
&clk_uart_clk,
};
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (!strcmp(p->name, id)) {
clk = p;
goto found;
}
}
found:
mutex_unlock(&clocks_mutex);
return clk;
}
void clk_put(struct clk *clk)
{
}
int clk_enable(struct clk *clk)
{
return 0;
}
void clk_disable(struct clk *clk)
{
}
unsigned long clk_get_rate(struct clk *clk)
{
return clk->get_rate();
}
int imx_clocks_init(void)
{
int i;
mutex_lock(&clocks_mutex);
for (i = 0; i < ARRAY_SIZE(clks); i++)
list_add(&clks[i]->node, &clocks);
mutex_unlock(&clocks_mutex);
return 0;
}
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/hardware.h> #include <asm/hardware.h>
...@@ -52,6 +54,8 @@ ...@@ -52,6 +54,8 @@
static u32 mpctl0_at_boot; static u32 mpctl0_at_boot;
static u32 bclk_div_at_boot; static u32 bclk_div_at_boot;
static struct clk *system_clk, *mcu_clk;
static void imx_set_async_mode(void) static void imx_set_async_mode(void)
{ {
adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE); adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE);
...@@ -160,10 +164,10 @@ static unsigned int imx_get_speed(unsigned int cpu) ...@@ -160,10 +164,10 @@ static unsigned int imx_get_speed(unsigned int cpu)
cr = get_cr(); cr = get_cr();
if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) { if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) {
freq = imx_get_system_clk(); freq = clk_get_rate(system_clk);
freq = (freq + bclk_div/2) / bclk_div; freq = (freq + bclk_div/2) / bclk_div;
} else { } else {
freq = imx_get_mcu_clk(); freq = clk_get_rate(mcu_clk);
if (cscr & CSCR_MPU_PRESC) if (cscr & CSCR_MPU_PRESC)
freq /= 2; freq /= 2;
} }
...@@ -201,7 +205,7 @@ static int imx_set_target(struct cpufreq_policy *policy, ...@@ -201,7 +205,7 @@ static int imx_set_target(struct cpufreq_policy *policy,
pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n", pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n",
freq, mpctl0_at_boot); freq, mpctl0_at_boot);
sysclk = imx_get_system_clk(); sysclk = clk_get_rate(system_clk);
if (freq > sysclk / bclk_div_at_boot + 1000000) { if (freq > sysclk / bclk_div_at_boot + 1000000) {
freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation); freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation);
...@@ -290,6 +294,16 @@ static int __init imx_cpufreq_init(void) ...@@ -290,6 +294,16 @@ static int __init imx_cpufreq_init(void)
bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1; bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1;
mpctl0_at_boot = 0; mpctl0_at_boot = 0;
system_clk = clk_get(NULL, "system_clk");
if (IS_ERR(system_clk))
return PTR_ERR(system_clk);
mcu_clk = clk_get(NULL, "mcu_clk");
if (IS_ERR(mcu_clk)) {
clk_put(system_clk);
return PTR_ERR(mcu_clk);
}
if((CSCR & CSCR_MPEN) && if((CSCR & CSCR_MPEN) &&
((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE)) ((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE))
mpctl0_at_boot = MPCTL0; mpctl0_at_boot = MPCTL0;
......
...@@ -214,82 +214,6 @@ int imx_irq_to_gpio(unsigned irq) ...@@ -214,82 +214,6 @@ int imx_irq_to_gpio(unsigned irq)
EXPORT_SYMBOL(imx_irq_to_gpio); EXPORT_SYMBOL(imx_irq_to_gpio);
/*
* get the system pll clock in Hz
*
* mfi + mfn / (mfd +1)
* f = 2 * f_ref * --------------------
* pd + 1
*/
static unsigned int imx_decode_pll(unsigned int pll, u32 f_ref)
{
unsigned long long ll;
unsigned long quot;
u32 mfi = (pll >> 10) & 0xf;
u32 mfn = pll & 0x3ff;
u32 mfd = (pll >> 16) & 0x3ff;
u32 pd = (pll >> 26) & 0xf;
mfi = mfi <= 5 ? 5 : mfi;
ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) );
quot = (pd+1) * (1<<16);
ll += quot / 2;
do_div(ll, quot);
return (unsigned int) ll;
}
unsigned int imx_get_system_clk(void)
{
u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
return imx_decode_pll(SPCTL0, f_ref);
}
EXPORT_SYMBOL(imx_get_system_clk);
unsigned int imx_get_mcu_clk(void)
{
return imx_decode_pll(MPCTL0, CLK32 * 512);
}
EXPORT_SYMBOL(imx_get_mcu_clk);
/*
* get peripheral clock 1 ( UART[12], Timer[12], PWM )
*/
unsigned int imx_get_perclk1(void)
{
return imx_get_system_clk() / (((PCDR) & 0xf)+1);
}
EXPORT_SYMBOL(imx_get_perclk1);
/*
* get peripheral clock 2 ( LCD, SD, SPI[12] )
*/
unsigned int imx_get_perclk2(void)
{
return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1);
}
EXPORT_SYMBOL(imx_get_perclk2);
/*
* get peripheral clock 3 ( SSI )
*/
unsigned int imx_get_perclk3(void)
{
return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1);
}
EXPORT_SYMBOL(imx_get_perclk3);
/*
* get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
*/
unsigned int imx_get_hclk(void)
{
return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1);
}
EXPORT_SYMBOL(imx_get_hclk);
static struct resource imx_mmc_resources[] = { static struct resource imx_mmc_resources[] = {
[0] = { [0] = {
.start = 0x00214000, .start = 0x00214000,
......
...@@ -69,6 +69,11 @@ static struct resource imx_uart1_resources[] = { ...@@ -69,6 +69,11 @@ static struct resource imx_uart1_resources[] = {
.end = (UART1_MINT_TX), .end = (UART1_MINT_TX),
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
[3] = {
.start = UART1_MINT_RTS,
.end = UART1_MINT_RTS,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device imx_uart1_device = { static struct platform_device imx_uart1_device = {
...@@ -97,6 +102,11 @@ static struct resource imx_uart2_resources[] = { ...@@ -97,6 +102,11 @@ static struct resource imx_uart2_resources[] = {
.end = (UART2_MINT_TX), .end = (UART2_MINT_TX),
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
[3] = {
.start = UART2_MINT_RTS,
.end = UART2_MINT_RTS,
.flags = IORESOURCE_IRQ,
},
}; };
static struct platform_device imx_uart2_device = { static struct platform_device imx_uart2_device = {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/clocksource.h> #include <linux/clocksource.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/clk.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -86,10 +87,10 @@ static struct clocksource clocksource_imx = { ...@@ -86,10 +87,10 @@ static struct clocksource clocksource_imx = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS, .flags = CLOCK_SOURCE_IS_CONTINUOUS,
}; };
static int __init imx_clocksource_init(void) static int __init imx_clocksource_init(unsigned long rate)
{ {
clocksource_imx.mult = clocksource_imx.mult =
clocksource_hz2mult(imx_get_perclk1(), clocksource_imx.shift); clocksource_hz2mult(rate, clocksource_imx.shift);
clocksource_register(&clocksource_imx); clocksource_register(&clocksource_imx);
return 0; return 0;
...@@ -174,9 +175,9 @@ static struct clock_event_device clockevent_imx = { ...@@ -174,9 +175,9 @@ static struct clock_event_device clockevent_imx = {
.rating = 200, .rating = 200,
}; };
static int __init imx_clockevent_init(void) static int __init imx_clockevent_init(unsigned long rate)
{ {
clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC, clockevent_imx.mult = div_sc(rate, NSEC_PER_SEC,
clockevent_imx.shift); clockevent_imx.shift);
clockevent_imx.max_delta_ns = clockevent_imx.max_delta_ns =
clockevent_delta2ns(0xfffffffe, &clockevent_imx); clockevent_delta2ns(0xfffffffe, &clockevent_imx);
...@@ -190,13 +191,23 @@ static int __init imx_clockevent_init(void) ...@@ -190,13 +191,23 @@ static int __init imx_clockevent_init(void)
return 0; return 0;
} }
extern int imx_clocks_init(void);
static void __init imx_timer_init(void) static void __init imx_timer_init(void)
{ {
struct clk *clk;
unsigned long rate;
imx_clocks_init();
clk = clk_get(NULL, "perclk1");
clk_enable(clk);
rate = clk_get_rate(clk);
imx_timer_hardware_init(); imx_timer_hardware_init();
imx_clocksource_init(); imx_clocksource_init(rate);
imx_clockevent_init(); imx_clockevent_init(rate);
/* /*
* Make irqs happen for the system timer * Make irqs happen for the system timer
......
This diff is collapsed.
#
# Makefile for the linux kernel.
#
# Object file lists.
obj-y := system.o generic.o devices.o serial.o
obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
obj-$(CONFIG_MACH_MX27) += clock_imx27.o
obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o
obj-$(CONFIG_MACH_PCM038) += pcm038.o
obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
zreladdr-y := 0xA0008000
params_phys-y := 0xA0000100
initrd_phys-y := 0xA0800000
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -8,5 +8,18 @@ config MACH_MX31ADS ...@@ -8,5 +8,18 @@ config MACH_MX31ADS
Include support for MX31ADS platform. This includes specific Include support for MX31ADS platform. This includes specific
configurations for the board and its peripherals. configurations for the board and its peripherals.
config MACH_PCM037
bool "Support Phytec pcm037 platforms"
help
Include support for Phytec pcm037 platform. This includes
specific configurations for the board and its peripherals.
config MACH_MX31LITE
bool "Support MX31 LITEKIT (LogicPD)"
default n
help
Include support for MX31 LITEKIT platform. This includes specific
configurations for the board and its peripherals.
endmenu endmenu
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment