Esempio n. 1
0
void __init tegra_soc_init_dvfs(void)
{
	int i;
	struct clk *c;
	struct dvfs *d;
	int process_id;
	int ret;
	int cpu_process_id = tegra_cpu_process_id();
	int core_process_id = tegra_core_process_id();
	int speedo_id = tegra_soc_speedo_id();

	BUG_ON(speedo_id >= ARRAY_SIZE(cpu_speedo_nominal_millivolts));
	tegra2_dvfs_rail_vdd_cpu.nominal_millivolts =
		cpu_speedo_nominal_millivolts[speedo_id];
	BUG_ON(speedo_id >= ARRAY_SIZE(core_speedo_nominal_millivolts));
	tegra2_dvfs_rail_vdd_core.nominal_millivolts =
		core_speedo_nominal_millivolts[speedo_id];
	tegra2_dvfs_rail_vdd_aon.nominal_millivolts =
		core_speedo_nominal_millivolts[speedo_id];

	tegra_dvfs_init_rails(tegra2_dvfs_rails, ARRAY_SIZE(tegra2_dvfs_rails));
	tegra_dvfs_add_relationships(tegra2_dvfs_relationships,
		ARRAY_SIZE(tegra2_dvfs_relationships));
	/*
	 * VDD_CORE must always be at least 50 mV higher than VDD_CPU
	 * Fill out cpu_core_millivolts based on cpu_millivolts
	 */
	for (i = 0; i < ARRAY_SIZE(dvfs_init); i++) {
		d = &dvfs_init[i];

		process_id = strcmp(d->clk_name, "cpu") ?
			core_process_id : cpu_process_id;
		if ((d->process_id != -1 && d->process_id != process_id) ||
		    (d->speedo_id != -1 && d->speedo_id != speedo_id)) {
			pr_debug("tegra_dvfs: rejected %s speedo %d,"
				" process %d\n", d->clk_name, d->speedo_id,
				d->process_id);
			continue;
		}

		c = tegra_get_clock_by_name(d->clk_name);

		if (!c) {
			pr_debug("tegra_dvfs: no clock found for %s\n",
				d->clk_name);
			continue;
		}

		ret = tegra_enable_dvfs_on_clk(c, d);
		if (ret)
			pr_err("tegra_dvfs: failed to enable dvfs on %s\n",
				c->name);
	}

	if (tegra_dvfs_core_disabled)
		tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_core);

	if (tegra_dvfs_cpu_disabled)
		tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_cpu);
}
Esempio n. 2
0
void tegra_init_fuse(void)
{
	u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
	reg |= 1 << 28;
	writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
	tegra_init_speedo_data();

	pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
		tegra_revision_name[tegra_get_revision()],
		tegra_sku_id(), tegra_cpu_process_id(),
		tegra_core_process_id());
}
Esempio n. 3
0
static int t3_variant_debugfs_show(struct seq_file *s, void *data)
{
	int cpu_speedo_id = tegra_cpu_speedo_id();
	int soc_speedo_id = tegra_soc_speedo_id();
	int cpu_process_id = tegra_cpu_process_id();
	int core_process_id = tegra_core_process_id();

	seq_printf(s, "cpu_speedo_id => %d\n", cpu_speedo_id);
	seq_printf(s, "soc_speedo_id => %d\n", soc_speedo_id);
	seq_printf(s, "cpu_process_id => %d\n", cpu_process_id);
	seq_printf(s, "core_process_id => %d\n", core_process_id);

	return 0;
}
Esempio n. 4
0
void __init tegra2_init_dvfs(void)
{
	int i;
	struct clk *c;
	struct dvfs *d;
	int ret;
	int cpu_process_id = tegra_cpu_process_id();

	tegra_dvfs_init_rails(tegra2_dvfs_rails, ARRAY_SIZE(tegra2_dvfs_rails));
	tegra_dvfs_add_relationships(tegra2_dvfs_relationships,
		ARRAY_SIZE(tegra2_dvfs_relationships));
	/*
	 * VDD_CORE must always be at least 50 mV higher than VDD_CPU
	 * Fill out cpu_core_millivolts based on cpu_millivolts
	 */
	for (i = 0; i < ARRAY_SIZE(dvfs_init); i++) {
		d = &dvfs_init[i];

		if (d->cpu_process_id != -1 &&
				d->cpu_process_id != cpu_process_id)
			continue;

		c = tegra_get_clock_by_name(d->clk_name);

		if (!c) {
			pr_debug("tegra_dvfs: no clock found for %s\n",
				d->clk_name);
			continue;
		}

		ret = tegra_enable_dvfs_on_clk(c, d);
		if (ret)
			pr_err("tegra_dvfs: failed to enable dvfs on %s\n",
				c->name);
	}

	if (tegra_dvfs_core_disabled)
		tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_core);

	if (tegra_dvfs_cpu_disabled)
		tegra_dvfs_rail_disable(&tegra2_dvfs_rail_vdd_cpu);
}
void __init tegra_soc_init_dvfs(void)
{
	int cpu_speedo_id = tegra_cpu_speedo_id();
	int soc_speedo_id = tegra_soc_speedo_id();
	int cpu_process_id = tegra_cpu_process_id();
#ifdef CONFIG_TEGRA3_LP_CORE_OVERDRIVE
	int core_process_id = 2;
#else
	int core_process_id = tegra_core_process_id();
#endif

	int i;
	int core_nominal_mv_index;
	int cpu_nominal_mv_index;

#ifndef CONFIG_TEGRA_CORE_DVFS
	tegra_dvfs_core_disabled = true;
#endif
#ifndef CONFIG_TEGRA_CPU_DVFS
	tegra_dvfs_cpu_disabled = true;
#endif

	/*
	 * Find nominal voltages for core (1st) and cpu rails before rail
	 * init. Nominal voltage index in the scaling ladder will also be
	 * used to determine max dvfs frequency for the respective domains.
	 */
	core_nominal_mv_index = get_core_nominal_mv_index(soc_speedo_id);
	if (core_nominal_mv_index < 0) {
		tegra3_dvfs_rail_vdd_core.disabled = true;
		tegra_dvfs_core_disabled = true;
		core_nominal_mv_index = 0;
	}
	tegra3_dvfs_rail_vdd_core.nominal_millivolts =
		core_millivolts[core_nominal_mv_index];

	cpu_nominal_mv_index = get_cpu_nominal_mv_index(
		cpu_speedo_id, cpu_process_id, &cpu_dvfs);
	BUG_ON((cpu_nominal_mv_index < 0) || (!cpu_dvfs));
	tegra3_dvfs_rail_vdd_cpu.nominal_millivolts =
		cpu_millivolts[cpu_nominal_mv_index];

	/* Init rail structures and dependencies */
	tegra_dvfs_init_rails(tegra3_dvfs_rails, ARRAY_SIZE(tegra3_dvfs_rails));
	tegra_dvfs_add_relationships(tegra3_dvfs_relationships,
		ARRAY_SIZE(tegra3_dvfs_relationships));

	/* Search core dvfs table for speedo/process matching entries and
	   initialize dvfs-ed clocks */
	for (i = 0; i <  ARRAY_SIZE(core_dvfs_table); i++) {
		struct dvfs *d = &core_dvfs_table[i];
		if (!match_dvfs_one(d, soc_speedo_id, core_process_id))
			continue;
		init_dvfs_one(d, core_nominal_mv_index);
	}

	/* Initialize matching cpu dvfs entry already found when nominal
	   voltage was determined */
	init_dvfs_one(cpu_dvfs, cpu_nominal_mv_index);
	init_dvfs_cold(cpu_dvfs, cpu_nominal_mv_index);

	/* Finally disable dvfs on rails if necessary */
	if (tegra_dvfs_core_disabled)
		tegra_dvfs_rail_disable(&tegra3_dvfs_rail_vdd_core);
	if (tegra_dvfs_cpu_disabled)
		tegra_dvfs_rail_disable(&tegra3_dvfs_rail_vdd_cpu);

	pr_info("tegra dvfs: VDD_CPU nominal %dmV, scaling %s\n",
		tegra3_dvfs_rail_vdd_cpu.nominal_millivolts,
		tegra_dvfs_cpu_disabled ? "disabled" : "enabled");
	pr_info("tegra dvfs: VDD_CORE nominal %dmV, scaling %s\n",
		tegra3_dvfs_rail_vdd_core.nominal_millivolts,
		tegra_dvfs_core_disabled ? "disabled" : "enabled");
}
static bool tegra_is_variant_4(void)
{
	return tegra_cpu_process_id()==4;
}
Esempio n. 7
0
/*
 * Specify regulator current in mA, e.g. 5000mA
 * Use 0 for default
 */
