diff options
Diffstat (limited to 'arch/arm/mach-mxs')
-rw-r--r-- | arch/arm/mach-mxs/clock-mx23.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-mxs/clock-mx28.c | 48 | ||||
-rw-r--r-- | arch/arm/mach-mxs/clock.c | 33 | ||||
-rw-r--r-- | arch/arm/mach-mxs/devices-mx28.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-mxs/devices/platform-mxs-saif.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-mxs/include/mach/common.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-mxs/include/mach/devices-common.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-mxs/include/mach/digctl.h | 21 | ||||
-rw-r--r-- | arch/arm/mach-mxs/include/mach/mx28.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-mxs/include/mach/mxs.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-mxs/include/mach/system.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-mxs/mach-m28evk.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-mxs/mach-mx23evk.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-mxs/mach-mx28evk.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-mxs/mach-stmp378x_devb.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-mxs/mach-tx28.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-mxs/module-tx28.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-mxs/system.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-mxs/timer.c | 2 |
19 files changed, 134 insertions, 38 deletions
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c index 0163b6d83773..e12e11231dc7 100644 --- a/arch/arm/mach-mxs/clock-mx23.c +++ b/arch/arm/mach-mxs/clock-mx23.c @@ -545,11 +545,11 @@ int __init mx23_clocks_init(void) */ clk_set_parent(&ssp_clk, &ref_io_clk); - clk_enable(&cpu_clk); - clk_enable(&hbus_clk); - clk_enable(&xbus_clk); - clk_enable(&emi_clk); - clk_enable(&uart_clk); + clk_prepare_enable(&cpu_clk); + clk_prepare_enable(&hbus_clk); + clk_prepare_enable(&xbus_clk); + clk_prepare_enable(&emi_clk); + clk_prepare_enable(&uart_clk); clkdev_add_table(lookups, ARRAY_SIZE(lookups)); diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index da6e4aad177c..5d68e4152220 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c @@ -22,6 +22,7 @@ #include <linux/io.h> #include <linux/jiffies.h> #include <linux/clkdev.h> +#include <linux/spinlock.h> #include <asm/clkdev.h> #include <asm/div64.h> @@ -29,6 +30,7 @@ #include <mach/mx28.h> #include <mach/common.h> #include <mach/clock.h> +#include <mach/digctl.h> #include "regs-clkctrl-mx28.h" @@ -43,6 +45,33 @@ static struct clk emi_clk; static struct clk saif0_clk; static struct clk saif1_clk; static struct clk clk32k_clk; +static DEFINE_SPINLOCK(clkmux_lock); + +/* + * HW_SAIF_CLKMUX_SEL: + * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1 + * clock pins selected for SAIF1 input clocks. + * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and + * SAIF0 clock inputs selected for SAIF1 input clocks. + * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input + * clocks. + * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input + * clocks. + */ +int mxs_saif_clkmux_select(unsigned int clkmux) +{ + if (clkmux > 0x3) + return -EINVAL; + + spin_lock(&clkmux_lock); + __raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX, + DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR); + __raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX, + DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR); + spin_unlock(&clkmux_lock); + + return 0; +} static int _raw_clk_enable(struct clk *clk) { @@ -775,16 +804,25 @@ int __init mx28_clocks_init(void) clk_set_parent(&ssp0_clk, &ref_io0_clk); clk_set_parent(&ssp1_clk, &ref_io0_clk); - clk_enable(&cpu_clk); - clk_enable(&hbus_clk); - clk_enable(&xbus_clk); - clk_enable(&emi_clk); - clk_enable(&uart_clk); + clk_prepare_enable(&cpu_clk); + clk_prepare_enable(&hbus_clk); + clk_prepare_enable(&xbus_clk); + clk_prepare_enable(&emi_clk); + clk_prepare_enable(&uart_clk); clk_set_parent(&lcdif_clk, &ref_pix_clk); clk_set_parent(&saif0_clk, &pll0_clk); clk_set_parent(&saif1_clk, &pll0_clk); + /* + * Set an initial clock rate for the saif internal logic to work + * properly. This is important when working in EXTMASTER mode that + * uses the other saif's BITCLK&LRCLK but it still needs a basic + * clock which should be fast enough for the internal logic. + */ + clk_set_rate(&saif0_clk, 24000000); + clk_set_rate(&saif1_clk, 24000000); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0); diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c index a7093c88e6a6..97a6f4acc6cc 100644 --- a/arch/arm/mach-mxs/clock.c +++ b/arch/arm/mach-mxs/clock.c @@ -74,10 +74,15 @@ static int __clk_enable(struct clk *clk) return 0; } -/* This function increments the reference count on the clock and enables the - * clock if not already enabled. The parent clock tree is recursively enabled +/* + * The clk_enable/clk_disable could be called by drivers in atomic context, + * so they should not really hold mutex. Instead, clk_prepare/clk_unprepare + * can hold a mutex, as the pair will only be called in non-atomic context. + * Before migrating to common clk framework, we can have __clk_enable and + * __clk_disable called in clk_prepare/clk_unprepare with mutex held and + * leave clk_enable/clk_disable as the dummy functions. */ -int clk_enable(struct clk *clk) +int clk_prepare(struct clk *clk) { int ret = 0; @@ -90,13 +95,9 @@ int clk_enable(struct clk *clk) return ret; } -EXPORT_SYMBOL(clk_enable); +EXPORT_SYMBOL(clk_prepare); -/* This function decrements the reference count on the clock and disables - * the clock when reference count is 0. The parent clock tree is - * recursively disabled - */ -void clk_disable(struct clk *clk) +void clk_unprepare(struct clk *clk) { if (clk == NULL || IS_ERR(clk)) return; @@ -105,6 +106,18 @@ void clk_disable(struct clk *clk) __clk_disable(clk); mutex_unlock(&clocks_mutex); } +EXPORT_SYMBOL(clk_unprepare); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + /* nothing to do */ +} EXPORT_SYMBOL(clk_disable); /* Retrieve the *current* clock rate. If the clock itself @@ -166,7 +179,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) return ret; if (clk->usecount) - clk_enable(parent); + clk_prepare_enable(parent); mutex_lock(&clocks_mutex); ret = clk->set_parent(clk, parent); diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h index c8887103f0e3..4f50094e293d 100644 --- a/arch/arm/mach-mxs/devices-mx28.h +++ b/arch/arm/mach-mxs/devices-mx28.h @@ -47,6 +47,7 @@ struct platform_device *__init mx28_add_mxsfb( const struct mxsfb_platform_data *pdata); extern const struct mxs_saif_data mx28_saif_data[] __initconst; -#define mx28_add_saif(id) mxs_add_saif(&mx28_saif_data[id]) +#define mx28_add_saif(id, pdata) \ + mxs_add_saif(&mx28_saif_data[id], pdata) struct platform_device *__init mx28_add_rtc_stmp3xxx(void); diff --git a/arch/arm/mach-mxs/devices/platform-mxs-saif.c b/arch/arm/mach-mxs/devices/platform-mxs-saif.c index 1ec965e9fe92..f6e3a60b4201 100644 --- a/arch/arm/mach-mxs/devices/platform-mxs-saif.c +++ b/arch/arm/mach-mxs/devices/platform-mxs-saif.c @@ -32,7 +32,8 @@ const struct mxs_saif_data mx28_saif_data[] __initconst = { }; #endif -struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data) +struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data, + const struct mxs_saif_platform_data *pdata) { struct resource res[] = { { @@ -56,5 +57,5 @@ struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data) }; return mxs_add_platform_device("mxs-saif", data->id, res, - ARRAY_SIZE(res), NULL, 0); + ARRAY_SIZE(res), pdata, sizeof(*pdata)); } diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h index 635bb5d9a20a..e1237ab25862 100644 --- a/arch/arm/mach-mxs/include/mach/common.h +++ b/arch/arm/mach-mxs/include/mach/common.h @@ -16,6 +16,8 @@ struct clk; extern const u32 *mxs_get_ocotp(void); extern int mxs_reset_block(void __iomem *); extern void mxs_timer_init(struct clk *, int); +extern void mxs_restart(char, const char *); +extern int mxs_saif_clkmux_select(unsigned int clkmux); extern int mx23_register_gpios(void); extern int mx23_clocks_init(void); diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h index a8080f44c03d..dc369c1239fc 100644 --- a/arch/arm/mach-mxs/include/mach/devices-common.h +++ b/arch/arm/mach-mxs/include/mach/devices-common.h @@ -94,6 +94,7 @@ struct platform_device *__init mxs_add_mxs_pwm( resource_size_t iobase, int id); /* saif */ +#include <sound/saif.h> struct mxs_saif_data { int id; resource_size_t iobase; @@ -103,4 +104,5 @@ struct mxs_saif_data { }; struct platform_device *__init mxs_add_saif( - const struct mxs_saif_data *data); + const struct mxs_saif_data *data, + const struct mxs_saif_platform_data *pdata); diff --git a/arch/arm/mach-mxs/include/mach/digctl.h b/arch/arm/mach-mxs/include/mach/digctl.h new file mode 100644 index 000000000000..49a888c65d6d --- /dev/null +++ b/arch/arm/mach-mxs/include/mach/digctl.h @@ -0,0 +1,21 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __MACH_DIGCTL_H__ +#define __MACH_DIGCTL_H__ + +/* MXS DIGCTL SAIF CLKMUX */ +#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT 0x0 +#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT 0x1 +#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2 +#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3 + +#define HW_DIGCTL_CTRL 0x0 +#define BP_DIGCTL_CTRL_SAIF_CLKMUX 10 +#define BM_DIGCTL_CTRL_SAIF_CLKMUX (0x3 << 10) +#endif diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h index 75d86118b76a..30c7990f3c01 100644 --- a/arch/arm/mach-mxs/include/mach/mx28.h +++ b/arch/arm/mach-mxs/include/mach/mx28.h @@ -104,8 +104,8 @@ #define MX28_INT_CAN1 9 #define MX28_INT_LRADC_TOUCH 10 #define MX28_INT_HSADC 13 -#define MX28_INT_IRADC_THRESH0 14 -#define MX28_INT_IRADC_THRESH1 15 +#define MX28_INT_LRADC_THRESH0 14 +#define MX28_INT_LRADC_THRESH1 15 #define MX28_INT_LRADC_CH0 16 #define MX28_INT_LRADC_CH1 17 #define MX28_INT_LRADC_CH2 18 diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h index 0d2d2b470998..bde5f6634747 100644 --- a/arch/arm/mach-mxs/include/mach/mxs.h +++ b/arch/arm/mach-mxs/include/mach/mxs.h @@ -30,6 +30,7 @@ */ #define cpu_is_mx23() ( \ machine_is_mx23evk() || \ + machine_is_stmp378x() || \ 0) #define cpu_is_mx28() ( \ machine_is_mx28evk() || \ diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h index 0e428239b433..e7ad1bb29423 100644 --- a/arch/arm/mach-mxs/include/mach/system.h +++ b/arch/arm/mach-mxs/include/mach/system.h @@ -22,6 +22,4 @@ static inline void arch_idle(void) cpu_do_idle(); } -void arch_reset(char mode, const char *cmd); - #endif /* __MACH_MXS_SYSTEM_H__ */ diff --git a/arch/arm/mach-mxs/mach-m28evk.c b/arch/arm/mach-mxs/mach-m28evk.c index 3b1681e4f49a..2f2758230edf 100644 --- a/arch/arm/mach-mxs/mach-m28evk.c +++ b/arch/arm/mach-mxs/mach-m28evk.c @@ -361,6 +361,7 @@ static struct sys_timer m28evk_timer = { MACHINE_START(M28EVK, "DENX M28 EVK") .map_io = mx28_map_io, .init_irq = mx28_init_irq, - .init_machine = m28evk_init, .timer = &m28evk_timer, + .init_machine = m28evk_init, + .restart = mxs_restart, MACHINE_END diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c index c325fbe4e4c6..5ea1c57d2606 100644 --- a/arch/arm/mach-mxs/mach-mx23evk.c +++ b/arch/arm/mach-mxs/mach-mx23evk.c @@ -184,4 +184,5 @@ MACHINE_START(MX23EVK, "Freescale MX23 EVK") .init_irq = mx23_init_irq, .timer = &mx23evk_timer, .init_machine = mx23evk_init, + .restart = mxs_restart, MACHINE_END diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c index 064ec5abaa55..fdb0a5664dd6 100644 --- a/arch/arm/mach-mxs/mach-mx28evk.c +++ b/arch/arm/mach-mxs/mach-mx28evk.c @@ -27,6 +27,7 @@ #include <mach/common.h> #include <mach/iomux-mx28.h> +#include <mach/digctl.h> #include "devices-mx28.h" @@ -228,7 +229,7 @@ static void __init mx28evk_fec_reset(void) /* Enable fec phy clock */ clk = clk_get_sys("pll2", NULL); if (!IS_ERR(clk)) - clk_enable(clk); + clk_prepare_enable(clk); /* Power up fec phy */ ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power"); @@ -421,6 +422,18 @@ static struct gpio mx28evk_lcd_gpios[] = { { MX28EVK_BL_ENABLE, GPIOF_OUT_INIT_HIGH, "bl-enable" }, }; +static const struct mxs_saif_platform_data + mx28evk_mxs_saif_pdata[] __initconst = { + /* working on EXTMSTR0 mode (saif0 master, saif1 slave) */ + { + .master_mode = 1, + .master_id = 0, + }, { + .master_mode = 0, + .master_id = 0, + }, +}; + static void __init mx28evk_init(void) { int ret; @@ -454,8 +467,9 @@ static void __init mx28evk_init(void) else mx28_add_mxsfb(&mx28evk_mxsfb_pdata); - mx28_add_saif(0); - mx28_add_saif(1); + mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0); + mx28_add_saif(0, &mx28evk_mxs_saif_pdata[0]); + mx28_add_saif(1, &mx28evk_mxs_saif_pdata[1]); mx28_add_mxs_i2c(0); i2c_register_board_info(0, mxs_i2c0_board_info, @@ -501,4 +515,5 @@ MACHINE_START(MX28EVK, "Freescale MX28 EVK") .init_irq = mx28_init_irq, .timer = &mx28evk_timer, .init_machine = mx28evk_init, + .restart = mxs_restart, MACHINE_END diff --git a/arch/arm/mach-mxs/mach-stmp378x_devb.c b/arch/arm/mach-mxs/mach-stmp378x_devb.c index 177e53123a02..a626c07b8713 100644 --- a/arch/arm/mach-mxs/mach-stmp378x_devb.c +++ b/arch/arm/mach-mxs/mach-stmp378x_devb.c @@ -115,6 +115,7 @@ static struct sys_timer stmp378x_dvb_timer = { MACHINE_START(STMP378X, "STMP378X") .map_io = mx23_map_io, .init_irq = mx23_init_irq, - .init_machine = stmp378x_dvb_init, .timer = &stmp378x_dvb_timer, + .init_machine = stmp378x_dvb_init, + .restart = mxs_restart, MACHINE_END diff --git a/arch/arm/mach-mxs/mach-tx28.c b/arch/arm/mach-mxs/mach-tx28.c index 9a1f0e7a338e..2c0862e655ee 100644 --- a/arch/arm/mach-mxs/mach-tx28.c +++ b/arch/arm/mach-mxs/mach-tx28.c @@ -178,4 +178,5 @@ MACHINE_START(TX28, "Ka-Ro electronics TX28 module") .init_irq = mx28_init_irq, .timer = &tx28_timer, .init_machine = tx28_stk5v3_init, + .restart = mxs_restart, MACHINE_END diff --git a/arch/arm/mach-mxs/module-tx28.c b/arch/arm/mach-mxs/module-tx28.c index 0fcff47009cf..9a7b08b2a925 100644 --- a/arch/arm/mach-mxs/module-tx28.c +++ b/arch/arm/mach-mxs/module-tx28.c @@ -66,11 +66,11 @@ static const iomux_cfg_t tx28_fec1_pads[] __initconst = { MX28_PAD_ENET0_CRS__ENET1_RX_EN, }; -static struct fec_platform_data tx28_fec0_data = { +static const struct fec_platform_data tx28_fec0_data __initconst = { .phy = PHY_INTERFACE_MODE_RMII, }; -static struct fec_platform_data tx28_fec1_data = { +static const struct fec_platform_data tx28_fec1_data __initconst = { .phy = PHY_INTERFACE_MODE_RMII, }; diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c index cab88364e7c1..54f91ad1c965 100644 --- a/arch/arm/mach-mxs/system.c +++ b/arch/arm/mach-mxs/system.c @@ -42,7 +42,7 @@ static void __iomem *mxs_clkctrl_reset_addr; /* * Reset the system. It is called by machine_restart(). */ -void arch_reset(char mode, const char *cmd) +void mxs_restart(char mode, const char *cmd) { /* reset the chip */ __mxs_setl(MXS_CLKCTRL_RESET_CHIP, mxs_clkctrl_reset_addr); @@ -66,7 +66,7 @@ static int __init mxs_arch_reset_init(void) clk = clk_get_sys("rtc", NULL); if (!IS_ERR(clk)) - clk_enable(clk); + clk_prepare_enable(clk); return 0; } diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c index cace0d2e5a55..564a63279f18 100644 --- a/arch/arm/mach-mxs/timer.c +++ b/arch/arm/mach-mxs/timer.c @@ -245,7 +245,7 @@ static int __init mxs_clocksource_init(struct clk *timer_clk) void __init mxs_timer_init(struct clk *timer_clk, int irq) { - clk_enable(timer_clk); + clk_prepare_enable(timer_clk); /* * Initialize timers to a known state |