summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-05-02 11:02:43 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-05-02 11:02:43 +0800
commit3b9257f71a2a0dc0e0061ce2d455c504515c26d9 (patch)
tree6d19fa9ec5cf7973d4b599fce2a8e2861bd0dce9 /arch/arm
parent5f5288b61bc0596dbe1436a65f0bdf52b8d855cb (diff)
parent1b64ead9cdb4eae25789cfc5bbb7d8ad07dee402 (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.h13
-rw-r--r--arch/arm/include/asm/pgtable.h3
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.c2
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.h2
-rw-r--r--arch/arm/mach-mx6/bus_freq.c53
-rw-r--r--arch/arm/mach-mx6/clock.c13
-rw-r--r--arch/arm/mach-mx6/mx6_ddr_freq.S79
-rw-r--r--arch/arm/mach-mx6/mx6_mmdc.c84
-rw-r--r--arch/arm/mm/dma-mapping.c12
-rw-r--r--arch/arm/plat-mxc/ahci_sata.c13
-rwxr-xr-xarch/arm/plat-mxc/clock.c14
-rwxr-xr-xarch/arm/plat-mxc/include/mach/clock.h3
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);