static int __init tmp102_init(void)
{
	if (!cpu_is_omap447x())
		return 0;

	return i2c_add_driver(&tmp102_driver);
}
static ssize_t omap_set_thermal_hw_reset(struct device *dev,
				 struct device_attribute *devattr,
				 const char *buf, size_t count)
{
	u32 reg_val;
	long val;

	if (!cpu_is_omap447x()) {
		pr_err("Not available\n");
		count = -EINVAL;
		goto out;
	} else if (strict_strtol(buf, 10, &val)) {
		count = -EINVAL;
		goto out;
	}

	reg_val = omap4_ctrl_wk_pad_readl(\
		OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_RW);

	if (val == 0)
		reg_val &= ~OMAP4_HW_TSHUT_MASK;
	else
		reg_val |= OMAP4_HW_TSHUT_MASK;

	omap4_ctrl_wk_pad_writel(reg_val,
		OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_RW);
out:
	return count;
}
int __init omap_temp_sensor_init(void)
{
	if (!cpu_is_omap446x() && !cpu_is_omap447x())
		return 0;

	return platform_driver_register(&omap_temp_sensor_driver);
}
예제 #4
0
int __init gcxxx_init(void)
{
	int retval = 0;
	struct omap_hwmod *oh;
	struct omap_device *od;
	const char *oh_name = "bb2d";
	const char *dev_name = "gccore";

	if (!cpu_is_omap447x())
		return retval;

	/*
	 * Hwmod lookup will fail in case our platform doesn't support the
	 * hardware spinlock module, so it is safe to run this initcall
	 * on all omaps
	 */
	oh = omap_hwmod_lookup(oh_name);
	if (oh == NULL)
		return -EINVAL;

	od = omap_device_build(dev_name, 0, oh, &omap_gcxxx,
				sizeof(omap_gcxxx), omap_gcxxx_latency,
				ARRAY_SIZE(omap_gcxxx_latency), false);
	if (IS_ERR(od)) {
		pr_err("Can't build omap_device for %s:%s\n", dev_name,
								oh_name);
		retval = PTR_ERR(od);
	}

	return retval;
}
static int __init tmp102_init(void)
{
#ifndef CONFIG_MACH_OMAP4_JET
	if (!cpu_is_omap447x())
		return 0;
#endif
	return i2c_add_driver(&tmp102_driver);
}
int __init omap_devinit_temp_sensor(void)
{
	if (!cpu_is_omap446x() && !cpu_is_omap447x())
		return 0;

	return omap_hwmod_for_each_by_class("thermal_sensor",
			temp_sensor_dev_init, NULL);
}
static int __init omap_die_governor_init(void)
{
	struct thermal_dev *thermal_fw;

	omap_gov = kzalloc(sizeof(struct omap_die_governor), GFP_KERNEL);
	if (!omap_gov) {
		pr_err("%s:Cannot allocate memory\n", __func__);
		return -ENOMEM;
	}

	thermal_fw = kzalloc(sizeof(struct thermal_dev), GFP_KERNEL);
	if (thermal_fw) {
		thermal_fw->name = "omap_ondie_governor";
		thermal_fw->domain_name = "cpu";
		thermal_fw->dev_ops = &omap_gov_ops;
		thermal_governor_dev_register(thermal_fw);
		therm_fw = thermal_fw;
	} else {
		pr_err("%s: Cannot allocate memory\n", __func__);
		kfree(omap_gov);
		return -ENOMEM;
	}

	if (cpu_is_omap446x()) {
		omap_gov->gradient_slope = OMAP_GRADIENT_SLOPE_4460;
		omap_gov->gradient_const = OMAP_GRADIENT_CONST_4460;
		omap_gov->gradient_slope_w_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4460;
		omap_gov->gradient_const_w_pcb = OMAP_GRADIENT_CONST_W_PCB_4460;
	} else if (cpu_is_omap447x()) {
		omap_gov->gradient_slope = OMAP_GRADIENT_SLOPE_4470;
		omap_gov->gradient_const = OMAP_GRADIENT_CONST_4470;
		omap_gov->gradient_slope_w_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4470;
		omap_gov->gradient_const_w_pcb = OMAP_GRADIENT_CONST_W_PCB_4470;
	} else {
		omap_gov->gradient_slope = 0;
		omap_gov->gradient_const = 0;
		omap_gov->gradient_slope_w_pcb = 0;
		omap_gov->gradient_const_w_pcb = 0;
	}

	/* Init delayed work to average on-die temperature */
	INIT_DELAYED_WORK(&omap_gov->average_cpu_sensor_work,
			  average_cpu_sensor_delayed_work_fn);
	INIT_DELAYED_WORK(&omap_gov->decrease_mpu_freq_work,
			  decrease_mpu_freq_fn);

	omap_gov->average_period = NORMAL_TEMP_MONITORING_RATE;
	omap_gov->decrease_mpu_freq_period = DECREASE_MPU_FREQ_PERIOD;
	omap_gov->avg_is_valid = 0;

	if (register_pm_notifier(&omap_die_pm_notifier))
		pr_err("%s: omap_die pm registration failed!\n", __func__);

	schedule_delayed_work(&omap_gov->average_cpu_sensor_work,
			msecs_to_jiffies(0));

	return 0;
}
void omap_temp_sensor_idle(int idle_state)
{
	if (!cpu_is_omap446x() && !cpu_is_omap447x())
		return;

	if (idle_state)
		omap_temp_sensor_disable(temp_sensor_pm);
	else
		omap_temp_sensor_enable(temp_sensor_pm);
}
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);
};
예제 #10
0
/*
 * Continue initialise the wakeupgen initialization after sar
 * is initialized
 */
