diff options
author | Xinyu Chen <xinyu.chen@freescale.com> | 2012-05-02 11:02:43 +0800 |
---|---|---|
committer | Xinyu Chen <xinyu.chen@freescale.com> | 2012-05-02 11:02:43 +0800 |
commit | 3b9257f71a2a0dc0e0061ce2d455c504515c26d9 (patch) | |
tree | 6d19fa9ec5cf7973d4b599fce2a8e2861bd0dce9 /arch/arm | |
parent | 5f5288b61bc0596dbe1436a65f0bdf52b8d855cb (diff) | |
parent | 1b64ead9cdb4eae25789cfc5bbb7d8ad07dee402 (diff) |
Merge remote branch 'fsl-linux-sdk/imx_3.0.15_12.04.01' into imx_3.0.15_android
Conflicts:
sound/soc/imx/Makefile
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/dma-mapping.h | 13 | ||||
-rw-r--r-- | arch/arm/include/asm/pgtable.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_sabreauto.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_sabreauto.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx6/bus_freq.c | 53 | ||||
-rw-r--r-- | arch/arm/mach-mx6/clock.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-mx6/mx6_ddr_freq.S | 79 | ||||
-rw-r--r-- | arch/arm/mach-mx6/mx6_mmdc.c | 84 | ||||
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 12 | ||||
-rw-r--r-- | arch/arm/plat-mxc/ahci_sata.c | 13 | ||||
-rwxr-xr-x | arch/arm/plat-mxc/clock.c | 14 | ||||
-rwxr-xr-x | arch/arm/plat-mxc/include/mach/clock.h | 3 |
12 files changed, 222 insertions, 69 deletions
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 4fff837363ed..d9b4badee6b2 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -186,6 +186,19 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size, extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); /** + * dma_alloc_writethrough - allocate consistent memory for DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: required memory size + * @handle: bus-specific DMA address + * + * Allocate some writethrough cached, for a device for + * performing DMA. This function allocates pages, and will + * return the CPU-viewed address, and sets @handle to be the + * device-viewed address. + */ +extern void *dma_alloc_writethrough(struct device *, size_t, dma_addr_t *, gfp_t); + +/** * dma_free_coherent - free memory allocated by dma_alloc_coherent * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices * @size: size of memory originally requested in dma_alloc_coherent diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 5750704e0271..6682ab931451 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -232,6 +232,9 @@ extern pgprot_t pgprot_kernel; #define pgprot_writecombine(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) +#define pgprot_writethrough(prot) \ + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_WRITETHROUGH) + #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE #define pgprot_dmacoherent(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN) diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c index 571ae7ce03f2..ba4ad5b05f63 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c @@ -259,6 +259,7 @@ static int plt_sd3_pad_change(int clock) static const struct esdhc_platform_data mx6q_sabreauto_sd3_data __initconst = { .cd_gpio = SABREAUTO_SD3_CD, .wp_gpio = SABREAUTO_SD3_WP, + .keep_power_at_suspend = 1, .support_18v = 1, .support_8bit = 1, .delay_line = 0, @@ -268,6 +269,7 @@ static const struct esdhc_platform_data mx6q_sabreauto_sd3_data __initconst = { static const struct esdhc_platform_data mx6q_sabreauto_sd1_data __initconst = { .cd_gpio = SABREAUTO_SD1_CD, .wp_gpio = SABREAUTO_SD1_WP, + .keep_power_at_suspend = 1, }; diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.h b/arch/arm/mach-mx6/board-mx6q_sabreauto.h index 4c74a6aba961..bffd109115c2 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.h +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.h @@ -179,7 +179,7 @@ static iomux_v3_cfg_t mx6q_sabreauto_pads[] = { MX6Q_PAD_EIM_EB0__GPIO_2_28, /* USBOTG ID pin */ - MX6Q_PAD_ENET_RX_ER__ENET_RX_ER, + MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID, /* VIDEO adv7180 INTRQ */ MX6Q_PAD_ENET_RXD0__GPIO_1_27, diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index e4244afe7ae7..b721bc0479f0 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -53,6 +53,7 @@ DEFINE_SPINLOCK(ddr_freq_lock); int low_bus_freq_mode; +int audio_bus_freq_mode; int high_bus_freq_mode; int med_bus_freq_mode; @@ -65,6 +66,7 @@ int bus_freq_scaling_is_active; int lp_high_freq; int lp_med_freq; +int lp_audio_freq; unsigned int ddr_low_rate; unsigned int ddr_med_rate; unsigned int ddr_normal_rate; @@ -97,6 +99,9 @@ static void reduce_bus_freq_handler(struct work_struct *work) if (low_bus_freq_mode || !low_freq_bus_used()) return; + if (audio_bus_freq_mode && lp_audio_freq) + return; + while (!mutex_trylock(&bus_freq_mutex)) msleep(1); @@ -106,26 +111,42 @@ static void reduce_bus_freq_handler(struct work_struct *work) mutex_unlock(&bus_freq_mutex); return; } - clk_enable(pll3); + if (audio_bus_freq_mode && lp_audio_freq) { + mutex_unlock(&bus_freq_mutex); + return; + } + + clk_enable(pll3); - update_ddr_freq(24000000); + if (lp_audio_freq) { + /* Need to ensure that PLL2_PFD_400M is kept ON. */ + clk_enable(pll2_400); + update_ddr_freq(50000000); + audio_bus_freq_mode = 1; + low_bus_freq_mode = 0; + } else { + update_ddr_freq(24000000); + if (audio_bus_freq_mode) + clk_disable(pll2_400); + low_bus_freq_mode = 1; + audio_bus_freq_mode = 0; + } if (med_bus_freq_mode) clk_disable(pll2_400); - low_bus_freq_mode = 1; high_bus_freq_mode = 0; med_bus_freq_mode = 0; - /* Power gate the PU LDO. */ - org_ldo = reg = __raw_readl(ANADIG_REG_CORE); - reg &= ~(ANADIG_REG_TARGET_MASK << ANADIG_REG1_PU_TARGET_OFFSET); - __raw_writel(reg, ANADIG_REG_CORE); - - mutex_unlock(&bus_freq_mutex); + if (cpu_is_mx6q()) { + /* Power gate the PU LDO. */ + org_ldo = reg = __raw_readl(ANADIG_REG_CORE); + reg &= ~(ANADIG_REG_TARGET_MASK << ANADIG_REG1_PU_TARGET_OFFSET); + __raw_writel(reg, ANADIG_REG_CORE); + } clk_disable(pll3); - + mutex_unlock(&bus_freq_mutex); } @@ -176,26 +197,30 @@ int set_high_bus_freq(int high_bus_freq) clk_enable(pll3); /* Enable the PU LDO */ - if (low_bus_freq_mode) + if (cpu_is_mx6q() && low_bus_freq_mode) __raw_writel(org_ldo, ANADIG_REG_CORE); if (high_bus_freq) { update_ddr_freq(ddr_normal_rate); if (med_bus_freq_mode) clk_disable(pll2_400); - low_bus_freq_mode = 0; high_bus_freq_mode = 1; med_bus_freq_mode = 0; } else { clk_enable(pll2_400); update_ddr_freq(ddr_med_rate); - low_bus_freq_mode = 0; high_bus_freq_mode = 0; med_bus_freq_mode = 1; } + if (audio_bus_freq_mode) + clk_disable(pll2_400); + low_bus_freq_mode = 0; + audio_bus_freq_mode = 0; + + low_bus_freq_mode = 0; - mutex_unlock(&bus_freq_mutex); clk_disable(pll3); + mutex_unlock(&bus_freq_mutex); return 0; } diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 16927e5e182b..12a8fcf8464c 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -47,7 +47,7 @@ extern struct regulator *cpu_regulator; extern struct cpu_op *(*get_cpu_op)(int *op); extern int lp_high_freq; extern int lp_med_freq; -extern int mx6q_revision(void); +extern int lp_audio_freq; void __iomem *apll_base; static struct clk pll1_sys_main_clk; @@ -2494,6 +2494,7 @@ static struct clk ssi1_clk = { #else .secondary = &mmdc_ch0_axi_clk[0], #endif + .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static unsigned long _clk_ssi2_get_rate(struct clk *clk) @@ -2567,6 +2568,7 @@ static struct clk ssi2_clk = { #else .secondary = &mmdc_ch0_axi_clk[0], #endif + .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static unsigned long _clk_ssi3_get_rate(struct clk *clk) @@ -2639,6 +2641,7 @@ static struct clk ssi3_clk = { #else .secondary = &mmdc_ch0_axi_clk[0], #endif + .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE, }; static unsigned long _clk_ldb_di_round_rate(struct clk *clk, @@ -5220,10 +5223,6 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc, /* S/PDIF */ clk_set_parent(&spdif0_clk[0], &pll3_pfd_454M); - /* pxp & epdc */ - clk_set_parent(&ipu2_clk, &pll2_pfd_400M); - clk_set_rate(&ipu2_clk, 200000000); - if (mx6q_revision() == IMX_CHIP_REVISION_1_0) { gpt_clk[0].parent = &ipg_perclk; gpt_clk[0].get_rate = NULL; @@ -5234,6 +5233,9 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc, } if (cpu_is_mx6dl()) { + /* pxp & epdc */ + clk_set_parent(&ipu2_clk, &pll2_pfd_400M); + clk_set_rate(&ipu2_clk, 200000000); if (epdc_enabled) clk_set_parent(&ipu2_di_clk[1], &pll5_video_main_clk); else @@ -5245,6 +5247,7 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc, lp_high_freq = 0; lp_med_freq = 0; + lp_audio_freq = 0; /* Turn OFF all unnecessary PHYs. */ if (cpu_is_mx6q()) { diff --git a/arch/arm/mach-mx6/mx6_ddr_freq.S b/arch/arm/mach-mx6/mx6_ddr_freq.S index 766d867ee1c4..85af2a402e68 100644 --- a/arch/arm/mach-mx6/mx6_ddr_freq.S +++ b/arch/arm/mach-mx6/mx6_ddr_freq.S @@ -191,16 +191,16 @@ switch_pre_periph_clk_50: orr r0, r0, #0xC0000 str r0, [r6, #0x18] - /* Set the MMDC_DIV=4, AXI_DIV = 4, AHB_DIV=6 (need to maintain GPT divider). */ + /* Set the MMDC_DIV=4, AXI_DIV = 4, AHB_DIV=8 (need to maintain GPT divider). */ ldr r0, [r6, #0x14] ldr r2, =0x3F1C00 bic r0, r0, r2 orr r0, r0, #0x180000 - orr r0, r0, #0x10000 + orr r0, r0, #0x30000 /* If changing AHB divider remember to change the IPGPER divider too below. */ - orr r0, r0, #0xC00 + orr r0, r0, #0x1C00 str r0, [r6, #0x14] wait_div_update_50: @@ -348,7 +348,7 @@ ddr_freq_change: /* set CON_REG */ ldr r0, =0x8000 - str r0, [r5, #0x1C] + str r0, [r5, #0x1C] poll_conreq_set_1: ldr r0, [r5, #0x1C] and r0, r0, #0x4000 @@ -587,7 +587,7 @@ poll_conreq_clear_1: dll_on_mode: /* assert DVFS - enter self refresh mode */ ldr r0, [r5, #0x404] - orr r0, r0, #0x200000 + orr r0, r0, #0x200000 str r0, [r5, #0x404] /* de-assert CON_REQ */ @@ -632,7 +632,7 @@ poll_dvfs_clear_2: /* if DLL is currently off, turn it back on */ cmp r9, #0 - beq update_calibration + beq update_calibration_only ldr r0, =0xa5390003 str r0, [r5, #0x800] @@ -697,16 +697,17 @@ update_iomux1: @//setmem /32 0x021b0014 = 0x01ff00db @// MMDC0_MDCFG2 - tRRD - 4ck; tWTR - 4ck; tRTP - 4ck; tDLLK - 512ck @//setmem /32 0x021b0018 = 0x00081740 @// MMDC0_MDMISC, RALAT=0x5 (original value) */ + ldr r9, [r8] @size of array + add r8, r8, #8 @skip first eight bytes in array + ldr r0, [r8, #0x0] @ offset + ldr r3, [r8, #0x4] @ value + str r3, [r5, r0] + add r8, r8, #8 - ldr r0, [r5, #0x0C] - bic r0, r0, #0xf - orr r0, r0, #0x5 - str r0, [r5, #0x0C] - - ldr r0, [r5, #0x10] - bic r0, r0, #0x7 - orr r0, r0, #0x4 - str r0, [r5, #0x10] + ldr r0, [r8, #0x0] @ offset + ldr r3, [r8, #0x4] @ value + str r3, [r5, r0] + add r8, r8, #8 /* update MISC register: WALAT, RALAT */ ldr r0, =0x00081740 @@ -762,11 +763,17 @@ cont8: @//setmem /32 0x021b001c = 0x04088032 @//setmem /32 0x021b001c = 0x0408803a */ - ldr r0, =0x04088032 - str r0, [r5, #0x1C] + /* MR2 - CS0 */ + ldr r0, [r8, #0x0] @ offset + ldr r3, [r8, #0x4] @ value + str r3, [r5, r0] + add r8, r8, #8 - ldr r0, =0x0408803a - str r0, [r5, #0x1C] + /*MR2 - CS1 */ + ldr r0, [r8, #0x0] @ offset + ldr r3, [r8, #0x4] @ value + str r3, [r5, r0] + add r8, r8, #8 ldr r0, =0x00428031 str r0, [r5, #0x1C] @@ -778,11 +785,17 @@ cont8: @// setmem /32 0x021b001c = 0x08408030 @// setmem /32 0x021b001c = 0x08408038 */ - ldr r0, =0x08408030 - str r0, [r5, #0x1C] + /* MR1 - CS0 */ + ldr r0, [r8, #0x0] @ offset + ldr r3, [r8, #0x4] @ value + str r3, [r5, r0] + add r8, r8, #8 - ldr r0, =0x08408038 - str r0, [r5, #0x1C] + /*MR1 - CS1 */ + ldr r0, [r8, #0x0] @ offset + ldr r3, [r8, #0x4] @ value + str r3, [r5, r0] + add r8, r8, #8 /* issue a zq command @// setmem /32 0x021b001c = 0x04000040 @@ -798,8 +811,11 @@ cont8: @//setmem /32 0x021b0818 = 0x00022225 @// DDR_PHY_P0_MPODTCTRL @//setmem /32 0x021b4818 = 0x00022225 @// DDR_PHY_P1_MPODTCTRL */ - ldr r0, =0x00022225 - str r0, [r5, #0x818] + ldr r0, [r8, #0x0] @ offset + ldr r3, [r8, #0x4] @ value + str r3, [r5, r0] + add r8, r8, #8 + ldr r2, =0x4818 str r0, [r5, r2] @@ -827,10 +843,19 @@ cont15: orr r0, r0, #0x5500 str r0, [r5, #0x4] + b update_calibration + +update_calibration_only: + ldr r1, [r8] @ size of array + sub r1, r1, #7 @ first 7 entries are not related to calibration + add r8, r8, #64 @ Skip the first 7 entries that are needed only when DLL was OFF + count entry. + b update_calib + update_calibration: /* Write the new calibration values. */ - ldr r1, [r8] @size of array - add r8, r8, #8 @skip first eight bytes in array + mov r1, r9 @ size of array + sub r1, r1, #7 @ first 7 entries are not related to calibration + update_calib: ldr r0, [r8, #0x0] @ offset ldr r3, [r8, #0x4] @ value diff --git a/arch/arm/mach-mx6/mx6_mmdc.c b/arch/arm/mach-mx6/mx6_mmdc.c index 2b5ce842489e..2498f01e0889 100644 --- a/arch/arm/mach-mx6/mx6_mmdc.c +++ b/arch/arm/mach-mx6/mx6_mmdc.c @@ -64,12 +64,22 @@ static int ddr_settings_size; static int iomux_settings_size; static volatile unsigned int cpus_in_wfe; static volatile bool wait_for_ddr_freq_update; - +static int curr_ddr_rate; #define MIN_DLL_ON_FREQ 333000000 #define MAX_DLL_OFF_FREQ 125000000 -unsigned long ddr3_mmdc_regs_offsets[][2] = { +unsigned long ddr3_dll_mx6q[][2] = { + {0x0c, 0x0}, + {0x10, 0x0}, + {0x1C, 0x04088032}, + {0x1C, 0x0408803a}, + {0x1C, 0x08408030}, + {0x1C, 0x08408038}, + {0x818, 0x0}, +}; + +unsigned long ddr3_calibration[][2] = { {0x83c, 0x0}, {0x840, 0x0}, {0x483c, 0x0}, @@ -80,6 +90,16 @@ unsigned long ddr3_mmdc_regs_offsets[][2] = { {0x4850, 0x0}, }; +unsigned long ddr3_dll_mx6dl[][2] = { + {0x0c, 0x0}, + {0x10, 0x0}, + {0x1C, 0x04008032}, + {0x1C, 0x0400803a}, + {0x1C, 0x07208030}, + {0x1C, 0x07208038}, + {0x818, 0x0}, +}; + unsigned long iomux_offsets_mx6q[][2] = { {0x5A8, 0x0}, {0x5B0, 0x0}, @@ -90,6 +110,7 @@ unsigned long iomux_offsets_mx6q[][2] = { {0x5B8, 0x0}, {0x5C0, 0x0}, }; + unsigned long iomux_offsets_mx6dl[][2] = { {0x4BC, 0x0}, {0x4C0, 0x0}, @@ -146,13 +167,14 @@ irqreturn_t wait_in_wfe_irq(int irq, void *dev_id) wfe(); *((char *)(&cpus_in_wfe) + (u8)me) = 0; + return IRQ_HANDLED; } /* Change the DDR frequency. */ int update_ddr_freq(int ddr_rate) { - int i; + int i, j; unsigned int reg; bool dll_off = false; unsigned int online_cpus = 0; @@ -162,17 +184,26 @@ int update_ddr_freq(int ddr_rate) if (!can_change_ddr_freq()) return -1; + if (ddr_rate == curr_ddr_rate) + return 0; + if (low_bus_freq_mode) dll_off = true; iram_ddr_settings[0][0] = ddr_settings_size; iram_iomux_settings[0][0] = iomux_settings_size; - if (ddr_rate == ddr_med_rate) { - for (i = 0; i < iram_ddr_settings[0][0]; i++) { + if (ddr_rate == ddr_med_rate && cpu_is_mx6q()) { + for (i = 0; i < ARRAY_SIZE(ddr3_dll_mx6q); i++) { iram_ddr_settings[i + 1][0] = - ddr3_400[i][0]; + normal_mmdc_settings[i][0]; iram_ddr_settings[i + 1][1] = - ddr3_400[i][1]; + normal_mmdc_settings[i][1]; + } + for (j = 0, i = ARRAY_SIZE(ddr3_dll_mx6q); i < iram_ddr_settings[0][0]; j++, i++) { + iram_ddr_settings[i + 1][0] = + ddr3_400[j][0]; + iram_ddr_settings[i + 1][1] = + ddr3_400[j][1]; } } else if (ddr_rate == ddr_normal_rate) { for (i = 0; i < iram_ddr_settings[0][0]; i++) { @@ -190,7 +221,6 @@ int update_ddr_freq(int ddr_rate) *((char *)(&cpus_in_wfe) + (u8)me) = 0xff; wait_for_ddr_freq_update = true; - for_each_online_cpu(cpu) { *((char *)(&online_cpus) + (u8)cpu) = 0xff; if (cpu != me) { @@ -206,6 +236,8 @@ int update_ddr_freq(int ddr_rate) /* Now we can change the DDR frequency. */ mx6_change_ddr_freq(ddr_rate, iram_ddr_settings, dll_off, iram_iomux_settings); + curr_ddr_rate = ddr_rate; + /* DDR frequency change is done . */ wait_for_ddr_freq_update = false; @@ -229,19 +261,37 @@ int init_mmdc_settings(void) gic_dist_base = ioremap(IC_DISTRIBUTOR_BASE_ADDR, SZ_16K); gic_cpu_base = ioremap(IC_INTERFACES_BASE_ADDR, SZ_16K); - normal_mmdc_settings = ddr3_mmdc_regs_offsets; - ddr_settings_size = ARRAY_SIZE(ddr3_mmdc_regs_offsets); + if (cpu_is_mx6q()) + ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6q) + ARRAY_SIZE(ddr3_calibration); + if (cpu_is_mx6dl()) + ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6dl) + ARRAY_SIZE(ddr3_calibration); + + normal_mmdc_settings = kmalloc((ddr_settings_size * 8), GFP_KERNEL); + if (cpu_is_mx6q()) { + memcpy(normal_mmdc_settings, ddr3_dll_mx6q, sizeof(ddr3_dll_mx6q)); + memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6q)), ddr3_calibration, sizeof(ddr3_calibration)); + } + if (cpu_is_mx6dl()) { + memcpy(normal_mmdc_settings, ddr3_dll_mx6dl, sizeof(ddr3_dll_mx6dl)); + memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6dl)), ddr3_calibration, sizeof(ddr3_calibration)); + } /* Store the original DDR settings at boot. */ for (i = 0; i < ddr_settings_size; i++) { - normal_mmdc_settings[i][1] = - __raw_readl(mmdc_base - + normal_mmdc_settings[i][0]); + /*Writes via command mode register cannot be read back. + * Hence hardcode them in the initial static array. + * This may require modification on a per customer basis. + */ + if (normal_mmdc_settings[i][0] != 0x1C) + normal_mmdc_settings[i][1] = + __raw_readl(mmdc_base + + normal_mmdc_settings[i][0]); } + /* Store the size of the array in iRAM also, * increase the size by 8 bytes. */ - iram_ddr_settings = iram_alloc(ddr_settings_size + 8, &iram_paddr); + iram_ddr_settings = iram_alloc((ddr_settings_size * 8) + 8, &iram_paddr); if (iram_ddr_settings == NULL) { printk(KERN_DEBUG "%s: failed to allocate iRAM memory for ddr settings\n", @@ -249,10 +299,11 @@ int init_mmdc_settings(void) return ENOMEM; } + iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6q); /* Store the size of the iomux settings in iRAM also, * increase the size by 8 bytes. */ - iram_iomux_settings = iram_alloc(iomux_settings_size + 8, &iram_paddr); + iram_iomux_settings = iram_alloc((iomux_settings_size * 8) + 8, &iram_paddr); if (iram_iomux_settings == NULL) { printk(KERN_DEBUG "%s: failed to allocate iRAM memory for iomuxr settings\n", @@ -262,7 +313,6 @@ int init_mmdc_settings(void) /* Store the IOMUX settings at boot. */ if (cpu_is_mx6q()) { - iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6q); for (i = 0; i < iomux_settings_size; i++) { iomux_offsets_mx6q[i][1] = __raw_readl(iomux_base @@ -272,8 +322,8 @@ int init_mmdc_settings(void) } irq_used = irqs_used_mx6q; } + if (cpu_is_mx6dl()) { - iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6dl); for (i = 0; i < iomux_settings_size; i++) { iomux_offsets_mx6dl[i][1] = __raw_readl(iomux_base diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index f96d2c730020..79e05f69631c 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -357,6 +357,18 @@ dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_ } EXPORT_SYMBOL(dma_alloc_writecombine); +/* + * Allocate DMA-writethrough memory space and return both the kernel remapped + * virtual and bus address for that space. + */ +void * +dma_alloc_writethrough(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) +{ + return __dma_alloc(dev, size, handle, gfp, + pgprot_writethrough(pgprot_kernel)); +} +EXPORT_SYMBOL(dma_alloc_writethrough); + static int dma_mmap(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size) { diff --git a/arch/arm/plat-mxc/ahci_sata.c b/arch/arm/plat-mxc/ahci_sata.c index 0d78a123a469..cee34b6f70d9 100644 --- a/arch/arm/plat-mxc/ahci_sata.c +++ b/arch/arm/plat-mxc/ahci_sata.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -18,11 +18,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <asm/errno.h> #include <linux/io.h> #include <linux/clk.h> #include <linux/kernel.h> #include <linux/delay.h> -#include <asm/errno.h> + +#include <mach/hardware.h> #include <mach/ahci_sata.h> int write_phy_ctl_ack_polling(u32 data, void __iomem *mmio, @@ -140,6 +142,13 @@ int sata_init(void __iomem *addr, unsigned long timer1ms) u32 tmpdata; int iterations = 20; + /* + * Make sure that SATA PHY is enabled + * The PDDQ mode is disabled. + */ + tmpdata = readl(addr + PORT_PHY_CTL); + writel(tmpdata & (~PORT_PHY_CTL_PDDQ_LOC), addr + PORT_PHY_CTL); + /* Reset HBA */ writel(HOST_RESET, addr + HOST_CTL); diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index f6e14a3cf2f5..43d33376b52d 100755 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c @@ -47,6 +47,8 @@ extern int dvfs_core_is_active; extern int lp_high_freq; extern int lp_med_freq; +extern int lp_audio_freq; +extern int audio_bus_freq_mode; extern int low_bus_freq_mode; extern int high_bus_freq_mode; extern int med_bus_freq_mode; @@ -115,13 +117,19 @@ int clk_enable(struct clk *clk) lp_high_freq++; else if (clk->flags & AHB_MED_SET_POINT) lp_med_freq++; + else if (clk->flags & AHB_AUDIO_SET_POINT) + lp_audio_freq++; if ((clk->flags & CPU_FREQ_TRIG_UPDATE) && (clk_get_usecount(clk) == 0)) { if (!(clk->flags & (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) { - if (low_freq_bus_used() && !low_bus_freq_mode) - set_low_bus_freq(); + if (low_freq_bus_used()) { + if ((clk->flags & AHB_AUDIO_SET_POINT) & !audio_bus_freq_mode) + set_low_bus_freq(); + else if (!low_bus_freq_mode) + set_low_bus_freq(); + } } else { if ((clk->flags & AHB_MED_SET_POINT) && !med_bus_freq_mode) @@ -164,6 +172,8 @@ void clk_disable(struct clk *clk) lp_high_freq--; else if (clk->flags & AHB_MED_SET_POINT) lp_med_freq--; + else if (clk->flags & AHB_AUDIO_SET_POINT) + lp_audio_freq--; mutex_lock(&clocks_mutex); __clk_disable(clk); diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h index a66b0018c944..e150579e5ced 100755 --- a/arch/arm/plat-mxc/include/mach/clock.h +++ b/arch/arm/plat-mxc/include/mach/clock.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2005-2012 Freescale Semiconductor, Inc. * Copyright 2008 Juergen Beisert, kernel@pengutronix.de * * This program is free software; you can redistribute it and/or @@ -71,6 +71,7 @@ int clk_get_usecount(struct clk *clk); #define CPU_FREQ_TRIG_UPDATE (1 << 3) /* CPUFREQ trig update */ #define AHB_HIGH_SET_POINT (1 << 4) /* Requires max AHB clock */ #define AHB_MED_SET_POINT (1 << 5) /* Requires med AHB clock */ +#define AHB_AUDIO_SET_POINT (1 << 6) /* Requires LOW AHB, but higher DDR clock */ unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref); |