/** * omap4_opp_init() - initialize omap4 opp table */ int __init omap4_opp_init(void) { int r = -ENODEV; int trimmed = 1; if (!cpu_is_omap44xx()) return r; if (cpu_is_omap443x()) r = omap_init_opp_table(omap443x_opp_def_list, ARRAY_SIZE(omap443x_opp_def_list)); else if (cpu_is_omap446x()) { r = omap_init_opp_table(omap446x_opp_def_list, ARRAY_SIZE(omap446x_opp_def_list)); trimmed = omap_readl(0x4a002268) & ((1 << 18) | (1 << 19)); /* if device is untrimmed override DPLL TRIM register */ if (!trimmed) omap_writel(0x29, 0x4a002330); } if (!r) { if (omap4_has_mpu_1_2ghz()) omap4_mpu_opp_enable(1200000000); if (!trimmed) pr_info("This is DPLL un-trimmed SOM. OPP is limited at 1.2 GHz\n"); if (omap4_has_mpu_1_5ghz() && trimmed) omap4_mpu_opp_enable(1500000000); } return r; }
/** * omap4_opp_init() - initialize omap4 opp table */ int __init omap4_opp_init(void) { int r = -ENODEV; if (!cpu_is_omap44xx()) return r; if (cpu_is_omap443x()) r = omap_init_opp_table(omap443x_opp_def_list, ARRAY_SIZE(omap443x_opp_def_list)); else if (cpu_is_omap446x()) r = omap_init_opp_table(omap446x_opp_def_list, ARRAY_SIZE(omap446x_opp_def_list)); if (!r) { if (omap4_has_mpu_1_2ghz()) omap4_mpu_opp_enable(1200000000); /* 1.8Ghz까지 오버클럭 */ if (omap4_has_mpu_1_5ghz()) omap4_mpu_opp_enable(1340000000); omap4_mpu_opp_enable(1520000000); omap4_mpu_opp_enable(1650000000); } return r; }
static ssize_t omap4_soc_type_max_freq(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { char *max_freq = "unknown"; if (omap4_has_mpu_1_5ghz()) max_freq = "1.5Ghz"; else if (omap4_has_mpu_1_2ghz()) max_freq = "1.2Ghz"; else max_freq = "1.0Ghz"; return sprintf(buf, "%s\n", max_freq); }
/** * omap4460_mpu_dpll_trim_override() - provide a selective s/w trim overide */ static __init void omap4460_mpu_dpll_trim_override(void) { u32 val; val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_1) & OMAP4_DPLL_MPU_TRIMMED_MASK; switch (val) { case OMAP4_DPLL_MPU_TRIMMED_VAL_3P0: /* all ok.. */ break; case OMAP4_DPLL_MPU_TRIMMED_VAL_2P4: /* Cross check! */ if (omap4_has_mpu_1_5ghz()) { WARN(1, "%s: OMAP is 1.5GHz capable, trimmed=1.2GHz!\n", __func__); } break; default: WARN(1, "%s: UNKNOWN TRIM:0x%08x, using s/w override\n", __func__, val); /* fall through and use override */ case 0: /* * For PRE_RTP devices: Not trimmed, use s/w override! * We only support unto 1.2GHz with s/w override, * so just give a gentle warning if higher opp is attempted */ dpll_trim_override = true; /* Confirm */ if (omap4_has_mpu_1_5ghz()) { pr_err("%s: OMAP is 1.5GHz capable, s/w trim=1.2GHz!\n", __func__); } break; } }
/** * omap4_opp_init() - initialize omap4 opp table */ int __init omap4_opp_init(void) { int r = -ENODEV; if (!cpu_is_omap44xx()) return r; if (cpu_is_omap443x()) r = omap_init_opp_table(omap443x_opp_def_list, ARRAY_SIZE(omap443x_opp_def_list)); else if (cpu_is_omap446x()) r = omap_init_opp_table(omap446x_opp_def_list, ARRAY_SIZE(omap446x_opp_def_list)); if (!r) { if (omap4_has_mpu_1_2ghz()) omap4_mpu_opp_enable(1200000000); /* The tuna supports 1.35GHz & 1.42GHz */ if (omap4_has_mpu_1_5ghz()) omap4_mpu_opp_enable(1350000000); omap4_mpu_opp_enable(1420000000); } return r; }
int omap4460plus_temp_sensor_init(struct scm *scm_ptr) { struct omap_temp_sensor_registers *reg_ptr; struct omap4460plus_temp_sensor_data *ts_ptr; struct scm_regval *regval_ptr; int clk_rate, ret, i; scm_ptr->registers = kzalloc(sizeof(reg_ptr) * scm_ptr->cnt, GFP_KERNEL); if (!scm_ptr->registers) { pr_err("Unable to allocate mem for scm registers\n"); return -ENOMEM; } scm_ptr->ts_data = kzalloc(sizeof(ts_ptr) * scm_ptr->cnt, GFP_KERNEL); if (!scm_ptr->ts_data) { pr_err("Unable to allocate memory for ts data\n"); ret = -ENOMEM; goto fail_alloc; } scm_ptr->regval = kzalloc(sizeof(regval_ptr) * scm_ptr->cnt, GFP_KERNEL); if (!scm_ptr->regval) { pr_err("Unable to allocate memory for regval\n"); ret = -ENOMEM; goto fail_alloc; } #ifdef CONFIG_THERMAL_FRAMEWORK scm_ptr->therm_fw = kzalloc(sizeof(struct thermal_dev *) * scm_ptr->cnt, GFP_KERNEL); if (!scm_ptr->therm_fw) { pr_err("Unable to allocate memory for ts data\n"); return -ENOMEM; } #elif defined(CONFIG_CPU_THERMAL) scm_ptr->cpu_therm = kzalloc(sizeof(struct thermal_sensor_conf) * scm_ptr->cnt, GFP_KERNEL); if (!scm_ptr->cpu_therm) { pr_err("Unable to allocate memory for ts data\n"); goto clk_err; } #endif for (i = 0; i < scm_ptr->cnt; i++) { #ifdef CONFIG_THERMAL_FRAMEWORK scm_ptr->therm_fw[i] = kzalloc(sizeof(struct thermal_dev), GFP_KERNEL); #endif scm_ptr->regval[i] = kzalloc(sizeof(struct scm_regval), GFP_KERNEL); } if (scm_ptr->rev == 1) { scm_ptr->registers[0] = &omap4460_mpu_temp_sensor_registers; scm_ptr->ts_data[0] = &omap4460_mpu_temp_sensor_data; scm_ptr->conv_table = omap4460_adc_to_temp; /* * check if the efuse has a non-zero value if not * it is an untrimmed sample and the temperatures * may not be accurate */ if (!omap4plus_scm_readl(scm_ptr, scm_ptr->registers[0]->bgap_efuse)) pr_info("Non-trimmed BGAP, Temp not accurate\n"); #ifdef CONFIG_THERMAL_FRAMEWORK if (scm_ptr->therm_fw) { scm_ptr->therm_fw[0]->name = "omap_ondie_sensor"; scm_ptr->therm_fw[0]->domain_name = "cpu"; scm_ptr->therm_fw[0]->dev = scm_ptr->dev; scm_ptr->therm_fw[0]->dev_ops = &omap_sensor_ops; scm_ptr->therm_fw[0]->sen_id = 0; scm_ptr->therm_fw[0]->slope = 376; scm_ptr->therm_fw[0]->constant_offset = -16000; thermal_sensor_dev_register(scm_ptr->therm_fw[0]); } else { pr_err("%s:Cannot alloc memory for thermal fw\n", __func__); ret = -ENOMEM; } #elif defined(CONFIG_CPU_THERMAL) strncpy(scm_ptr->cpu_therm[0].name, "omap_ondie_sensor", SENSOR_NAME_LEN); scm_ptr->cpu_therm[0].private_data = scm_ptr; scm_ptr->cpu_therm[0].read_temperature = omap_read_temp; if (omap4_has_mpu_1_5ghz()) scm_ptr->cpu_therm[0].sensor_data = &omap4_1500mhz_bandgap_data; else scm_ptr->cpu_therm[0].sensor_data = &omap4_1200mhz_bandgap_data; omap_zones[0] = omap4_register_thermal(scm_ptr->cpu_therm); #endif } else if (scm_ptr->rev == 2) { scm_ptr->registers[0] = &omap5430_mpu_temp_sensor_registers; scm_ptr->ts_data[0] = &omap5430_mpu_temp_sensor_data; scm_ptr->registers[1] = &omap5430_gpu_temp_sensor_registers; scm_ptr->ts_data[1] = &omap5430_gpu_temp_sensor_data; scm_ptr->registers[2] = &omap5430_core_temp_sensor_registers; scm_ptr->ts_data[2] = &omap5430_core_temp_sensor_data; scm_ptr->conv_table = omap5430_adc_to_temp; #ifdef CONFIG_THERMAL_FRAMEWORK if (scm_ptr->therm_fw) { scm_ptr->therm_fw[0]->name = "omap_ondie_mpu_sensor"; scm_ptr->therm_fw[0]->domain_name = "cpu"; scm_ptr->therm_fw[0]->dev = scm_ptr->dev; scm_ptr->therm_fw[0]->dev_ops = &omap_sensor_ops; scm_ptr->therm_fw[0]->sen_id = 0; scm_ptr->therm_fw[0]->slope = 196; scm_ptr->therm_fw[0]->constant_offset = -6822; thermal_sensor_dev_register(scm_ptr->therm_fw[0]); scm_ptr->therm_fw[1]->name = "omap_ondie_gpu_sensor"; scm_ptr->therm_fw[1]->domain_name = "gpu"; scm_ptr->therm_fw[1]->dev = scm_ptr->dev; scm_ptr->therm_fw[1]->dev_ops = &omap_sensor_ops; scm_ptr->therm_fw[1]->sen_id = 1; scm_ptr->therm_fw[1]->slope = 0; scm_ptr->therm_fw[1]->constant_offset = 7000; thermal_sensor_dev_register(scm_ptr->therm_fw[1]); scm_ptr->therm_fw[2]->name = "omap_ondie_core_sensor"; scm_ptr->therm_fw[2]->domain_name = "core"; scm_ptr->therm_fw[2]->dev = scm_ptr->dev; scm_ptr->therm_fw[2]->dev_ops = &omap_sensor_ops; scm_ptr->therm_fw[2]->sen_id = 2; scm_ptr->therm_fw[2]->slope = 0; scm_ptr->therm_fw[2]->constant_offset = 0; thermal_sensor_dev_register(scm_ptr->therm_fw[2]); /*TO DO: Add for GPU and core */ } else { pr_err("%s:Cannot alloc memory for thermal fw\n", __func__); ret = -ENOMEM; } #elif defined(CONFIG_CPU_THERMAL) strncpy(scm_ptr->cpu_therm[0].name, "omap_ondie_sensor", SENSOR_NAME_LEN); scm_ptr->cpu_therm[0].private_data = scm_ptr; scm_ptr->cpu_therm[0].read_temperature = omap_read_temp; scm_ptr->cpu_therm[0].sensor_data = &omap5_1500mhz_bandgap_data; omap_zones[0] = omap4_register_thermal(&scm_ptr->cpu_therm[0]); strncpy(scm_ptr->cpu_therm[1].name, "omap_ondie_gpu_sensor", SENSOR_NAME_LEN); scm_ptr->cpu_therm[1].private_data = scm_ptr; scm_ptr->cpu_therm[1].read_temperature = omap_read_temp; scm_ptr->cpu_therm[1].sensor_data = &omap5_1500mhz_bandgap_data; strncpy(scm_ptr->cpu_therm[2].name, "omap_ondie_core_sensor", SENSOR_NAME_LEN); scm_ptr->cpu_therm[2].private_data = scm_ptr; scm_ptr->cpu_therm[2].read_temperature = omap_read_temp; scm_ptr->cpu_therm[2].sensor_data = &omap5_1500mhz_bandgap_data; #endif } if (scm_ptr->rev == 1) { clk_rate = clk_round_rate(scm_ptr->div_clk, scm_ptr->ts_data[0]->max_freq); if (clk_rate < scm_ptr->ts_data[0]->min_freq || clk_rate == 0xffffffff) { ret = -ENODEV; goto clk_err; } ret = clk_set_rate(scm_ptr->div_clk, clk_rate); if (ret) { pr_err("Cannot set clock rate\n"); goto clk_err; } scm_ptr->clk_rate = clk_rate; } else if (scm_ptr->rev == 2) { /* add clock rate code for omap5430 */ #ifdef CONFIG_MACH_OMAP_5430ZEBU scm_ptr->clk_rate = 1200; #else clk_rate = clk_round_rate(scm_ptr->fclock, scm_ptr->ts_data[0]->max_freq); if (clk_rate < scm_ptr->ts_data[0]->min_freq || clk_rate == 0xffffffff) { ret = -ENODEV; goto clk_err; } ret = clk_set_rate(scm_ptr->fclock, clk_rate); if (ret) { pr_err("Cannot set clock rate\n"); goto clk_err; } scm_ptr->clk_rate = clk_rate; #endif } clk_enable(scm_ptr->fclock); /* 1 clk cycle */ for (i = 0; i < scm_ptr->cnt; i++) configure_temp_sensor_counter(scm_ptr, i, 1); for (i = 0; i < scm_ptr->cnt; i++) { temp_sensor_init_talert_thresholds(scm_ptr, i, scm_ptr->ts_data[i]->t_hot, scm_ptr->ts_data[i]->t_cold); temp_sensor_configure_tshut_hot(scm_ptr, i, scm_ptr->ts_data[i]->tshut_hot); temp_sensor_configure_tshut_cold(scm_ptr, i, scm_ptr->ts_data[i]-> tshut_cold); } enable_continuous_mode(scm_ptr); /* Set .250 seconds time as default counter */ for (i = 0; i < scm_ptr->cnt; i++) { configure_temp_sensor_counter(scm_ptr, i, scm_ptr->clk_rate / 4); } return 0; clk_err: kfree(scm_ptr->ts_data); fail_alloc: kfree(scm_ptr->registers); return ret; }