void __init omap_wakeupgen_init_finish(void)
{
	int i;
	unsigned int max_spi_reg;
	/*
	 * Find out how many interrupts are supported.
	 * OMAP4 supports max of 128 SPIs where as GIC can support
	 * up to 1020 interrupt sources. On OMAP4, maximum SPIs are
	 * fused in DIST_CTR bit-fields as 128. Hence the code is safe
	 * from reserved register writes since its well within 1020.
	 */
	max_spi_reg = gic_readl(GIC_DIST_CTR, 0) & 0x1f;

	/*
	 * Set CPU0 GIC backup flag permanently for omap4460/70 GP,
	 * this is needed because of the ROM code bug that breaks
	 * GIC during wakeup from device off. This errata fix also
	 * clears the GIC save area during init to prevent restoring
	 * garbage to the GIC.
	 */
	if ((cpu_is_omap446x() || cpu_is_omap447x()) &&
	    omap_type() == OMAP2_DEVICE_TYPE_GP)
		pm44xx_errata |= PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx;

	if (cpu_is_omap44xx() && (omap_type() == OMAP2_DEVICE_TYPE_GP)) {
		sar_base = omap4_get_sar_ram_base();

		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx))
			for (i = SAR_BACKUP_STATUS_OFFSET;
			     i < WAKEUPGENENB_OFFSET_CPU0; i += 4)
				sar_writel(0, i, 0);

		sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_CPU0_OFFSET, 0);
		sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_CPU1_OFFSET, 0);
		for (i = 0; i < max_spi_reg; i++)
			sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_SPI_OFFSET,
				   i);

		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx))
			__raw_writel(SAR_BACKUP_STATUS_GIC_CPU0,
				     sar_base + SAR_BACKUP_STATUS_OFFSET);

	} else {
		l3_main_3_oh = omap_hwmod_lookup("l3_main_3");
		if (!l3_main_3_oh)
			pr_err("%s: failed to get l3_main_3_oh\n", __func__);
	}
}
예제 #11
0
static void __init tablet_camera_mux_init(void)
{
	u32 r = 0;

	/* Enable CSI22 pads for 4460 and 4470*/
	if ((cpu_is_omap446x() || cpu_is_omap447x()) &&
		(omap_get_board_version() >= OMAP4_TABLET_2_0)) {
		r = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX);
		r |= (0x7 << OMAP4_CAMERARX_CSI22_LANEENABLE_SHIFT);
		omap4_ctrl_pad_writel(r,
			OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX);

		omap_mux_init_signal("csi22_dx2.csi22_dx2",
				OMAP_PIN_INPUT | OMAP_MUX_MODE0);
		omap_mux_init_signal("csi22_dy2.csi22_dy2",
				OMAP_PIN_INPUT | OMAP_MUX_MODE0);
	}
}
예제 #12
0
/**
 * omap4_trim_configure() - Handle device trim variance for omap4
 */
