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); }
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()); }
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; }
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; }
/* * 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; }