static struct omap_hwmod_mux_info * setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) { struct omap_device_pad *pads; int pads_cnt; u32 val = 0; switch (port_mode[0]) { case OMAP_EHCI_PORT_MODE_PHY: pads = port1_phy_pads; pads_cnt = ARRAY_SIZE(port1_phy_pads); break; case OMAP_EHCI_PORT_MODE_TLL: pads = port1_tll_pads; pads_cnt = ARRAY_SIZE(port1_tll_pads); /* Errata i687: set I/O drive strength to 1 */ if (cpu_is_omap443x()) { val = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_2); val |= OMAP4_USBB1_DR0_DS_MASK; omap4_ctrl_pad_writel(val, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_2); } break; case OMAP_USBHS_PORT_MODE_UNUSED: default: break; } switch (port_mode[1]) { case OMAP_EHCI_PORT_MODE_PHY: pads = port2_phy_pads; pads_cnt = ARRAY_SIZE(port2_phy_pads); break; case OMAP_EHCI_PORT_MODE_TLL: pads = port2_tll_pads; pads_cnt = ARRAY_SIZE(port2_tll_pads); /* Errata i687: set I/O drive strength to 1 */ if (cpu_is_omap443x()) { val = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_2); val |= OMAP4_USBB2_DR0_DS_MASK; omap4_ctrl_pad_writel(val, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_2); } break; case OMAP_USBHS_PORT_MODE_UNUSED: default: break; } return omap_hwmod_mux_init(pads, pads_cnt); }
int __init omap_devinit_temp_sensor(void) { if (!cpu_is_omap446x() && !cpu_is_omap443x()) return 0; if (cpu_is_omap443x()) { if (omap4_has_mpu_1_2ghz()) return omap_hwmod_for_each_by_class("bandgap", temp_sensor_dev_init, NULL); else return 0; } else return omap_hwmod_for_each_by_class("thermal_sensor", temp_sensor_dev_init, NULL); }
static void omap4_tuna_init_hw_rev(void) { int ret; int i; u32 r; /* Disable weak driver pulldown on usbb2_hsic_strobe */ r = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USBB_HSIC); r &= ~OMAP4_USBB2_HSIC_STROBE_WD_MASK; omap4_ctrl_pad_writel(r, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USBB_HSIC); ret = gpio_request_array(tuna_hw_rev_gpios, ARRAY_SIZE(tuna_hw_rev_gpios)); BUG_ON(ret); for (i = 0; i < ARRAY_SIZE(tuna_hw_rev_gpios); i++) tuna_hw_rev |= gpio_get_value(tuna_hw_rev_gpios[i].gpio) << i; snprintf(omap4_tuna_bd_info_string, ARRAY_SIZE(omap4_tuna_bd_info_string), "Tuna HW revision: %02x (%s), cpu %s ES%d.%d ", tuna_hw_rev, omap4_tuna_hw_rev_name(), cpu_is_omap443x() ? "OMAP4430" : "OMAP4460", (GET_OMAP_REVISION() >> 4) & 0xf, GET_OMAP_REVISION() & 0xf); pr_info("%s\n", omap4_tuna_bd_info_string); mach_panic_string = omap4_tuna_bd_info_string; }
static void omap4_secondary_init(unsigned int cpu) { /* * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA * init and for CPU1, a secure PPA API provided. CPU0 must be ON * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. * OMAP443X GP devices- SMP bit isn't accessible. * OMAP446X GP devices - SMP bit access is enabled on both CPUs. */ if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, 4, 0, 0, 0, 0, 0); /* * Configure the CNTFRQ register for the secondary cpu's which * indicates the frequency of the cpu local timers. */ if (soc_is_omap54xx() || soc_is_dra7xx()) set_cntfreq(); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
void __cpuinit platform_secondary_init(unsigned int cpu) { u32 diag0_errata_flags = 0; /* Enable NS access to SMP bit for this CPU on HS devices */ if (cpu_is_omap446x() || cpu_is_omap443x()) { if (omap_type() != OMAP2_DEVICE_TYPE_GP) omap4_secure_dispatcher(PPA_SERVICE_DEFAULT_POR_NS_SMP, FLAG_START_CRITICAL, 0, 0, 0, 0, 0); else { diag0_errata_flags = omap4_get_diagctrl0_errata_flags(); if (diag0_errata_flags) omap_smc1(HAL_DIAGREG_0, diag0_errata_flags); } } /* * If any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled * for us: do so */ gic_secondary_init(0); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
static void __cpuinit omap4_secondary_init(unsigned int cpu) { /* * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA * init and for CPU1, a secure PPA API provided. CPU0 must be ON * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. * OMAP443X GP devices- SMP bit isn't accessible. * OMAP446X GP devices - SMP bit access is enabled on both CPUs. */ if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, 4, 0, 0, 0, 0, 0); /* * If any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled * for us: do so */ gic_secondary_init(0); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
/** * 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; }
int __init omap_twl4030_init(void) { /* Reuse OMAP3430 values */ if (cpu_is_omap3630()) { omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN; omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX; omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN; omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX; } if (cpu_is_omap446x()) { /* use SMPS1 for CORE instead of SMPS3 on 4430 */ omap_twl_map[1].pmic_data->volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG; omap_twl_map[1].pmic_data->cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG; /* Adjust min / max voltages */ omap_twl_map[0].pmic_data->vp_vddmin = OMAP4460_VP_MPU_VLIMITTO_VDDMIN; omap_twl_map[0].pmic_data->vp_vddmax = OMAP4460_VP_MPU_VLIMITTO_VDDMAX; omap_twl_map[1].pmic_data->vp_vddmin = OMAP4460_VP_CORE_VLIMITTO_VDDMIN; omap_twl_map[1].pmic_data->vp_vddmax = OMAP4460_VP_CORE_VLIMITTO_VDDMAX; omap_twl_map[2].pmic_data->vp_vddmin = OMAP4460_VP_IVA_VLIMITTO_VDDMIN; omap_twl_map[2].pmic_data->vp_vddmax = OMAP4460_VP_IVA_VLIMITTO_VDDMAX; } if (cpu_is_omap34xx()) return omap_pmic_register_data(omap3_twl_map); else if (cpu_is_omap443x()) return omap_pmic_register_data(&omap_twl_map[0]); else if (cpu_is_omap446x()) /* mpu from tps6236x */ return omap_pmic_register_data(&omap_twl_map[1]); else return 0; }
int __init omap_temp_sensor_init(void) { if (!cpu_is_omap443x() || !omap4_has_mpu_1_2ghz()) return 0; return platform_driver_register(&omap_temp_sensor_driver); }
/** * 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; }
void __init omap44xx_voltagedomains_init(void) { struct voltagedomain *voltdm; int i; /* * XXX Will depend on the process, validation, and binning * for the currently-running IC */ #ifdef CONFIG_PM_OPP if (cpu_is_omap443x()) { omap4_voltdm_mpu.volt_data = omap443x_vdd_mpu_volt_data; omap4_voltdm_iva.volt_data = omap443x_vdd_iva_volt_data; omap4_voltdm_core.volt_data = omap443x_vdd_core_volt_data; } else if (cpu_is_omap446x()) { omap4_voltdm_mpu.volt_data = omap446x_vdd_mpu_volt_data; omap4_voltdm_iva.volt_data = omap446x_vdd_iva_volt_data; omap4_voltdm_core.volt_data = omap446x_vdd_core_volt_data; } #endif omap4_voltdm_mpu.vp_param = &omap4_mpu_vp_data; omap4_voltdm_iva.vp_param = &omap4_iva_vp_data; omap4_voltdm_core.vp_param = &omap4_core_vp_data; omap4_voltdm_mpu.vc_param = &omap4_mpu_vc_data; omap4_voltdm_iva.vc_param = &omap4_iva_vc_data; omap4_voltdm_core.vc_param = &omap4_core_vc_data; for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++) voltdm->sys_clk.name = sys_clk_name; voltdm_init(voltagedomains_omap4); };
static int __init omap_init_pmu(void) { unsigned oh_num; char **oh_names; /* * To create an ARM-PMU device the following HWMODs * are required for the various OMAP2+ devices. * * OMAP24xx: mpu * OMAP3xxx: mpu, debugss * OMAP4430: l3_main_3, l3_instr, debugss * OMAP4460/70: mpu, debugss */ if (cpu_is_omap443x()) { oh_num = ARRAY_SIZE(omap4430_pmu_oh_names); oh_names = omap4430_pmu_oh_names; /* XXX Remove the next two lines when CTI driver available */ pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n"); return 0; } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { oh_num = ARRAY_SIZE(omap3_pmu_oh_names); oh_names = omap3_pmu_oh_names; } else { oh_num = ARRAY_SIZE(omap2_pmu_oh_names); oh_names = omap2_pmu_oh_names; } return omap2_init_pmu(oh_num, oh_names); }
/* Smartreflex Class3 init API to be called from board file */ static int __init sr_class3_init(void) { /* Enable this class only for OMAP343x and OMAP443x */ if (!cpu_is_omap343x() && !cpu_is_omap443x()) return -EINVAL; pr_info("SmartReflex Class3 initialized\n"); return sr_register_class(&class3_data); }
static __init int omap4_ldo_trim_init(void) { u32 bgap_trimmed = 0; /* Applicable only for OMAP4 */ if (!cpu_is_omap44xx()) return 0; /* * Some ES2.2 efuse values for BGAP and SLDO trim * are not programmed. For these units * 1. we can set overide mode for SLDO trim, * and program the max multiplication factor, to ensure * high enough voltage on SLDO output. * 2. trim VDAC value for TV output as per recomendation */ if (omap_rev() >= CHIP_IS_OMAP4430ES2_2) bgap_trimmed = omap_ctrl_readl( OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP); bgap_trimmed &= OMAP4_STD_FUSE_OPP_BGAP_MASK_LSB; /* if not trimmed, we set force overide, insted of efuse. */ if (!bgap_trimmed) bgap_trim_sw_overide = true; /* If not already trimmed, use s/w override */ if (cpu_is_omap446x()) omap4460_mpu_dpll_trim_override(); /* * Errata i684 (revision B) * Impacts all OMAP4430ESx.y trimmed and untrimmed excluding units * with with ProdID[51:50]=11 * OMAP4460/70 are not impacted. * * ProdID: * 51 50 * 0 0 Incorrect trim, SW WA needed. * 0 1 Fixed test program issue of overlapping of LPDDR & SmartIO * efuse fields, SW WA needed for LPDDR. * 1 1 New LPDDR trim formula to compensate for vertical vs horizontal * cell layout. No overwrite required. */ if (cpu_is_omap443x()) { u32 prod_id; prod_id = omap_ctrl_readl( OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1); prod_id &= OMAP4_PROD_ID_I684_MASK; if (prod_id != OMAP4_PROD_ID_I684_MASK) ddr_io_trim_override = true; } return omap4_ldo_trim_configure(); }
void __init omap44xx_powerdomains_init(void) { pwrdm_register_platform_funcs(&omap4_pwrdm_operations); pwrdm_register_pwrdms(powerdomains_omap44xx); if (cpu_is_omap443x()) pwrdm_register_pwrdms(powerdomains_omap443x); if (cpu_is_omap446x()) pwrdm_register_pwrdms(powerdomains_omap446x); pwrdm_complete_init(); }
void __init omap44xx_voltagedomains_init(void) { struct voltagedomain *voltdm; int i; omap4_voltdm_mpu.vp->vlimits->vddmax = OMAP4460_VP_MPU_VLIMITTO_VDDMAX; omap4_voltdm_iva.vp->vlimits->vddmax = OMAP4460_VP_IVA_VLIMITTO_VDDMAX; omap4_voltdm_core.vp->vlimits->vddmax = OMAP4460_VP_CORE_VLIMITTO_VDDMAX; /* * XXX Will depend on the process, validation, and binning * for the currently-running IC */ if (cpu_is_omap443x()) { struct setup_time_ramp_params *params = omap4_vc_core.common->setup_time_params; if (params) { params->pre_scaler_to_sysclk_cycles = pre_scaler_to_sysclk_cycles_443x; } omap4_vdd_mpu_info.volt_data = omap443x_vdd_mpu_volt_data; omap4_vdd_iva_info.volt_data = omap443x_vdd_iva_volt_data; omap4_vdd_core_info.volt_data = omap443x_vdd_core_volt_data; omap4_vdd_mpu_info.dep_vdd_info = omap443x_vddmpu_dep_info; omap4_vdd_iva_info.dep_vdd_info = omap443x_vddiva_dep_info; omap4_voltdm_mpu.vp->vlimits->vddmax = OMAP4430_VP_MPU_VLIMITTO_VDDMAX; omap4_voltdm_iva.vp->vlimits->vddmax = OMAP4430_VP_IVA_VLIMITTO_VDDMAX; omap4_voltdm_core.vp->vlimits->vddmax = OMAP4430_VP_CORE_VLIMITTO_VDDMAX; } else if (cpu_is_omap446x()) { omap4_vdd_mpu_info.volt_data = omap446x_vdd_mpu_volt_data; omap4_vdd_iva_info.volt_data = omap446x_vdd_iva_volt_data; omap4_vdd_core_info.volt_data = omap446x_vdd_core_volt_data; omap4_vdd_mpu_info.dep_vdd_info = omap446x_vddmpu_dep_info; omap4_vdd_iva_info.dep_vdd_info = omap446x_vddiva_dep_info; } else if (cpu_is_omap447x()) { omap4_vdd_mpu_info.volt_data = omap447x_vdd_mpu_volt_data; omap4_vdd_iva_info.volt_data = omap447x_vdd_iva_volt_data; omap4_vdd_core_info.volt_data = omap447x_vdd_core_volt_data; omap4_vdd_mpu_info.dep_vdd_info = omap447x_vddmpu_dep_info; omap4_vdd_iva_info.dep_vdd_info = omap447x_vddiva_dep_info; } else { return; } for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++) voltdm->sys_clk.name = sys_clk_name; voltdm_init(voltagedomains_omap4); };
static void omap4_panda_init_rev(void) { if (cpu_is_omap443x()) { /* PandaBoard 4430 */ /* ASoC audio configuration */ panda_abe_audio_data.card_name = "PandaBoard"; panda_abe_audio_data.has_hsmic = 1; } else { /* PandaBoard ES */ /* ASoC audio configuration */ panda_abe_audio_data.card_name = "PandaBoardES"; } }
static void omap4_panda_init_rev(void) { if (cpu_is_omap443x()) { panda_abe_audio_data.card_name = "PandaBoard"; panda_abe_audio_data.has_hsmic = 1; } else { panda_abe_audio_data.card_name = "PandaBoardES"; } }
/* * For kexec, we must set CPU1_WAKEUP_NS_PA_ADDR to point to * current kernel's secondary_startup() early before * clockdomains_init(). Otherwise clockdomain_init() can * wake CPU1 and cause a hang. */ void __init omap4_mpuss_early_init(void) { unsigned long startup_pa; if (!cpu_is_omap44xx()) return; sar_base = omap4_get_sar_ram_base(); if (cpu_is_omap443x()) startup_pa = virt_to_phys(omap4_secondary_startup); else startup_pa = virt_to_phys(omap4460_secondary_startup); writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET); }
int __init omap_twl_init(void) { struct omap_pmic_description *desc = NULL; /* Reuse OMAP3430 values */ if (cpu_is_omap3630()) { omap3_mpu_pmic.min_volt = OMAP3630_VP1_VLIMITTO_VDDMIN; omap3_mpu_pmic.max_volt = OMAP3630_VP1_VLIMITTO_VDDMAX; omap3_core_pmic.min_volt = OMAP3630_VP2_VLIMITTO_VDDMIN; omap3_core_pmic.max_volt = OMAP3630_VP2_VLIMITTO_VDDMAX; } if (cpu_is_omap44xx()) desc = &twl6030_pmic_desc; if (cpu_is_omap443x() && is_twl6030_lite()) { omap443x_core_pmic.volt_reg_addr = TWL6032_SMPS2_SR_VOLT_REG; omap443x_core_pmic.cmd_reg_addr = TWL6032_SMPS2_SR_CMD_REG; omap443x_446x_iva_pmic.volt_reg_addr = TWL6032_SMPS5_SR_VOLT_REG; omap443x_446x_iva_pmic.cmd_reg_addr = TWL6032_SMPS5_SR_CMD_REG; pr_info("%s: TWL6032 PMIC SR Addr Change Success!!\n", __func__); } if (cpu_is_omap446x() && is_twl6030_lite()) { omap446x_core_pmic.volt_reg_addr = TWL6032_SMPS2_SR_VOLT_REG; omap446x_core_pmic.cmd_reg_addr = TWL6032_SMPS2_SR_CMD_REG; omap443x_446x_iva_pmic.volt_reg_addr = TWL6032_SMPS5_SR_VOLT_REG; omap443x_446x_iva_pmic.cmd_reg_addr = TWL6032_SMPS5_SR_CMD_REG; pr_info("%s: TWL6032 PMIC SR Addr Change Success!!\n", __func__); } return omap_pmic_register_data(omap_twl_map, desc); }
/** * omap4_ldo_trim_configure() - Handle device trim variance * * Few of the silicon out of the fab come out without trim parameters * efused in. These need some software support to allow the device to * function normally. Handle these silicon quirks here. */ int omap4_ldo_trim_configure(void) { u32 val; /* if not trimmed, we set force overide, insted of efuse. */ if (bgap_trim_sw_overide) { /* Fill in recommended values */ val = 0x0f << OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_SHIFT; val |= OMAP4_LDOSRAMCORE_ACTMODE_MUX_CTRL_MASK; val |= 0x1 << OMAP4_LDOSRAMCORE_RETMODE_VSET_OUT_SHIFT; val |= OMAP4_LDOSRAMCORE_RETMODE_MUX_CTRL_MASK; omap_ctrl_writel(val, OMAP4_CTRL_MODULE_CORE_LDOSRAM_MPU_VOLTAGE_CTRL); omap_ctrl_writel(val, OMAP4_CTRL_MODULE_CORE_LDOSRAM_CORE_VOLTAGE_CTRL); omap_ctrl_writel(val, OMAP4_CTRL_MODULE_CORE_LDOSRAM_IVA_VOLTAGE_CTRL); } /* OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_1 is reserved for 4470 */ /* FIXME: original code is: if (!cpu_is_omap447x()) */ if (cpu_is_omap443x() || cpu_is_omap446x()) { /* For all trimmed and untrimmed write recommended value */ val = 0x10 << OMAP4_AVDAC_TRIM_BYTE0_SHIFT; val |= 0x01 << OMAP4_AVDAC_TRIM_BYTE1_SHIFT; val |= 0x4d << OMAP4_AVDAC_TRIM_BYTE2_SHIFT; val |= 0x1C << OMAP4_AVDAC_TRIM_BYTE3_SHIFT; omap4_ctrl_pad_writel(val, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_1); } /* DDR I/O Trim override as per erratum i684 */ if (ddr_io_trim_override) { omap4_ctrl_pad_writel(OMAP4_LPDDR2_I684_FIX_VALUE, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_2); } /* Required for DPLL_MPU to lock at 2.4 GHz */ if (dpll_trim_override) omap_ctrl_writel(0x29, OMAP4_CTRL_MODULE_CORE_DPLL_NWELL_TRIM_0); return 0; }
static void omap4_secondary_init(unsigned int cpu) { /* * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA * init and for CPU1, a secure PPA API provided. CPU0 must be ON * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. * OMAP443X GP devices- SMP bit isn't accessible. * OMAP446X GP devices - SMP bit access is enabled on both CPUs. */ if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, 4, 0, 0, 0, 0, 0); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
static int __init omap4_duty_governor_init(void) { if (!cpu_is_omap443x()) return 0; t_governor = kzalloc(sizeof(struct duty_governor), GFP_KERNEL); if (IS_ERR_OR_NULL(t_governor)) { pr_err("%s:Cannot allocate memory\n", __func__); return -ENOMEM; } t_governor->period = NORMAL_MONITORING_RATE; t_governor->previous_temp = DEFAULT_TEMPERATURE; t_governor->tpcb_sections = pcb_sections; t_governor->npcb_sections = pcb_sections_size; t_governor->working_section = INIT_SECTION; INIT_DELAYED_WORK(&t_governor->duty_cycle_governor_work, omap4_duty_governor_delayed_work_fn); return 0; }
/** * 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) { omap4_opp_enable("mpu", 1200000000); omap4_opp_enable("mpu", 1350000000); omap4_opp_enable("mpu", 1520000000); omap4_opp_enable("mpu", 1650000000); } 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); omap4_mpu_opp_enable(1350000000); /* The tuna PCB doesn't support 1.5GHz, so disable it for now */ /*if (omap4_has_mpu_1_5ghz()) 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); /* 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; }
void gic_dist_enable(void) { if (cpu_is_omap443x() || gic_dist_disabled()) __raw_writel(0x1, gic_dist_base_addr + GIC_DIST_CTRL); }
static struct omap_hwmod_mux_info * __init setup_4430_usbhs_io_mux(struct platform_device *pdev, const enum usbhs_omap_port_mode *port_mode) { const struct omap_device_pad *pads[OMAP3_HS_USB_PORTS]; int pads_cnt[OMAP3_HS_USB_PORTS]; switch (port_mode[0]) { case OMAP_EHCI_PORT_MODE_PHY: pads[0] = port1_phy_pads; pads_cnt[0] = ARRAY_SIZE(port1_phy_pads); break; case OMAP_EHCI_PORT_MODE_TLL: pads[0] = port1_tll_pads; pads_cnt[0] = ARRAY_SIZE(port1_tll_pads); /* Errata i687: set I/O drive strength to 1 */ if (cpu_is_omap443x()) { u32 val; val = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_2); val |= OMAP4_USBB1_DR0_DS_MASK; omap4_ctrl_pad_writel(val, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_2); } break; case OMAP_EHCI_PORT_MODE_HSIC: pads[0] = port1_hsic_pads; pads_cnt[0] = ARRAY_SIZE(port1_hsic_pads); break; case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: pads[0] = port1_6pin_pads; pads_cnt[0] = ARRAY_SIZE(port1_6pin_pads); break; case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: pads[0] = port1_4pin_pads; pads_cnt[0] = ARRAY_SIZE(port1_4pin_pads); break; case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: pads[0] = port1_3pin_pads; pads_cnt[0] = ARRAY_SIZE(port1_3pin_pads); break; case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: pads[0] = port1_2pin_pads; pads_cnt[0] = ARRAY_SIZE(port1_2pin_pads); break; case OMAP_USBHS_PORT_MODE_UNUSED: default: pads_cnt[0] = 0; break; } switch (port_mode[1]) { case OMAP_EHCI_PORT_MODE_PHY: pads[1] = port2_phy_pads; pads_cnt[1] = ARRAY_SIZE(port2_phy_pads); break; case OMAP_EHCI_PORT_MODE_TLL: pads[1] = port2_tll_pads; pads_cnt[1] = ARRAY_SIZE(port2_tll_pads); /* Errata i687: set I/O drive strength to 1 */ if (cpu_is_omap443x()) { u32 val; val = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_2); val |= OMAP4_USBB2_DR0_DS_MASK; omap4_ctrl_pad_writel(val, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_2); } break; case OMAP_EHCI_PORT_MODE_HSIC: pads[1] = port2_hsic_pads; pads_cnt[1] = ARRAY_SIZE(port2_hsic_pads); break; case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: pads[1] = port2_6pin_pads; pads_cnt[1] = ARRAY_SIZE(port2_6pin_pads); break; case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: pads[1] = port2_4pin_pads; pads_cnt[1] = ARRAY_SIZE(port2_4pin_pads); break; case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: pads[1] = port2_3pin_pads; pads_cnt[1] = ARRAY_SIZE(port2_3pin_pads); break; case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: pads[1] = port2_2pin_pads; pads_cnt[1] = ARRAY_SIZE(port2_3pin_pads); break; case OMAP_USBHS_PORT_MODE_UNUSED: default: pads_cnt[1] = 0; break; } switch (port_mode[2]) { case OMAP_EHCI_PORT_MODE_HSIC: pads[2] = port3_hsic_pads; pads_cnt[2] = ARRAY_SIZE(port3_hsic_pads); break; case OMAP_USBHS_PORT_MODE_UNUSED: default: pads_cnt[2] = 0; break; } return omap_hwmod_mux_array_init(pdev, pads, pads_cnt, port_mode); }
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { static struct clockdomain *cpu1_clkdm; static bool booted; /* * Set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * Update the AuxCoreBoot0 with boot state for secondary core. * omap_secondary_startup() routine will hold the secondary core till * the AuxCoreBoot1 register is updated with cpu state * A barrier is added to ensure that write buffer is drained */ omap_modify_auxcoreboot0(0x200, 0xfffffdff); flush_cache_all(); smp_wmb(); if (!cpu1_clkdm) cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); /* * The SGI(Software Generated Interrupts) are not wakeup capable * from low power states. This is known limitation on OMAP4 and * needs to be worked around by using software forced clockdomain * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to * software force wakeup. After the wakeup, CPU1 restores its * clockdomain hardware supervised mode. * More details can be found in OMAP4430 TRM - Version J * Section : * 4.3.4.2 Power States of CPU0 and CPU1 */ if (booted) { /* * GIC distributor control register has changed between * CortexA9 r1pX and r2pX. The Control Register secure * banked version is now composed of 2 bits: * bit 0 == Secure Enable * bit 1 == Non-Secure Enable * The Non-Secure banked register has not changed * Because the ROM Code is based on the r1pX GIC, the CPU1 * GIC restoration will cause a problem to CPU0 Non-Secure SW. * The workaround must be: * 1) Before doing the CPU1 wakeup, CPU0 must disable * the GIC distributor * 2) CPU1 must re-enable the GIC distributor on * it's wakeup path. */ if (!cpu_is_omap443x()) { local_irq_disable(); gic_dist_disable(); } clkdm_wakeup(cpu1_clkdm); if (!cpu_is_omap443x()) { while (gic_dist_disabled()) { udelay(1); cpu_relax(); } gic_timer_retrigger(); local_irq_enable(); } } else { clkdm_init_mpu1(cpu1_clkdm); dsb_sev(); booted = true; } /* * Now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return 0; }
static int omap_i2c_init(struct omap_i2c_dev *dev) { u16 psc = 0, scll = 0, sclh = 0, buf = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 12000000; unsigned long internal_clk = 0; struct clk *fclk; if (dev->rev >= OMAP_I2C_REV_ON_3430) { /* * Enabling all wakup sources to stop I2C freezing on * WFI instruction. * REVISIT: Some wkup sources might not be needed. */ dev->westate = OMAP_I2C_WE_ALL; omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); } omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (cpu_class_is_omap1()) { /* * The I2C functional clock is the armxor_ck, so there's * no need to get "armxor_ck" separately. Now, if OMAP2420 * always returns 12MHz for the functional clock, we can * do this bit unconditionally. */ fclk = clk_get(dev->dev, "fck"); fclk_rate = clk_get_rate(fclk); clk_put(fclk); /* TRM for 5912 says the I2C clock must be prescaled to be * between 7 - 12 MHz. The XOR input clock is typically * 12, 13 or 19.2 MHz. So we should have code that produces: * * XOR MHz Divider Prescaler * 12 1 0 * 13 2 1 * 19.2 2 1 */ if (fclk_rate > 12000000) psc = fclk_rate / 12000000; } if (!(cpu_class_is_omap1() || cpu_is_omap2420())) { /* * HSI2C controller internal clk rate should be 19.2 Mhz for * HS and for all modes on 2430. On 34xx we can use lower rate * to get longer filter period for better noise suppression. * The filter is iclk (fclk for HS) period. */ if (dev->speed > 400 || cpu_is_omap2430()) internal_clk = 19200; else if (dev->speed > 100) internal_clk = 9600; else internal_clk = 4000; fclk = clk_get(dev->dev, "fck"); fclk_rate = clk_get_rate(fclk) / 1000; clk_put(fclk); /* Compute prescaler divisor */ psc = fclk_rate / internal_clk; psc = psc - 1; /* If configured for High Speed */ if (dev->speed > 400) { unsigned long scl; /* For first phase of HS mode */ scl = internal_clk / 400; fsscll = scl - (scl / 3) - 7; fssclh = (scl / 3) - 5; /* For second phase of HS mode */ scl = fclk_rate / dev->speed; hsscll = scl - (scl / 3) - 7; hssclh = (scl / 3) - 5; } else if (dev->speed > 100) { unsigned long scl; /* Fast mode */ scl = internal_clk / dev->speed; fsscll = scl - (scl / 3) - 7; fssclh = (scl / 3) - 5; } else { /* Standard mode */ fsscll = internal_clk / (dev->speed * 2) - 7; fssclh = internal_clk / (dev->speed * 2) - 5; } scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll; sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh; } else { /* Program desired operating rate */ fclk_rate /= (psc + 1) * 1000; if (psc > 2) psc = 2; scll = fclk_rate / (dev->speed * 2) - 7 + psc; sclh = fclk_rate / (dev->speed * 2) - 7 + psc; } /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); /* SCL low and high time values */ if ((cpu_is_omap443x()) && ((unsigned int)dev->base == 0xfa070000)) { omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, 0xC); omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, 0x6); } else { omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); } if (dev->fifo_size) { /* Note: setup required fifo size - 1. RTRSH and XTRSH */ buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR | (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR; omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); } /* Take the I2C module out of reset: */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); dev->errata = 0; if (cpu_is_omap2430() || cpu_is_omap34xx()) dev->errata |= I2C_OMAP_ERRATA_I207; if (cpu_is_omap34xx() || cpu_is_omap44xx()) { dev->pscstate = psc; if ((cpu_is_omap443x()) && ((int)dev->base == 0xfa070000)) { dev->scllstate = 0xC; dev->sclhstate = 0x6; } else { dev->scllstate = scll; dev->sclhstate = sclh; } dev->bufstate = buf; } return 0; }