int omap4_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 */
	if (!cpu_is_omap447x()) {
		/* 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;
}
예제 #13
0
static int __init gc_init(void)
{
	/* check if hardware is available */
	if (!cpu_is_omap447x())
		return 0;

	/* Initialize context mutex. */
	mutex_init(&mtx);

	/* Initialize interrupt completion. */
	init_completion(&g_gccoreint);

	g_bb2d_dev = omap_hwmod_name_get_dev("bb2d");
	if (g_bb2d_dev == NULL) {
		GCPRINT(NULL, 0, GC_MOD_PREFIX
			"cannot find bb2d_fck.\n",
			 __func__, __LINE__);
		goto fail;
	}

	/* Initialize the command buffer. */
	if (cmdbuf_init() != GCERR_NONE) {
		GCPRINT(NULL, 0, GC_MOD_PREFIX
			"failed to initialize command buffer.\n",
			 __func__, __LINE__);
		goto fail;
	}

	/* Create debugfs entry */
	g_debugRoot = debugfs_create_dir("gcx", NULL);
	if (g_debugRoot)
		gc_debug_init(g_debugRoot);

	mutex_init(&g_maplock);

#if defined(CONFIG_HAS_EARLYSUSPEND)
	register_early_suspend(&early_suspend_info);
#endif

	return platform_driver_register(&plat_drv);
fail:

	return -EINVAL;
}
static void omap_configure_temp_sensor_thresholds(struct omap_temp_sensor
						  *temp_sensor)
{
	u32 temp = 0, t_hot, t_cold, tshut_hot, tshut_cold;

	t_hot = temp_to_adc_conversion(BGAP_THRESHOLD_T_HOT);
	t_cold = temp_to_adc_conversion(BGAP_THRESHOLD_T_COLD);

	if ((t_hot == -EINVAL) || (t_cold == -EINVAL)) {
		pr_err("%s:Temp thresholds out of bounds\n", __func__);
		return;
	}
	temp = ((t_hot << OMAP4_T_HOT_SHIFT) | (t_cold << OMAP4_T_COLD_SHIFT));
	omap_temp_sensor_writel(temp_sensor, temp, BGAP_THRESHOLD_OFFSET);

	/*
	 * Prevent multiple writing to one time writable register, assuming
	 * that no one wrote zero into it before.
	 */

	if (cpu_is_omap447x() &&
		omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET) != 0) {
		pr_debug("%s:Shutdown thresholds are already set\n", __func__);
		return;
	}

	tshut_hot = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_HOT);
	tshut_cold = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_COLD);
	if ((tshut_hot == -EINVAL) || (tshut_cold == -EINVAL)) {
		pr_err("%s:Temp shutdown thresholds out of bounds\n", __func__);
		return;
	}
	temp = ((tshut_hot << OMAP4_TSHUT_HOT_SHIFT)
			| (tshut_cold << OMAP4_TSHUT_COLD_SHIFT));
	omap_temp_sensor_writel(temp_sensor, temp, BGAP_TSHUT_OFFSET);

	if (omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET) != temp)
		pr_err("%s:Shutdown thresholds can't be set\n", __func__);
}
예제 #15
0
static void __exit gc_exit(void)
{
	if (!cpu_is_omap447x())
		return;

	platform_driver_unregister(&plat_drv);
#if defined(CONFIG_HAS_EARLYSUSPEND)
	unregister_early_suspend(&early_suspend_info);
#endif
	delete_context_map();
	mutex_destroy(&g_maplock);
	gc_set_power(GCPWR_OFF);

	pm_runtime_disable(gcdevice.dev);

	if (g_debugRoot)
		debugfs_remove_recursive(g_debugRoot);

	mutex_destroy(&mtx);

	if (g_irqinstalled)
		free_irq(gcirq, &gcdevice);
}
예제 #16
0
static void __init omap_tablet_init(void)
{
	int status;
	int package = OMAP_PACKAGE_CBS;
	int tablet_rev = 0;

	if (omap_rev() == OMAP4430_REV_ES1_0)
		package = OMAP_PACKAGE_CBL;
	omap4_mux_init(board_mux, NULL, package);

	if (cpu_is_omap447x())
		omap_emif_setup_device_details(&emif_devices_4470,
					       &emif_devices_4470);
	else
		omap_emif_setup_device_details(&emif_devices, &emif_devices);

	omap_board_config = tablet_config;
	omap_board_config_size = ARRAY_SIZE(tablet_config);
	tablet_rev = omap_init_board_version(0);
	omap4_create_board_props();
	omap4_audio_conf();
	omap4_i2c_init();
	tablet_touch_init();
	tablet_camera_mux_init();
	omap_dmm_init();
	tablet_panel_init();
	tablet_pmic_mux_init();
	tablet_set_osc_timings();
	tablet_button_init();
	omap4_register_ion();
	board_serial_init();
	omap4_tablet_wifi_init();
	omap4_twl6030_hsmmc_init(mmc);
	tablet_sensor_init();
	platform_add_devices(tablet4430_devices,
			ARRAY_SIZE(tablet4430_devices));
	wake_lock_init(&st_wk_lock, WAKE_LOCK_SUSPEND, "st_wake_lock");
	omap4_ehci_ohci_init();
	usb_musb_init(&musb_board_data);

	status = omap_ethernet_init();
	if (status) {
		pr_err("Ethernet initialization failed: %d\n", status);
	} else {
		tablet_spi_board_info[0].irq = gpio_to_irq(ETH_KS8851_IRQ);
		spi_register_board_info(tablet_spi_board_info,
				ARRAY_SIZE(tablet_spi_board_info));
	}

	if (cpu_is_omap446x()) {
		/* Vsel0 = gpio, vsel1 = gnd */
		status = omap_tps6236x_board_setup(true, TPS62361_GPIO, -1,
					OMAP_PIN_OFF_OUTPUT_HIGH, -1);
		if (status)
			pr_err("TPS62361 initialization failed: %d\n", status);
	}

	omap_enable_smartreflex_on_init();
	if (enable_suspend_off)
		omap_pm_enable_off_mode();

}
예제 #17
0
int omap4460_mpu_dpll_set_rate(struct clk *clk, unsigned long rate)
{
	struct dpll_data *dd;
	u32 v;
	unsigned long dpll_rate;

	if (!clk || !rate || !clk->parent)
		return -EINVAL;

	dd = clk->parent->dpll_data;

	if (!dd)
		return -EINVAL;

	if (!clk->parent->set_rate)
		return -EINVAL;

	if (rate > clk->rate)
		omap4460_mpu_dpll_update_children(rate);

	/*
	 * To obtain MPU DPLL frequency higher than 1GHz, On OMAP4470,
	 * DCC (Duty Cycle Correction) needs to be enabled.
	 * And needs to be kept disabled for < 1 Ghz.
	 *
	 * OMAP4460 has a HW issue with DCC so until proper WA is found
	 * DCC shouldn't be used at any frequency.
	 */
	dpll_rate = omap2_get_dpll_rate(clk->parent);
	if (!cpu_is_omap447x() || rate <= OMAP_1GHz) {
		/* If DCC is enabled, disable it */
		v = __raw_readl(dd->mult_div1_reg);
		if (v & OMAP4460_DCC_EN_MASK) {
			v &= ~OMAP4460_DCC_EN_MASK;
			__raw_writel(v, dd->mult_div1_reg);
		}

		if (rate != dpll_rate)
			clk->parent->set_rate(clk->parent, rate);
	} else {
		/*
		 * On OMAP4470, the MPU clk for frequencies higher than 1Ghz
		 * is sourced from CLKOUTX2_M3, instead of CLKOUT_M2, while
		 * value of M3 is fixed to 1. Hence for frequencies higher
		 * than 1 Ghz, lock the DPLL at half the rate so the
		 * CLKOUTX2_M3 then matches the requested rate.
		 */
		if (rate != dpll_rate * 2)
			clk->parent->set_rate(clk->parent, rate / 2);

		v = __raw_readl(dd->mult_div1_reg);
		v &= ~OMAP4460_DCC_COUNT_MAX_MASK;
		v |= (5 << OMAP4460_DCC_COUNT_MAX_SHIFT);
		__raw_writel(v, dd->mult_div1_reg);

		v |= OMAP4460_DCC_EN_MASK;
		__raw_writel(v, dd->mult_div1_reg);
	}

	if (rate < clk->rate)
		omap4460_mpu_dpll_update_children(rate);

	clk->rate = rate;

	return 0;
}