mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
ARM i.MX25: Add devicetree support
This adds a i.MX25 dt machine descriptor and changes the clock support to optionally initialize from dt. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: Shawn Guo <shawn.guo@linaro.org>
This commit is contained in:
parent
f6d3346f95
commit
ef4bac5532
5 changed files with 109 additions and 4 deletions
|
@ -272,6 +272,13 @@ config MACH_EUKREA_MBIMXSD25_BASEBOARD
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config MACH_IMX25_DT
|
||||||
|
bool "Support i.MX25 platforms from device tree"
|
||||||
|
select SOC_IMX25
|
||||||
|
help
|
||||||
|
Include support for Freescale i.MX25 based platforms
|
||||||
|
using the device tree for discovery
|
||||||
|
|
||||||
comment "MX27 platforms:"
|
comment "MX27 platforms:"
|
||||||
|
|
||||||
config MACH_MX27ADS
|
config MACH_MX27ADS
|
||||||
|
|
|
@ -50,6 +50,7 @@ obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
|
||||||
obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
|
obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
|
||||||
obj-$(CONFIG_MACH_EUKREA_CPUIMX25SD) += mach-eukrea_cpuimx25.o
|
obj-$(CONFIG_MACH_EUKREA_CPUIMX25SD) += mach-eukrea_cpuimx25.o
|
||||||
obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o
|
obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o
|
||||||
|
obj-$(CONFIG_MACH_IMX25_DT) += imx25-dt.o
|
||||||
|
|
||||||
# i.MX27 based machines
|
# i.MX27 based machines
|
||||||
obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
|
obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/clkdev.h>
|
#include <linux/clkdev.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
|
||||||
#include "clk.h"
|
#include "clk.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -55,6 +58,8 @@
|
||||||
|
|
||||||
#define ccm(x) (CRM_BASE + (x))
|
#define ccm(x) (CRM_BASE + (x))
|
||||||
|
|
||||||
|
static struct clk_onecell_data clk_data;
|
||||||
|
|
||||||
static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
|
static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
|
||||||
static const char *per_sel_clks[] = { "ahb", "upll", };
|
static const char *per_sel_clks[] = { "ahb", "upll", };
|
||||||
|
|
||||||
|
@ -82,12 +87,12 @@ enum mx25_clks {
|
||||||
|
|
||||||
static struct clk *clk[clk_max];
|
static struct clk *clk[clk_max];
|
||||||
|
|
||||||
int __init mx25_clocks_init(void)
|
static int __init __mx25_clocks_init(unsigned long osc_rate)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
clk[dummy] = imx_clk_fixed("dummy", 0);
|
clk[dummy] = imx_clk_fixed("dummy", 0);
|
||||||
clk[osc] = imx_clk_fixed("osc", 24000000);
|
clk[osc] = imx_clk_fixed("osc", osc_rate);
|
||||||
clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
|
clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
|
||||||
clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
|
clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
|
||||||
clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
|
clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
|
||||||
|
@ -219,6 +224,16 @@ int __init mx25_clocks_init(void)
|
||||||
|
|
||||||
clk_prepare_enable(clk[emi_ahb]);
|
clk_prepare_enable(clk[emi_ahb]);
|
||||||
|
|
||||||
|
clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
|
||||||
|
clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __init mx25_clocks_init(void)
|
||||||
|
{
|
||||||
|
__mx25_clocks_init(24000000);
|
||||||
|
|
||||||
/* i.mx25 has the i.mx21 type uart */
|
/* i.mx25 has the i.mx21 type uart */
|
||||||
clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0");
|
clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0");
|
||||||
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0");
|
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0");
|
||||||
|
@ -230,8 +245,6 @@ int __init mx25_clocks_init(void)
|
||||||
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3");
|
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3");
|
||||||
clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4");
|
clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4");
|
||||||
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4");
|
clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4");
|
||||||
clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
|
|
||||||
clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
|
|
||||||
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
|
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
|
||||||
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0");
|
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0");
|
||||||
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
|
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
|
||||||
|
@ -289,5 +302,40 @@ int __init mx25_clocks_init(void)
|
||||||
clk_register_clkdev(clk[iim_ipg], "iim", NULL);
|
clk_register_clkdev(clk[iim_ipg], "iim", NULL);
|
||||||
|
|
||||||
mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
|
mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __init mx25_clocks_init_dt(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
void __iomem *base;
|
||||||
|
int irq;
|
||||||
|
unsigned long osc_rate = 24000000;
|
||||||
|
|
||||||
|
/* retrieve the freqency of fixed clocks from device tree */
|
||||||
|
for_each_compatible_node(np, NULL, "fixed-clock") {
|
||||||
|
u32 rate;
|
||||||
|
if (of_property_read_u32(np, "clock-frequency", &rate))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (of_device_is_compatible(np, "fsl,imx-osc"))
|
||||||
|
osc_rate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
np = of_find_compatible_node(NULL, NULL, "fsl,imx25-ccm");
|
||||||
|
clk_data.clks = clk;
|
||||||
|
clk_data.clk_num = ARRAY_SIZE(clk);
|
||||||
|
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||||
|
|
||||||
|
__mx25_clocks_init(osc_rate);
|
||||||
|
|
||||||
|
np = of_find_compatible_node(NULL, NULL, "fsl,imx25-gpt");
|
||||||
|
base = of_iomap(np, 0);
|
||||||
|
WARN_ON(!base);
|
||||||
|
irq = irq_of_parse_and_map(np, 0);
|
||||||
|
|
||||||
|
mxc_timer_init(base, irq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
|
||||||
unsigned long ckih1, unsigned long ckih2);
|
unsigned long ckih1, unsigned long ckih2);
|
||||||
extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
|
extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
|
||||||
unsigned long ckih1, unsigned long ckih2);
|
unsigned long ckih1, unsigned long ckih2);
|
||||||
|
extern int mx25_clocks_init_dt(void);
|
||||||
extern int mx27_clocks_init_dt(void);
|
extern int mx27_clocks_init_dt(void);
|
||||||
extern int mx31_clocks_init_dt(void);
|
extern int mx31_clocks_init_dt(void);
|
||||||
extern int mx51_clocks_init_dt(void);
|
extern int mx51_clocks_init_dt(void);
|
||||||
|
|
48
arch/arm/mach-imx/imx25-dt.c
Normal file
48
arch/arm/mach-imx/imx25-dt.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Sascha Hauer, Pengutronix
|
||||||
|
*
|
||||||
|
* The code contained herein is licensed under the GNU General Public
|
||||||
|
* License. You may obtain a copy of the GNU General Public License
|
||||||
|
* Version 2 or later at the following locations:
|
||||||
|
*
|
||||||
|
* http://www.opensource.org/licenses/gpl-license.html
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
#include <asm/mach/time.h>
|
||||||
|
#include "common.h"
|
||||||
|
#include "mx25.h"
|
||||||
|
|
||||||
|
static void __init imx25_dt_init(void)
|
||||||
|
{
|
||||||
|
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init imx25_timer_init(void)
|
||||||
|
{
|
||||||
|
mx25_clocks_init_dt();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct sys_timer imx25_timer = {
|
||||||
|
.init = imx25_timer_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const imx25_dt_board_compat[] __initconst = {
|
||||||
|
"fsl,imx25",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)")
|
||||||
|
.map_io = mx25_map_io,
|
||||||
|
.init_early = imx25_init_early,
|
||||||
|
.init_irq = mx25_init_irq,
|
||||||
|
.handle_irq = imx25_handle_irq,
|
||||||
|
.timer = &imx25_timer,
|
||||||
|
.init_machine = imx25_dt_init,
|
||||||
|
.dt_compat = imx25_dt_board_compat,
|
||||||
|
.restart = mxc_restart,
|
||||||
|
MACHINE_END
|
Loading…
Reference in a new issue