void __init tegra_init_cpu_edp_limits(unsigned int regulator_mA)
{
	int cpu_speedo_id = tegra_cpu_speedo_id();
	int cpu_process_id = tegra_cpu_process_id();
	int i, j;
	struct tegra_edp_limits *e;
	struct tegra_edp_entry *t = (struct tegra_edp_entry *)tegra_edp_map;
	int tsize = sizeof(tegra_edp_map)/sizeof(struct tegra_edp_entry);

	if (!regulator_mA) {
		edp_limits = edp_default_limits;
		edp_limits_size = ARRAY_SIZE(edp_default_limits);
		return;
	}
	regulator_cur = regulator_mA;

	for (i = 0; i < tsize; i++) {
		if (t[i].speedo_id == cpu_speedo_id &&
		    t[i].regulator_100mA <= regulator_mA / 100)
			break;
	}

	/* No entry found in tegra_edp_map */
	if (i >= tsize) {
		edp_limits = edp_default_limits;
		edp_limits_size = ARRAY_SIZE(edp_default_limits);
		return;
	}

	/* Find all rows for this entry */
	for (j = i + 1; j < tsize; j++) {
		if (t[i].speedo_id != t[j].speedo_id ||
		    t[i].regulator_100mA != t[j].regulator_100mA)
			break;
	}

	edp_limits_size = j - i;
	e = kmalloc(sizeof(struct tegra_edp_limits) * edp_limits_size,
		    GFP_KERNEL);
	BUG_ON(!e);

#ifdef CONFIG_CPU_OVERCLOCK
  switch (cpu_process_id) {
    case 0:
      edpl0 = 20;
      edpl123 = 30;
      break;
    case 1:
      edpl0 = 20;
      edpl123 = 30;
      break;
    case 2:
      edpl0 = 20;
      edpl123 = 30;
      break;
    case 3:
    default:
      edpl0 = 20;
      edpl123 = 30;
      break;
}
#endif

	for (j = 0; j < edp_limits_size; j++) {
#ifdef CONFIG_CPU_OVERCLOCK
		e[j].temperature = (int)t[i+j].temperature;
		e[j].freq_limits[0] = (unsigned int)(t[i+j].freq_limits[0]+edpl0) * 10000;
		e[j].freq_limits[1] = (unsigned int)(t[i+j].freq_limits[1]+edpl123) * 10000;
		e[j].freq_limits[2] = (unsigned int)(t[i+j].freq_limits[2]+edpl123) * 10000;
		e[j].freq_limits[3] = (unsigned int)(t[i+j].freq_limits[3]+edpl123) * 10000;
#else
		e[j].temperature = (int)t[i+j].temperature;
		e[j].freq_limits[0] = (unsigned int)t[i+j].freq_limits[0] * 10000;
		e[j].freq_limits[1] = (unsigned int)(t[i+j].freq_limits[1]+10) * 10000;
		e[j].freq_limits[2] = (unsigned int)(t[i+j].freq_limits[2]+10) * 10000;
		e[j].freq_limits[3] = (unsigned int)(t[i+j].freq_limits[3]+10) * 10000;
#endif
	}

	if (edp_limits != edp_default_limits)
		kfree(edp_limits);

	edp_limits = e;
}