예제 #1
0
int update_ddr_freq(int ddr_rate)
{
	int i;
	unsigned int reg;

	if (!can_change_ddr_freq())
		return -1;

	local_flush_tlb_all();
	flush_cache_all();

	iram_ddr_settings[0][0] = ddr_settings_size;
	if (ddr_rate == LP_APM_CLK) {
		if (mx50_ddr_type == MX50_LPDDR2) {
			for (i = 0; i < iram_ddr_settings[0][0]; i++) {
				iram_ddr_settings[i + 1][0] =
								lpddr2_24[i][0];
				iram_ddr_settings[i + 1][1] =
								lpddr2_24[i][1];
			}
		} else {
			for (i = 0; i < iram_ddr_settings[0][0]; i++) {
				iram_ddr_settings[i + 1][0]
								= mddr_24[i][0];
				iram_ddr_settings[i + 1][1]
								= mddr_24[i][1];
			}
		}
	} else {
        if (mx50_ddr_type == MX50_DDR2)
        {
		    if (ddr_rate == ddr_low_rate) {
		        for (i = 0; i < iram_ddr_settings[0][0]; i++) {
			        iram_ddr_settings[i + 1][0] =
					        ddr2_133[i][0];
			        iram_ddr_settings[i + 1][1] =
					        ddr2_133[i][1];
		        }
            }
		    if (ddr_rate == ddr_med_rate) {
		        for (i = 0; i < iram_ddr_settings[0][0]; i++) {
			        iram_ddr_settings[i + 1][0] =
					        ddr2_160[i][0];
			        iram_ddr_settings[i + 1][1] =
					        ddr2_160[i][1];
		        }
            }
		    else {
		        for (i = 0; i < iram_ddr_settings[0][0]; i++) {
			        iram_ddr_settings[i + 1][0] =
					        normal_databahn_settings[i][0];
			        iram_ddr_settings[i + 1][1] =
					        normal_databahn_settings[i][1];
		        }
            }
        }
        else
        {
		    for (i = 0; i < iram_ddr_settings[0][0]; i++) {
			    iram_ddr_settings[i + 1][0] =
					    normal_databahn_settings[i][0];
			    iram_ddr_settings[i + 1][1] =
					    normal_databahn_settings[i][1];
		    }
		    if (ddr_rate == ddr_med_rate) {
			    /*Change the tref setting */
			    for (i = 0; i < iram_ddr_settings[0][0]; i++) {
				    if (iram_ddr_settings[i + 1][0] == 0x40) {
					    if (mx50_ddr_type == MX50_LPDDR2)
						    /* LPDDR2 133MHz. */
						    iram_ddr_settings[i + 1][1] =
								    0x00050180;
					    else
						    /* mDDR 133MHz. */
						    iram_ddr_settings[i + 1][1] =
								    0x00050208;
					    break;
				    }
			    }
		    }
        }
    }
	/* Disable all masters from accessing the DDR, leave masters
	 * on port 0 and 1 enabled.
	 */
	reg = __raw_readl(qosc_base + HW_QOS_DISABLE);
	reg |= QoS_DISABLE_MASTERS;
	__raw_writel(reg, qosc_base + HW_QOS_DISABLE_SET);
	udelay(100);

	/* Set the DDR to default freq. */
	change_ddr_freq(ccm_base, databahn_base, ddr_rate,
					iram_ddr_settings);

	/* Enable all masters to access the DDR. */
	__raw_writel(reg, qosc_base + HW_QOS_DISABLE_CLR);

	return 0;
}
예제 #2
0
/* change the DDR frequency. */
int update_ddr_freq(int ddr_rate)
{
	int i, j;
	unsigned int reg;
	bool dll_off = false;
	unsigned int online_cpus = 0;
	int cpu = 0;
	int me;

	if (!can_change_ddr_freq())
		return -1;

	if (ddr_rate == curr_ddr_rate)
		return 0;

	printk(KERN_DEBUG "\nBus freq set to %d start...\n", ddr_rate);

	if (low_bus_freq_mode || audio_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 && cpu_is_imx6q()) {
		for (i = 0; i < ARRAY_SIZE(ddr3_dll_mx6q); i++) {
			iram_ddr_settings[i + 1][0] =
					normal_mmdc_settings[i][0];
			iram_ddr_settings[i + 1][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++) {
			iram_ddr_settings[i + 1][0] =
					normal_mmdc_settings[i][0];
			iram_ddr_settings[i + 1][1] =
					normal_mmdc_settings[i][1];
		}
	}

	/* ensure that all Cores are in WFE. */
	local_irq_disable();

	me = smp_processor_id();

	*((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) {
			/* set the interrupt to be pending in the GIC. */
			reg = 1 << (irqs_used[cpu] % 32);
			writel_relaxed(reg, gic_dist_base + GIC_DIST_PENDING_SET
				+ (irqs_used[cpu] / 32) * 4);
		}
	}
	while (cpus_in_wfe != online_cpus)
		udelay(5);

	/* 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;

	/* wake up all the cores. */
	sev();

	*((char *)(&cpus_in_wfe) + (u8)me) = 0;

	local_irq_enable();

	printk(KERN_DEBUG "Bus freq set to %d done!\n", ddr_rate);

	return 0;
}