diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2011-05-04 10:43:33 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2011-05-04 10:43:33 +1000 |
commit | cb866a532573990e02e9ecf87ece24219518dc7a (patch) | |
tree | 1ab707061c6a6dea6d327bcb5a5100cea2930a3f /arch | |
parent | 4f7fb6583ab0cb3a6090cae31befba4db83cf3e7 (diff) | |
parent | f2ba30560a71b39b4ad3230f5deb96fefaaa6417 (diff) |
Merge remote-tracking branch 'msm/for-next'
Diffstat (limited to 'arch')
25 files changed, 807 insertions, 132 deletions
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 9519fd28a025..c72cb8e0e690 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,5 +1,6 @@ obj-y += io.o idle.o timer.o obj-y += clock.o +obj-y += clock-dummy.o obj-$(CONFIG_DEBUG_FS) += clock-debug.o obj-$(CONFIG_MSM_VIC) += irq-vic.o @@ -8,6 +9,8 @@ obj-$(CONFIG_MSM_IOMMU) += iommu.o iommu_dev.o devices-iommu.o obj-$(CONFIG_ARCH_MSM7X00A) += dma.o irq.o acpuclock-arm11.o obj-$(CONFIG_ARCH_MSM7X30) += dma.o obj-$(CONFIG_ARCH_QSD8X50) += dma.o sirc.o +obj-$(CONFIG_ARCH_MSM8X60) += dma.o +obj-$(CONFIG_ARCH_MSM8960) += dma.o obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o @@ -23,7 +26,7 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o b obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o -obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o +obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o devices-msm8x60.o obj-$(CONFIG_ARCH_MSM8960) += board-msm8960.o devices-msm8960.o obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-v1.o gpiomux.o diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c index 805d4ee53f7e..30f4ace13a46 100644 --- a/arch/arm/mach-msm/acpuclock-arm11.c +++ b/arch/arm/mach-msm/acpuclock-arm11.c @@ -376,7 +376,7 @@ int acpuclk_set_rate(unsigned long rate, int for_power_collapse) } #if PERF_SWITCH_STEP_DEBUG printk(KERN_DEBUG "%s: STEP khz = %u, pll = %d\n", - __FUNCTION__, cur_s->a11clk_khz, cur_s->pll); + __func__, cur_s->a11clk_khz, cur_s->pll); #endif if (!for_power_collapse&& cur_s->pll != ACPU_PLL_TCXO && !(plls_enabled & (1 << cur_s->pll))) { diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index 18a3c97bc863..4d264eb9a3b1 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -59,6 +59,7 @@ static struct platform_device smc91x_device = { static struct platform_device *devices[] __initdata = { &msm_device_uart3, + &msm_device_dmov, &msm_device_smd, &msm_device_nand, &msm_device_hsusb, diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c index 7a9a03eb189c..db3201ad8652 100644 --- a/arch/arm/mach-msm/board-mahimahi.c +++ b/arch/arm/mach-msm/board-mahimahi.c @@ -44,6 +44,7 @@ static struct platform_device *devices[] __initdata = { #if !defined(CONFIG_MSM_SERIAL_DEBUGGER) &msm_device_uart1, #endif + &msm_device_dmov, &msm_device_uart_dm1, &msm_device_nand, }; diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index b7a84966b711..8d21769d288e 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -79,6 +79,7 @@ static struct platform_device *devices[] __initdata = { #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) &msm_device_uart2, #endif + &msm_device_dmov, &msm_device_smd, &msm_device_otg, &msm_device_hsusb, diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c index 35c7ceeb3f29..8294692c27d7 100644 --- a/arch/arm/mach-msm/board-msm8960.c +++ b/arch/arm/mach-msm/board-msm8960.c @@ -35,6 +35,11 @@ static void __init msm8960_map_io(void) msm_map_msm8960_io(); } +static void __init msm8960_init_early(void) +{ + msm_clock_init(msm_clocks_8960, msm_num_clocks_8960); +} + static void __init msm8960_init_irq(void) { unsigned int i; @@ -65,18 +70,30 @@ static struct platform_device *rumi3_devices[] __initdata = { &msm8960_device_uart_gsbi5, }; +static struct platform_device *devices[] __initdata = { + &msm8960_device_dmov, +}; + +static void __init msm8960_init(void) +{ + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + static void __init msm8960_sim_init(void) { + msm8960_init(); platform_add_devices(sim_devices, ARRAY_SIZE(sim_devices)); } static void __init msm8960_rumi3_init(void) { + msm8960_init(); platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices)); } MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR") .map_io = msm8960_map_io, + .init_early = msm8960_init_early, .init_irq = msm8960_init_irq, .timer = &msm_timer, .init_machine = msm8960_sim_init, @@ -84,6 +101,7 @@ MACHINE_END MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3") .map_io = msm8960_map_io, + .init_early = msm8960_init_early, .init_irq = msm8960_init_irq, .timer = &msm_timer, .init_machine = msm8960_rumi3_init, diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c index 1163b6fd05d2..98c47ce517fb 100644 --- a/arch/arm/mach-msm/board-msm8x60.c +++ b/arch/arm/mach-msm/board-msm8x60.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. +/* Copyright (c) 2010-2011, Code Aurora Forum. 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 and @@ -27,6 +27,7 @@ #include <mach/board.h> #include <mach/msm_iomap.h> +#include "devices.h" static void __init msm8x60_map_io(void) @@ -34,6 +35,11 @@ static void __init msm8x60_map_io(void) msm_map_msm8x60_io(); } +static struct platform_device *devices[] __initdata = { + &msm_device_dmov_adm0, + &msm_device_dmov_adm1, +}; + static void __init msm8x60_init_irq(void) { unsigned int i; @@ -62,6 +68,7 @@ static void __init msm8x60_init_irq(void) static void __init msm8x60_init(void) { + platform_add_devices(devices, ARRAY_SIZE(devices)); } MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3") diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index 6a96911b0ad5..491fe76687b1 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -93,6 +93,7 @@ static struct msm_otg_platform_data msm_otg_pdata = { static struct platform_device *devices[] __initdata = { &msm_device_uart3, + &msm_device_dmov, &msm_device_smd, &msm_device_otg, &msm_device_hsusb, diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index 814386772c66..5831ce573739 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -35,6 +35,7 @@ extern int trout_init_mmc(unsigned int); static struct platform_device *devices[] __initdata = { &msm_device_uart3, + &msm_device_dmov, &msm_device_smd, &msm_device_nand, &msm_device_hsusb, diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c new file mode 100644 index 000000000000..8ae376867a51 --- /dev/null +++ b/arch/arm/mach-msm/clock-dummy.c @@ -0,0 +1,81 @@ +/* Copyright (c) 2011, Code Aurora Forum. 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 and + * only version 2 as published by the Free Software Foundation. + * + * 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 "clock.h" + +static int dummy_clk_enable(unsigned id) +{ + return 0; +} + +static void dummy_clk_disable(unsigned id) +{ +} + +static int dummy_clk_reset(unsigned id, enum clk_reset_action action) +{ + return 0; +} + +static int dummy_clk_set_rate(unsigned id, unsigned rate) +{ + return 0; +} + +static int dummy_clk_set_min_rate(unsigned id, unsigned rate) +{ + return 0; +} + +static int dummy_clk_set_max_rate(unsigned id, unsigned rate) +{ + return 0; +} + +static int dummy_clk_set_flags(unsigned id, unsigned flags) +{ + return 0; +} + +static unsigned dummy_clk_get_rate(unsigned id) +{ + return 0; +} + +static unsigned dummy_clk_is_enabled(unsigned id) +{ + return 0; +} + +static long dummy_clk_round_rate(unsigned id, unsigned rate) +{ + return rate; +} + +static bool dummy_clk_is_local(unsigned id) +{ + return true; +} + +struct clk_ops clk_ops_dummy = { + .enable = dummy_clk_enable, + .disable = dummy_clk_disable, + .reset = dummy_clk_reset, + .set_rate = dummy_clk_set_rate, + .set_min_rate = dummy_clk_set_min_rate, + .set_max_rate = dummy_clk_set_max_rate, + .set_flags = dummy_clk_set_flags, + .get_rate = dummy_clk_get_rate, + .is_enabled = dummy_clk_is_enabled, + .round_rate = dummy_clk_round_rate, + .is_local = dummy_clk_is_local, +}; diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h index 2c007f606d29..1e6207463e6d 100644 --- a/arch/arm/mach-msm/clock.h +++ b/arch/arm/mach-msm/clock.h @@ -69,4 +69,15 @@ static inline int __init clock_debug_init(void) { return 0; } static inline int __init clock_debug_add(struct clk *clock) { return 0; } #endif +extern struct clk_ops clk_ops_dummy; + +#define CLK_DUMMY(clk_name, clk_id, clk_dev) { \ + .con_id = clk_name, \ + .dev_id = clk_dev, \ + .clk = &(struct clk){ \ + .dbg_name = #clk_id, \ + .ops = &clk_ops_dummy, \ + }, \ + } + #endif diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c index c4f5e26feb4d..3ef38a53c508 100644 --- a/arch/arm/mach-msm/devices-msm7x00.c +++ b/arch/arm/mach-msm/devices-msm7x00.c @@ -418,8 +418,27 @@ struct platform_device msm_device_mdp = { .resource = resources_mdp, }; +static struct resource resources_dmov[] = { + { + .start = MSM7X00_DMOV_PHYS, + .end = MSM7X00_DMOV_PHYS + MSM7X00_DMOV_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_ADM_AARM, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm_device_dmov = { + .name = "msm_dmov", + .id = -1, + .num_resources = ARRAY_SIZE(resources_dmov), + .resource = resources_dmov, +}; + struct clk_lookup msm_clocks_7x01a[] = { - CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), + CLK_PCOM("adm_clk", ADM_CLK, "msm_dmov", 0), CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0), CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0), diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c index 09b4f1403824..f803fcd380d0 100644 --- a/arch/arm/mach-msm/devices-msm7x30.c +++ b/arch/arm/mach-msm/devices-msm7x30.c @@ -130,8 +130,27 @@ struct platform_device msm_device_hsusb_host = { }, }; +static struct resource resources_dmov[] = { + { + .start = MSM7X30_DMOV_PHYS, + .end = MSM7X30_DMOV_PHYS + MSM7X30_DMOV_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_ADM_AARM, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm_device_dmov = { + .name = "msm_dmov", + .id = -1, + .num_resources = ARRAY_SIZE(resources_dmov), + .resource = resources_dmov, +}; + struct clk_lookup msm_clocks_7x30[] = { - CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), + CLK_PCOM("adm_clk", ADM_CLK, "msm_dmov", 0), CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0), CLK_PCOM("camif_pad_pclk", CAMIF_PAD_P_CLK, NULL, OFF), diff --git a/arch/arm/mach-msm/devices-msm8960.c b/arch/arm/mach-msm/devices-msm8960.c index d9e1f26475de..2e17ac6f1f04 100644 --- a/arch/arm/mach-msm/devices-msm8960.c +++ b/arch/arm/mach-msm/devices-msm8960.c @@ -21,8 +21,11 @@ #include <linux/dma-mapping.h> #include <mach/irqs-8960.h> #include <mach/board.h> +#include <mach/msm_iomap.h> +#include <mach/irqs.h> #include "devices.h" +#include "clock.h" #define MSM_GSBI2_PHYS 0x16100000 #define MSM_UART2DM_PHYS (MSM_GSBI2_PHYS + 0x40000) @@ -83,3 +86,181 @@ struct platform_device msm8960_device_uart_gsbi5 = { .num_resources = ARRAY_SIZE(resources_uart_gsbi5), .resource = resources_uart_gsbi5, }; + +static struct resource resources_dmov[] = { + { + .start = MSM8960_DMOV_PHYS, + .end = MSM8960_DMOV_PHYS + MSM8960_DMOV_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_ADM0_SCSS_0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm8960_device_dmov = { + .name = "msm_dmov", + .id = -1, + .num_resources = ARRAY_SIZE(resources_dmov), + .resource = resources_dmov, +}; + +struct clk_lookup msm_clocks_8960[] = { + CLK_DUMMY("gsbi_uart_clk", GSBI1_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI2_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI3_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI4_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI5_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI6_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI7_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI8_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI9_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI10_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI11_UART_CLK, NULL), + CLK_DUMMY("gsbi_uart_clk", GSBI12_UART_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI1_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI2_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI3_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI4_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI5_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI6_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI7_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI8_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI9_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI10_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI11_QUP_CLK, NULL), + CLK_DUMMY("gsbi_qup_clk", GSBI12_QUP_CLK, NULL), + CLK_DUMMY("pdm_clk", PDM_CLK, NULL), + CLK_DUMMY("pmem_clk", PMEM_CLK, NULL), + CLK_DUMMY("prng_clk", PRNG_CLK, NULL), + CLK_DUMMY("sdc_clk", SDC1_CLK, NULL), + CLK_DUMMY("sdc_clk", SDC2_CLK, NULL), + CLK_DUMMY("sdc_clk", SDC3_CLK, NULL), + CLK_DUMMY("sdc_clk", SDC4_CLK, NULL), + CLK_DUMMY("sdc_clk", SDC5_CLK, NULL), + CLK_DUMMY("tsif_ref_clk", TSIF_REF_CLK, NULL), + CLK_DUMMY("tssc_clk", TSSC_CLK, NULL), + CLK_DUMMY("usb_hs_clk", USB_HS1_XCVR_CLK, NULL), + CLK_DUMMY("usb_phy_clk", USB_PHY0_CLK, NULL), + CLK_DUMMY("usb_fs_src_clk", USB_FS1_SRC_CLK, NULL), + CLK_DUMMY("usb_fs_clk", USB_FS1_XCVR_CLK, NULL), + CLK_DUMMY("usb_fs_sys_clk", USB_FS1_SYS_CLK, NULL), + CLK_DUMMY("usb_fs_src_clk", USB_FS2_SRC_CLK, NULL), + CLK_DUMMY("usb_fs_clk", USB_FS2_XCVR_CLK, NULL), + CLK_DUMMY("usb_fs_sys_clk", USB_FS2_SYS_CLK, NULL), + CLK_DUMMY("ce_clk", CE2_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI1_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI2_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI3_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI4_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI5_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI6_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI7_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI8_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI9_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI10_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI11_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI12_P_CLK, NULL), + CLK_DUMMY("gsbi_pclk", GSBI12_P_CLK, NULL), + CLK_DUMMY("ppss_pclk", PPSS_P_CLK, NULL), + CLK_DUMMY("tsif_pclk", TSIF_P_CLK, NULL), + CLK_DUMMY("usb_fs_pclk", USB_FS1_P_CLK, NULL), + CLK_DUMMY("usb_fs_pclk", USB_FS2_P_CLK, NULL), + CLK_DUMMY("usb_hs_pclk", USB_HS1_P_CLK, NULL), + CLK_DUMMY("sdc_pclk", SDC1_P_CLK, NULL), + CLK_DUMMY("sdc_pclk", SDC2_P_CLK, NULL), + CLK_DUMMY("sdc_pclk", SDC3_P_CLK, NULL), + CLK_DUMMY("sdc_pclk", SDC4_P_CLK, NULL), + CLK_DUMMY("sdc_pclk", SDC5_P_CLK, NULL), + CLK_DUMMY("adm_clk", ADM0_CLK, NULL), + CLK_DUMMY("adm_pclk", ADM0_P_CLK, NULL), + CLK_DUMMY("pmic_arb_pclk", PMIC_ARB0_P_CLK, NULL), + CLK_DUMMY("pmic_arb_pclk", PMIC_ARB1_P_CLK, NULL), + CLK_DUMMY("pmic_ssbi2", PMIC_SSBI2_CLK, NULL), + CLK_DUMMY("rpm_msg_ram_pclk", RPM_MSG_RAM_P_CLK, NULL), + CLK_DUMMY("amp_clk", AMP_CLK, NULL), + CLK_DUMMY("cam_clk", CAM0_CLK, NULL), + CLK_DUMMY("cam_clk", CAM1_CLK, NULL), + CLK_DUMMY("csi_src_clk", CSI0_SRC_CLK, NULL), + CLK_DUMMY("csi_src_clk", CSI1_SRC_CLK, NULL), + CLK_DUMMY("csi_clk", CSI0_CLK, NULL), + CLK_DUMMY("csi_clk", CSI1_CLK, NULL), + CLK_DUMMY("csi_pix_clk", CSI_PIX_CLK, NULL), + CLK_DUMMY("csi_rdi_clk", CSI_RDI_CLK, NULL), + CLK_DUMMY("csiphy_timer_src_clk", CSIPHY_TIMER_SRC_CLK, NULL), + CLK_DUMMY("csi0phy_timer_clk", CSIPHY0_TIMER_CLK, NULL), + CLK_DUMMY("csi1phy_timer_clk", CSIPHY1_TIMER_CLK, NULL), + CLK_DUMMY("dsi_byte_div_clk", DSI1_BYTE_CLK, NULL), + CLK_DUMMY("dsi_byte_div_clk", DSI2_BYTE_CLK, NULL), + CLK_DUMMY("dsi_esc_clk", DSI1_ESC_CLK, NULL), + CLK_DUMMY("dsi_esc_clk", DSI2_ESC_CLK, NULL), + CLK_DUMMY("gfx2d0_clk", GFX2D0_CLK, NULL), + CLK_DUMMY("gfx2d1_clk", GFX2D1_CLK, NULL), + CLK_DUMMY("gfx3d_clk", GFX3D_CLK, NULL), + CLK_DUMMY("ijpeg_axi_clk", IJPEG_AXI_CLK, NULL), + CLK_DUMMY("imem_axi_clk", IMEM_AXI_CLK, NULL), + CLK_DUMMY("jpegd_clk", JPEGD_CLK, NULL), + CLK_DUMMY("mdp_clk", MDP_CLK, NULL), + CLK_DUMMY("mdp_vsync_clk", MDP_VSYNC_CLK, NULL), + CLK_DUMMY("lut_mdp", LUT_MDP_CLK, NULL), + CLK_DUMMY("rot_clk", ROT_CLK, NULL), + CLK_DUMMY("tv_src_clk", TV_SRC_CLK, NULL), + CLK_DUMMY("tv_enc_clk", TV_ENC_CLK, NULL), + CLK_DUMMY("tv_dac_clk", TV_DAC_CLK, NULL), + CLK_DUMMY("vcodec_clk", VCODEC_CLK, NULL), + CLK_DUMMY("mdp_tv_clk", MDP_TV_CLK, NULL), + CLK_DUMMY("hdmi_clk", HDMI_TV_CLK, NULL), + CLK_DUMMY("hdmi_app_clk", HDMI_APP_CLK, NULL), + CLK_DUMMY("vpe_clk", VPE_CLK, NULL), + CLK_DUMMY("vfe_clk", VFE_CLK, NULL), + CLK_DUMMY("csi_vfe_clk", CSI0_VFE_CLK, NULL), + CLK_DUMMY("vfe_axi_clk", VFE_AXI_CLK, NULL), + CLK_DUMMY("ijpeg_axi_clk", IJPEG_AXI_CLK, NULL), + CLK_DUMMY("mdp_axi_clk", MDP_AXI_CLK, NULL), + CLK_DUMMY("rot_axi_clk", ROT_AXI_CLK, NULL), + CLK_DUMMY("vcodec_axi_clk", VCODEC_AXI_CLK, NULL), + CLK_DUMMY("vcodec_axi_a_clk", VCODEC_AXI_A_CLK, NULL), + CLK_DUMMY("vcodec_axi_b_clk", VCODEC_AXI_B_CLK, NULL), + CLK_DUMMY("vpe_axi_clk", VPE_AXI_CLK, NULL), + CLK_DUMMY("amp_pclk", AMP_P_CLK, NULL), + CLK_DUMMY("csi_pclk", CSI0_P_CLK, NULL), + CLK_DUMMY("dsi_m_pclk", DSI1_M_P_CLK, NULL), + CLK_DUMMY("dsi_s_pclk", DSI1_S_P_CLK, NULL), + CLK_DUMMY("dsi_m_pclk", DSI2_M_P_CLK, NULL), + CLK_DUMMY("dsi_s_pclk", DSI2_S_P_CLK, NULL), + CLK_DUMMY("gfx2d0_pclk", GFX2D0_P_CLK, NULL), + CLK_DUMMY("gfx2d1_pclk", GFX2D1_P_CLK, NULL), + CLK_DUMMY("gfx3d_pclk", GFX3D_P_CLK, NULL), + CLK_DUMMY("hdmi_m_pclk", HDMI_M_P_CLK, NULL), + CLK_DUMMY("hdmi_s_pclk", HDMI_S_P_CLK, NULL), + CLK_DUMMY("ijpeg_pclk", IJPEG_P_CLK, NULL), + CLK_DUMMY("jpegd_pclk", JPEGD_P_CLK, NULL), + CLK_DUMMY("imem_pclk", IMEM_P_CLK, NULL), + CLK_DUMMY("mdp_pclk", MDP_P_CLK, NULL), + CLK_DUMMY("smmu_pclk", SMMU_P_CLK, NULL), + CLK_DUMMY("rotator_pclk", ROT_P_CLK, NULL), + CLK_DUMMY("tv_enc_pclk", TV_ENC_P_CLK, NULL), + CLK_DUMMY("vcodec_pclk", VCODEC_P_CLK, NULL), + CLK_DUMMY("vfe_pclk", VFE_P_CLK, NULL), + CLK_DUMMY("vpe_pclk", VPE_P_CLK, NULL), + CLK_DUMMY("mi2s_osr_clk", MI2S_OSR_CLK, NULL), + CLK_DUMMY("mi2s_bit_clk", MI2S_BIT_CLK, NULL), + CLK_DUMMY("i2s_mic_osr_clk", CODEC_I2S_MIC_OSR_CLK, NULL), + CLK_DUMMY("i2s_mic_bit_clk", CODEC_I2S_MIC_BIT_CLK, NULL), + CLK_DUMMY("i2s_mic_osr_clk", SPARE_I2S_MIC_OSR_CLK, NULL), + CLK_DUMMY("i2s_mic_bit_clk", SPARE_I2S_MIC_BIT_CLK, NULL), + CLK_DUMMY("i2s_spkr_osr_clk", CODEC_I2S_SPKR_OSR_CLK, NULL), + CLK_DUMMY("i2s_spkr_bit_clk", CODEC_I2S_SPKR_BIT_CLK, NULL), + CLK_DUMMY("i2s_spkr_osr_clk", SPARE_I2S_SPKR_OSR_CLK, NULL), + CLK_DUMMY("i2s_spkr_bit_clk", SPARE_I2S_SPKR_BIT_CLK, NULL), + CLK_DUMMY("pcm_clk", PCM_CLK, NULL), + CLK_DUMMY("iommu_clk", JPEGD_AXI_CLK, NULL), + CLK_DUMMY("iommu_clk", VFE_AXI_CLK, NULL), + CLK_DUMMY("iommu_clk", VCODEC_AXI_CLK, NULL), + CLK_DUMMY("iommu_clk", GFX3D_CLK, NULL), + CLK_DUMMY("iommu_clk", GFX2D0_CLK, NULL), + CLK_DUMMY("iommu_clk", GFX2D1_CLK, NULL), +}; + +unsigned msm_num_clocks_8960 = ARRAY_SIZE(msm_clocks_8960); diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c new file mode 100644 index 000000000000..33c236ce7cf2 --- /dev/null +++ b/arch/arm/mach-msm/devices-msm8x60.c @@ -0,0 +1,56 @@ +/* Copyright (c) 2010-2011, Code Aurora Forum. 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 and + * only version 2 as published by the Free Software Foundation. + * + * 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/platform_device.h> + +#include <mach/board.h> +#include <mach/msm_iomap.h> +#include <mach/dma.h> + +static struct resource resources_dmov_adm0[] = { + { + .start = MSM8X60_DMOV_ADM0_PHYS, + .end = MSM8X60_DMOV_ADM0_PHYS + MSM8X60_DMOV_ADM0_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_ADM0_AARM, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource resources_dmov_adm1[] = { + { + .start = MSM8X60_DMOV_ADM1_PHYS, + .end = MSM8X60_DMOV_ADM1_PHYS + MSM8X60_DMOV_ADM1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_ADM1_AARM, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm_device_dmov_adm0 = { + .name = "msm_dmov", + .id = 0, + .num_resources = ARRAY_SIZE(resources_dmov_adm0), + .resource = resources_dmov_adm0, +}; + +struct platform_device msm_device_dmov_adm1 = { + .name = "msm_dmov", + .id = 1, + .num_resources = ARRAY_SIZE(resources_dmov_adm1), + .resource = resources_dmov_adm1, +}; diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c index 12d8deb78d9c..730982fe5902 100644 --- a/arch/arm/mach-msm/devices-qsd8x50.c +++ b/arch/arm/mach-msm/devices-qsd8x50.c @@ -315,8 +315,27 @@ int __init msm_add_sdcc(unsigned int controller, return platform_device_register(pdev); } +static struct resource resources_dmov[] = { + { + .start = QSD8X50_DMOV_PHYS, + .end = QSD8X50_DMOV_PHYS + QSD8X50_DMOV_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_ADM_AARM, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm_device_dmov = { + .name = "msm_dmov", + .id = -1, + .num_resources = ARRAY_SIZE(resources_dmov), + .resource = resources_dmov, +}; + struct clk_lookup msm_clocks_8x50[] = { - CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), + CLK_PCOM("adm_clk", ADM_CLK, "msm_dmov", 0), CLK_PCOM("ce_clk", CE_CLK, NULL, 0), CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN), CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0), diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index 9545c196c6e8..e38fc8610f39 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h @@ -40,6 +40,11 @@ extern struct platform_device msm_device_i2c; extern struct platform_device msm_device_smd; +extern struct platform_device msm_device_dmov; +extern struct platform_device msm8960_device_dmov; +extern struct platform_device msm_device_dmov_adm0; +extern struct platform_device msm_device_dmov_adm1; + extern struct platform_device msm_device_nand; extern struct platform_device msm_device_mddi0; @@ -55,4 +60,7 @@ extern unsigned msm_num_clocks_7x30; extern struct clk_lookup msm_clocks_8x50[]; extern unsigned msm_num_clocks_8x50; +extern struct clk_lookup msm_clocks_8960[]; +extern unsigned msm_num_clocks_8960; + #endif diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index 02cae5e2951c..16b40344d98c 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -1,6 +1,7 @@ /* linux/arch/arm/mach-msm/dma.c * * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -18,9 +19,15 @@ #include <linux/io.h> #include <linux/interrupt.h> #include <linux/completion.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> #include <mach/dma.h> #define MSM_DMOV_CHANNEL_COUNT 16 +#define MSM_DMOV_MAX_ADMS 2 + +#define MODULE_NAME "msm_dmov" enum { MSM_DMOV_PRINT_ERRORS = 1, @@ -28,13 +35,55 @@ enum { MSM_DMOV_PRINT_FLOW = 4 }; -static DEFINE_SPINLOCK(msm_dmov_lock); -static struct clk *msm_dmov_clk; -static unsigned int channel_active; -static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; -static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS; +struct msm_dmov_conf { + void __iomem *base; + int channel_active; + struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; + struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; + spinlock_t lock; + unsigned irq; + struct clk *clk; + struct clk *pclk; +}; + +static struct msm_dmov_conf dmov_conf[MSM_DMOV_MAX_ADMS]; +static int nr_adms; + +#if defined(CONFIG_ARCH_MSM7X30) +#define DMOV_SD_AARM DMOV_SD2 +#define DMOV_SD_SIZE 0x400 +#elif defined(CONFIG_ARCH_MSM8X60) +#define DMOV_SD_AARM DMOV_SD1 +#define DMOV_SD_SIZE 0x800 +#elif defined(CONFIG_ARCH_MSM8960) +#define DMOV_SD_AARM DMOV_SD0 +#define DMOV_SD_SIZE 0x800 +#else +#define DMOV_SD_AARM DMOV_SD3 +#define DMOV_SD_SIZE 0x400 +#endif + +#define DMOV_ADDR(sd, off, ch) (((sd) * DMOV_SD_SIZE) + (off) + ((ch) << 2)) + +#define DMOV_SD0(off, ch) DMOV_ADDR(0, off, ch) +#define DMOV_SD1(off, ch) DMOV_ADDR(1, off, ch) +#define DMOV_SD2(off, ch) DMOV_ADDR(2, off, ch) +#define DMOV_SD3(off, ch) DMOV_ADDR(3, off, ch) + +#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch) +#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch) +#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch) +#define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch) +#define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch) +#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch) +#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch) +#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch) +#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch) +#define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch) +#define DMOV_ISR DMOV_SD_AARM(0x380, 0) + #define MSM_DMOV_DPRINTF(mask, format, args...) \ do { \ if ((mask) & msm_dmov_print_mask) \ @@ -47,48 +96,121 @@ unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS; #define PRINT_FLOW(format, args...) \ MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args); -void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) +static inline unsigned dmov_readl(unsigned addr, int adm) +{ + return readl(dmov_conf[adm].base + addr); +} + +static inline void dmov_writel(unsigned val, unsigned addr, int adm) +{ + writel(val, dmov_conf[adm].base + addr); +} + +#define DMOV_ID_TO_ADM(id) ((id) / MSM_DMOV_CHANNEL_COUNT) +#define DMOV_ID_TO_CHAN(id) ((id) % MSM_DMOV_CHANNEL_COUNT) +#define DMOV_CHAN_ADM_TO_ID(ch, adm) ((ch) + (adm) * MSM_DMOV_CHANNEL_COUNT) + +int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) +{ + int adm = DMOV_ID_TO_ADM(id); + int ch = DMOV_ID_TO_CHAN(id); + + if (!dmov_conf[adm].base) + return -ENODEV; + + dmov_writel((graceful << 31), DMOV_FLUSH0(ch), adm); + + return 0; +} +EXPORT_SYMBOL(msm_dmov_stop_cmd); + +static int msm_dmov_clocks_on(int adm) +{ + int ret = 0; + + if (!IS_ERR(dmov_conf[adm].clk)) { + ret = clk_enable(dmov_conf[adm].clk); + if (ret) + return ret; + if (!IS_ERR(dmov_conf[adm].pclk)) { + ret = clk_enable(dmov_conf[adm].pclk); + if (ret) + clk_disable(dmov_conf[adm].clk); + } + } + return ret; +} + +static void msm_dmov_clocks_off(int adm) { - writel((graceful << 31), DMOV_FLUSH0(id)); + if (!IS_ERR(dmov_conf[adm].clk)) + clk_disable(dmov_conf[adm].clk); + if (!IS_ERR(dmov_conf[adm].pclk)) + clk_disable(dmov_conf[adm].pclk); } -void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) +int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { unsigned long irq_flags; unsigned int status; + int adm = DMOV_ID_TO_ADM(id); + int ch = DMOV_ID_TO_CHAN(id); + + if (!dmov_conf[adm].base) + return -ENODEV; - spin_lock_irqsave(&msm_dmov_lock, irq_flags); - if (!channel_active) - clk_enable(msm_dmov_clk); + spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags); + if (!dmov_conf[adm].channel_active) + msm_dmov_clocks_on(adm); dsb(); - status = readl(DMOV_STATUS(id)); - if (list_empty(&ready_commands[id]) && + status = dmov_readl(DMOV_STATUS(ch), adm); + if (list_empty(&dmov_conf[adm].ready_commands[ch]) && (status & DMOV_STATUS_CMD_PTR_RDY)) { -#if 0 - if (list_empty(&active_commands[id])) { - PRINT_FLOW("msm_dmov_enqueue_cmd(%d), enable interrupt\n", id); - writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id)); - } -#endif if (cmd->execute_func) cmd->execute_func(cmd); - PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status); - list_add_tail(&cmd->list, &active_commands[id]); - if (!channel_active) - enable_irq(INT_ADM_AARM); - channel_active |= 1U << id; - writel(cmd->cmdptr, DMOV_CMD_PTR(id)); + PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", + id, status); + list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]); + if (!dmov_conf[adm].channel_active) + enable_irq(dmov_conf[adm].irq); + dmov_conf[adm].channel_active |= 1U << ch; + dmov_writel(cmd->cmdptr, DMOV_CMD_PTR(ch), adm); } else { - if (!channel_active) - clk_disable(msm_dmov_clk); - if (list_empty(&active_commands[id])) - PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status); + if (!dmov_conf[adm].channel_active) + msm_dmov_clocks_off(adm); + if (list_empty(&dmov_conf[adm].active_commands[ch])) + PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover " + "stalled, status %x\n", id, status); + PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status " + "%x\n", id, status); + list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]); + } + spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags); - PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status %x\n", id, status); - list_add_tail(&cmd->list, &ready_commands[id]); + return 0; +} +EXPORT_SYMBOL(msm_dmov_enqueue_cmd); + +int msm_dmov_flush(unsigned int id) +{ + unsigned long flags; + int ch = DMOV_ID_TO_CHAN(id); + int adm = DMOV_ID_TO_ADM(id); + + if (!dmov_conf[adm].base) + return -ENODEV; + + spin_lock_irqsave(&dmov_conf[adm].lock, flags); + /* XXX not checking if flush cmd sent already */ + if (!list_empty(&dmov_conf[adm].active_commands[ch])) { + PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id); + dmov_writel(DMOV_FLUSH_GRACEFUL, DMOV_FLUSH0(ch), adm); } - spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); + spin_unlock_irqrestore(&dmov_conf[adm].lock, flags); + + return 0; } +EXPORT_SYMBOL(msm_dmov_flush); struct msm_dmov_exec_cmdptr_cmd { struct msm_dmov_cmd dmov_cmd; @@ -114,6 +236,10 @@ dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd, int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { struct msm_dmov_exec_cmdptr_cmd cmd; + int adm = DMOV_ID_TO_ADM(id); + + if (!dmov_conf[adm].base) + return -ENODEV; PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr); @@ -135,41 +261,68 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr); return 0; } +EXPORT_SYMBOL(msm_dmov_exec_cmd); +static void msm_dmov_fill_errdata(struct msm_dmov_errdata *errdata, int ch, + int adm) +{ + errdata->flush[0] = dmov_readl(DMOV_FLUSH0(ch), adm); + errdata->flush[1] = dmov_readl(DMOV_FLUSH1(ch), adm); + errdata->flush[2] = dmov_readl(DMOV_FLUSH2(ch), adm); + errdata->flush[3] = dmov_readl(DMOV_FLUSH3(ch), adm); + errdata->flush[4] = dmov_readl(DMOV_FLUSH4(ch), adm); + errdata->flush[5] = dmov_readl(DMOV_FLUSH5(ch), adm); +} + +static int msm_dmov_irq_to_adm(unsigned irq) +{ + int i; + for (i = 0; i < nr_adms; i++) + if (dmov_conf[i].irq == irq) + return i; + PRINT_ERROR("msm_dmov_irq_to_adm: can't match ADM to IRQ %d\n", irq); + return -EINVAL; +} static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) { unsigned int int_status, mask, id; unsigned long irq_flags; + unsigned int ch; unsigned int ch_status; unsigned int ch_result; struct msm_dmov_cmd *cmd; + int adm = msm_dmov_irq_to_adm(irq); - spin_lock_irqsave(&msm_dmov_lock, irq_flags); + spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags); - int_status = readl(DMOV_ISR); /* read and clear interrupt */ + int_status = dmov_readl(DMOV_ISR, adm); /* read and clear interrupt */ PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status); while (int_status) { mask = int_status & -int_status; - id = fls(mask) - 1; + ch = fls(mask) - 1; + id = DMOV_CHAN_ADM_TO_ID(ch, adm); PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id); int_status &= ~mask; - ch_status = readl(DMOV_STATUS(id)); + ch_status = dmov_readl(DMOV_STATUS(ch), adm); if (!(ch_status & DMOV_STATUS_RSLT_VALID)) { PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status); continue; } do { - ch_result = readl(DMOV_RSLT(id)); - if (list_empty(&active_commands[id])) { + ch_result = dmov_readl(DMOV_RSLT(ch), adm); + if (list_empty(&dmov_conf[adm].active_commands[ch])) { PRINT_ERROR("msm_datamover_irq_handler id %d, got result " "with no active command, status %x, result %x\n", id, ch_status, ch_result); cmd = NULL; } else - cmd = list_entry(active_commands[id].next, typeof(*cmd), list); - PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result); + cmd = list_entry(dmov_conf[adm]. + active_commands[ch].next, typeof(*cmd), + list); + PRINT_FLOW("msm_datamover_irq_handler id %d, status %x," + " result %x\n", id, ch_status, ch_result); if (ch_result & DMOV_RSLT_DONE) { PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); @@ -184,12 +337,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) if (ch_result & DMOV_RSLT_FLUSH) { struct msm_dmov_errdata errdata; - errdata.flush[0] = readl(DMOV_FLUSH0(id)); - errdata.flush[1] = readl(DMOV_FLUSH1(id)); - errdata.flush[2] = readl(DMOV_FLUSH2(id)); - errdata.flush[3] = readl(DMOV_FLUSH3(id)); - errdata.flush[4] = readl(DMOV_FLUSH4(id)); - errdata.flush[5] = readl(DMOV_FLUSH5(id)); + msm_dmov_fill_errdata(&errdata, ch, adm); PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); if (cmd) { @@ -201,13 +349,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) if (ch_result & DMOV_RSLT_ERROR) { struct msm_dmov_errdata errdata; - errdata.flush[0] = readl(DMOV_FLUSH0(id)); - errdata.flush[1] = readl(DMOV_FLUSH1(id)); - errdata.flush[2] = readl(DMOV_FLUSH2(id)); - errdata.flush[3] = readl(DMOV_FLUSH3(id)); - errdata.flush[4] = readl(DMOV_FLUSH4(id)); - errdata.flush[5] = readl(DMOV_FLUSH5(id)); - + msm_dmov_fill_errdata(&errdata, ch, adm); PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); if (cmd) { @@ -217,55 +359,148 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) } /* this does not seem to work, once we get an error */ /* the datamover will no longer accept commands */ - writel(0, DMOV_FLUSH0(id)); + dmov_writel(0, DMOV_FLUSH0(ch), adm); } - ch_status = readl(DMOV_STATUS(id)); + ch_status = dmov_readl(DMOV_STATUS(ch), adm); PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); - if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && !list_empty(&ready_commands[id])) { - cmd = list_entry(ready_commands[id].next, typeof(*cmd), list); + if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && + !list_empty(&dmov_conf[adm].ready_commands[ch])) { + cmd = list_entry(dmov_conf[adm]. + ready_commands[ch].next, typeof(*cmd), + list); list_del(&cmd->list); - list_add_tail(&cmd->list, &active_commands[id]); + list_add_tail(&cmd->list, &dmov_conf[adm]. + active_commands[ch]); if (cmd->execute_func) cmd->execute_func(cmd); PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id); - writel(cmd->cmdptr, DMOV_CMD_PTR(id)); + dmov_writel(cmd->cmdptr, DMOV_CMD_PTR(ch), adm); } } while (ch_status & DMOV_STATUS_RSLT_VALID); - if (list_empty(&active_commands[id]) && list_empty(&ready_commands[id])) - channel_active &= ~(1U << id); + if (list_empty(&dmov_conf[adm].active_commands[ch]) && + list_empty(&dmov_conf[adm].ready_commands[ch])) + dmov_conf[adm].channel_active &= ~(1U << ch); PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); } - if (!channel_active) { - disable_irq_nosync(INT_ADM_AARM); - clk_disable(msm_dmov_clk); + if (!dmov_conf[adm].channel_active) { + disable_irq_nosync(dmov_conf[adm].irq); + msm_dmov_clocks_off(adm); } - spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); + spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags); return IRQ_HANDLED; } -static int __init msm_init_datamover(void) +static void __init msm_dmov_deinit_clocks(int adm) +{ + if (!IS_ERR(dmov_conf[adm].clk)) + clk_put(dmov_conf[adm].clk); + if (!IS_ERR(dmov_conf[adm].pclk)) + clk_put(dmov_conf[adm].pclk); +} + +#define PDEV_TO_ADM(pdev) \ +({ \ + typeof(pdev) _pdev = pdev; \ + (_pdev->id == -1) ? 0 : _pdev->id; \ +}) + +static int __devinit msm_dmov_init_clocks(struct platform_device *pdev) +{ + int ret = 0; + int adm = PDEV_TO_ADM(pdev); + + dmov_conf[adm].clk = clk_get(&pdev->dev, "adm_clk"); + if (IS_ERR(dmov_conf[adm].clk)) { + PRINT_ERROR("%s: Error getting adm_clk\n", __func__); + ret = PTR_ERR(dmov_conf[adm].clk); + } + + dmov_conf[adm].pclk = clk_get(&pdev->dev, "adm_pclk"); + /* pclk not present on all SoCs, don't return error on failure */ + + return ret; +} + +static int __devinit msm_dmov_conf_init(struct platform_device *pdev) { int i; - int ret; - struct clk *clk; + int adm = PDEV_TO_ADM(pdev); + struct resource *irqres = + platform_get_resource(pdev, IORESOURCE_IRQ, 0); + struct resource *memres = + platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!irqres || !memres || !irqres->start) + return -EINVAL; + + dmov_conf[adm].irq = irqres->start; + + dmov_conf[adm].base = + ioremap_nocache(memres->start, resource_size(memres)); + if (!dmov_conf[adm].base) + return -ENOMEM; + + dmov_conf[adm].lock = __SPIN_LOCK_UNLOCKED(dmov_lock); for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) { - INIT_LIST_HEAD(&ready_commands[i]); - INIT_LIST_HEAD(&active_commands[i]); - writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i)); + INIT_LIST_HEAD(&dmov_conf[adm].ready_commands[i]); + INIT_LIST_HEAD(&dmov_conf[adm].active_commands[i]); } - clk = clk_get(NULL, "adm_clk"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - msm_dmov_clk = clk; - ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL); + return 0; +} + +static inline void __devinit msm_dmov_conf_free(int adm) +{ + iounmap(dmov_conf[adm].base); + dmov_conf[adm].base = NULL; +} + +static int __devinit msm_dmov_probe(struct platform_device *pdev) +{ + int i; + int ret; + int adm = PDEV_TO_ADM(pdev); + + ret = msm_dmov_conf_init(pdev); if (ret) return ret; - disable_irq(INT_ADM_AARM); + + for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) + dmov_writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT + | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i), adm); + + ret = msm_dmov_init_clocks(pdev); + if (ret) + goto out_conf; + + ret = request_irq(dmov_conf[adm].irq, msm_datamover_irq_handler, 0, + "msmdatamover", NULL); + if (ret) + goto out_clock; + disable_irq(dmov_conf[adm].irq); + nr_adms++; + return 0; + +out_clock: + msm_dmov_deinit_clocks(adm); +out_conf: + msm_dmov_conf_free(adm); + return ret; } -arch_initcall(msm_init_datamover); +static struct platform_driver msm_dmov_driver = { + .probe = msm_dmov_probe, + .driver = { + .name = MODULE_NAME, + .owner = THIS_MODULE, + }, +}; +static int __init msm_init_datamover(void) +{ + return platform_driver_register(&msm_dmov_driver); +} + +arch_initcall(msm_init_datamover); diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h index 05583f569524..3d677731eda3 100644 --- a/arch/arm/mach-msm/include/mach/dma.h +++ b/arch/arm/mach-msm/include/mach/dma.h @@ -1,6 +1,7 @@ /* linux/include/asm-arm/arch-msm/dma.h * * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -14,6 +15,7 @@ */ #ifndef __ASM_ARCH_MSM_DMA_H +#define __ASM_ARCH_MSM_DMA_H #include <linux/list.h> #include <mach/msm_iomap.h> @@ -32,67 +34,75 @@ struct msm_dmov_cmd { void *data; }; -#ifndef CONFIG_ARCH_MSM8X60 -void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd); -void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful); +int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd); +int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful); int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr); -#else -static inline -void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { } -static inline -void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { } -static inline -int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; } -#endif - - -#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2)) -#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2)) -#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2)) -#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2)) - -#if defined(CONFIG_ARCH_MSM7X30) -#define DMOV_SD_AARM DMOV_SD2 -#else -#define DMOV_SD_AARM DMOV_SD3 -#endif +int msm_dmov_flush(unsigned int id); -#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch) #define DMOV_CMD_LIST (0 << 29) /* does not work */ #define DMOV_CMD_PTR_LIST (1 << 29) /* works */ #define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */ #define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */ #define DMOV_CMD_ADDR(addr) ((addr) >> 3) -#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch) #define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */ #define DMOV_RSLT_ERROR (1 << 3) #define DMOV_RSLT_FLUSH (1 << 2) #define DMOV_RSLT_DONE (1 << 1) /* top pointer done */ #define DMOV_RSLT_USER (1 << 0) /* command with FR force result */ -#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch) -#define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch) -#define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch) -#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch) -#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch) -#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch) +#define DMOV_FLUSH_GRACEFUL (1 << 31) -#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch) #define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29)) #define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3) #define DMOV_STATUS_RSLT_VALID (1 << 1) #define DMOV_STATUS_CMD_PTR_RDY (1 << 0) -#define DMOV_ISR DMOV_SD_AARM(0x380, 0) - -#define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch) #define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2) #define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1) #define DMOV_CONFIG_IRQ_EN (1 << 0) -/* channel assignments */ +#define DMOV_8X60_GP_CHAN 16 + +#define DMOV_8X60_CE_IN_CHAN 2 +#define DMOV_8X60_CE_IN_CRCI 4 + +#define DMOV_8X60_CE_OUT_CHAN 3 +#define DMOV_8X60_CE_OUT_CRCI 5 + +#define DMOV_8X60_CE_HASH_CRCI 15 + +#define DMOV_8X60_SDC1_CHAN 18 +#define DMOV_8X60_SDC1_CRCI 1 + +#define DMOV_8X60_SDC2_CHAN 19 +#define DMOV_8X60_SDC2_CRCI 4 + +#define DMOV_8X60_SDC3_CHAN 20 +#define DMOV_8X60_SDC3_CRCI 2 + +#define DMOV_8X60_SDC4_CHAN 21 +#define DMOV_8X60_SDC4_CRCI 5 + +#define DMOV_8X60_SDC5_CHAN 21 +#define DMOV_8X60_SDC5_CRCI 14 + +#define DMOV_8X60_TSIF_CHAN 4 +#define DMOV_8X60_TSIF_CRCI 6 + +#define DMOV_8X60_HSUART1_TX_CHAN 22 +#define DMOV_8X60_HSUART1_TX_CRCI 8 + +#define DMOV_8X60_HSUART1_RX_CHAN 23 +#define DMOV_8X60_HSUART1_RX_CRCI 9 + +#define DMOV_8X60_HSUART2_TX_CHAN 8 +#define DMOV_8X60_HSUART2_TX_CRCI 13 + +#define DMOV_8X60_HSUART2_RX_CHAN 8 +#define DMOV_8X60_HSUART2_RX_CRCI 14 +/* channel assignments before 8x60 */ #define DMOV_NAND_CHAN 7 #define DMOV_NAND_CRCI_CMD 5 #define DMOV_NAND_CRCI_DATA 4 diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h index 8f99d97615a0..d6540e1192eb 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h @@ -51,9 +51,8 @@ #define MSM7X00_CSR_PHYS 0xC0100000 #define MSM7X00_CSR_SIZE SZ_4K -#define MSM_DMOV_BASE IOMEM(0xE0002000) -#define MSM_DMOV_PHYS 0xA9700000 -#define MSM_DMOV_SIZE SZ_4K +#define MSM7X00_DMOV_PHYS 0xA9700000 +#define MSM7X00_DMOV_SIZE SZ_4K #define MSM_GPIO1_BASE IOMEM(0xE0003000) #define MSM_GPIO1_PHYS 0xA9200000 diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h index 4d84be15955e..23912e541cdb 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h @@ -42,9 +42,8 @@ #define MSM7X30_CSR_PHYS 0xC0100000 #define MSM7X30_CSR_SIZE SZ_4K -#define MSM_DMOV_BASE IOMEM(0xE0002000) -#define MSM_DMOV_PHYS 0xAC400000 -#define MSM_DMOV_SIZE SZ_4K +#define MSM7X30_DMOV_PHYS 0xAC400000 +#define MSM7X30_DMOV_SIZE SZ_4K #define MSM_GPIO1_BASE IOMEM(0xE0003000) #define MSM_GPIO1_PHYS 0xAC001000 diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h index 3c9d9602a318..b251ba63b3e2 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h @@ -45,4 +45,7 @@ #define MSM8960_TMR0_PHYS 0x0208A000 #define MSM8960_TMR0_SIZE SZ_4K +#define MSM8960_DMOV_PHYS 0x18300000 +#define MSM8960_DMOV_SIZE SZ_1M + #endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h index d4143201999f..fc36b82d41b3 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h @@ -42,9 +42,8 @@ #define QSD8X50_CSR_PHYS 0xAC100000 #define QSD8X50_CSR_SIZE SZ_4K -#define MSM_DMOV_BASE IOMEM(0xE0002000) -#define MSM_DMOV_PHYS 0xA9700000 -#define MSM_DMOV_SIZE SZ_4K +#define QSD8X50_DMOV_PHYS 0xA9700000 +#define QSD8X50_DMOV_SIZE SZ_4K #define MSM_GPIO1_BASE IOMEM(0xE0003000) #define MSM_GPIO1_PHYS 0xA9000000 diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h index 3b19b8f244b8..87a26c6ed98f 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h @@ -56,6 +56,12 @@ #define MSM_SHARED_RAM_BASE IOMEM(0xF0100000) #define MSM_SHARED_RAM_SIZE SZ_1M +#define MSM8X60_DMOV_ADM0_PHYS 0x18320000 +#define MSM8X60_DMOV_ADM0_SIZE SZ_1M + +#define MSM8X60_DMOV_ADM1_PHYS 0x18420000 +#define MSM8X60_DMOV_ADM1_SIZE SZ_1M + #define MSM8X60_TMR_PHYS 0x02000000 #define MSM8X60_TMR_SIZE SZ_4K diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index cec6ed1c91d3..1c86cda45d3b 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -42,7 +42,6 @@ static struct map_desc msm_io_desc[] __initdata = { MSM_DEVICE(VIC), MSM_CHIP_DEVICE(CSR, MSM7X00), - MSM_DEVICE(DMOV), MSM_DEVICE(GPIO1), MSM_DEVICE(GPIO2), MSM_DEVICE(CLK_CTL), @@ -75,7 +74,6 @@ void __init msm_map_common_io(void) static struct map_desc qsd8x50_io_desc[] __initdata = { MSM_DEVICE(VIC), MSM_CHIP_DEVICE(CSR, QSD8X50), - MSM_DEVICE(DMOV), MSM_DEVICE(GPIO1), MSM_DEVICE(GPIO2), MSM_DEVICE(CLK_CTL), @@ -134,7 +132,6 @@ void __init msm_map_msm8960_io(void) static struct map_desc msm7x30_io_desc[] __initdata = { MSM_DEVICE(VIC), MSM_CHIP_DEVICE(CSR, MSM7X30), - MSM_DEVICE(DMOV), MSM_DEVICE(GPIO1), MSM_DEVICE(GPIO2), MSM_DEVICE(CLK_CTL), |