Exemplo n.º 1
0
/**
 * omap_device_set_rate - Set a new rate at which the device is to operate
 * @req_dev : pointer to the device requesting the scaling.
 * @dev : pointer to the device that is to be scaled
 * @rate : the rnew rate for the device.
 *
 * This API gets the device opp table associated with this device and
 * tries putting the device to the requested rate and the voltage domain
 * associated with the device to the voltage corresponding to the
 * requested rate. Since multiple devices can be assocciated with a
 * voltage domain this API finds out the possible voltage the
 * voltage domain can enter and then decides on the final device
 * rate. Return 0 on success else the error value
 */
int omap_device_set_rate(struct device *req_dev, struct device *dev,
			unsigned long rate)
{
	struct omap_opp *opp;
	unsigned long volt, freq, min_freq, max_freq, flags;
	struct voltagedomain *voltdm;
	struct platform_device *pdev;
	struct omap_device *od;
	int ret;

	pdev = container_of(dev, struct platform_device, dev);
	od = _find_by_pdev(pdev);

	/* if in low power DPLL cascading mode, bail out early */
	if (cpu_is_omap44xx()) {
		read_lock_irqsave(&dpll_cascading_lock, flags);

		if (in_dpll_cascading) {
			ret = -EINVAL;
			goto out;
		}
	}

	/*
	 * Figure out if the desired frquency lies between the
	 * maximum and minimum possible for the particular device
	 */
	min_freq = 0;
	if (IS_ERR(opp_find_freq_ceil(dev, &min_freq))) {
		dev_err(dev, "%s: Unable to find lowest opp\n", __func__);
		ret = -ENODEV;
		goto out;
	}

	max_freq = ULONG_MAX;
	if (IS_ERR(opp_find_freq_floor(dev, &max_freq))) {
		dev_err(dev, "%s: Unable to find highest opp\n", __func__);
		ret = -ENODEV;
		goto out;
	}

	if (rate < min_freq)
		freq = min_freq;
	else if (rate > max_freq)
		freq = max_freq;
	else
		freq = rate;

	/* Get the possible rate from the opp layer */
	opp = opp_find_freq_ceil(dev, &freq);
	if (IS_ERR(opp)) {
		dev_dbg(dev, "%s: Unable to find OPP for freq%ld\n",
			__func__, rate);
		ret = -ENODEV;
		goto out;
	}
	if (unlikely(freq != rate))
		dev_dbg(dev, "%s: Available freq %ld != dpll freq %ld.\n",
			__func__, freq, rate);

	/* Get the voltage corresponding to the requested frequency */
	volt = opp_get_voltage(opp);

	/*
	 * Call into the voltage layer to get the final voltage possible
	 * for the voltage domain associated with the device.
	 */
	voltdm = od->hwmods[0]->voltdm;
	ret = omap_voltage_add_userreq(voltdm, req_dev, &volt);
	if (ret) {
		dev_err(dev, "%s: Unable to get the final volt for scaling\n",
			__func__);
		goto out;
	}

	/* Do the actual scaling */
	ret =  omap_voltage_scale(voltdm);
out:
	if (cpu_is_omap44xx())
		read_unlock_irqrestore(&dpll_cascading_lock, flags);

	return ret;
}
Exemplo n.º 2
0
/**
 * omap_serial_init_port() - initialize single serial port
 * @bdata: port specific board data pointer
 * @info: platform specific data pointer
 *
 * This function initialies serial driver for given port only.
 * Platforms can call this function instead of omap_serial_init()
 * if they don't plan to use all available UARTs as serial ports.
 *
 * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
 * use only one of the two.
 */
void __init omap_serial_init_port(struct omap_board_data *bdata,
			struct omap_uart_port_info *info)
{
	struct omap_hwmod *oh;
	struct omap_device *od;
	struct omap_uart_port_info *pdata;
	char *name = DRIVER_NAME;

	if (WARN_ON(!bdata))
		return;
	if (WARN_ON(bdata->id < 0))
		return;
	if (WARN_ON(bdata->id >= OMAP_MAX_HSUART_PORTS))
		return;

	oh = omap_uart_hwmod_lookup(bdata->id);
	if (!oh)
		return;

	if (info == NULL)
		info = omap_serial_default_info;

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		pr_err("Memory allocation for UART pdata failed\n");
		return;
	}

	if (cpu_is_omap34xx() || cpu_is_omap44xx())
		pdata->errata |= UART_ERRATA_i202_MDR1_ACCESS;

	omap_uart_idle_init(pdata, bdata->id);

	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
	pdata->flags = UPF_BOOT_AUTOCONF;
	pdata->enable_wakeup = omap_uart_wakeup_enable;
	pdata->use_dma = info->use_dma;
	pdata->chk_wakeup = omap_uart_chk_wakeup;
	pdata->dma_rx_buf_size = info->dma_rx_buf_size;
	pdata->dma_rx_poll_rate = info->dma_rx_poll_rate;
	pdata->dma_rx_timeout = info->dma_rx_timeout;
	pdata->auto_sus_timeout = info->auto_sus_timeout;
	pdata->wake_peer = info->wake_peer;
	pdata->rts_mux_driver_control = info->rts_mux_driver_control;
        pdata->wer = info->wer;
	if (bdata->id == omap_uart_con_id) {
		pdata->console_uart = true;
#ifdef CONFIG_DEBUG_LL
		pdata->auto_sus_timeout = -1;
#endif
	}

	if (pdata->use_dma &&
			cpu_is_omap44xx() && omap_rev() > OMAP4430_REV_ES1_0)
		pdata->errata |= OMAP4_UART_ERRATA_i659_TX_THR;

	od = omap_device_build(name, bdata->id, oh, pdata,
				sizeof(*pdata), omap_uart_latency,
				ARRAY_SIZE(omap_uart_latency), false);
	WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
	     name, oh->name);

	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);

	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) ||
	    (pdata->wk_en && pdata->wk_mask)) {
		device_init_wakeup(&od->pdev.dev, true);
	}

	kfree(pdata);
}
Exemplo n.º 3
0
/**
 * omap3_noncore_dpll_set_rate - set non-core DPLL rate
 * @clk: struct clk * of DPLL to set
 * @rate: rounded target rate
 *
 * Set the DPLL CLKOUT to the target rate.  If the DPLL can enter
 * low-power bypass, and the target rate is the bypass source clock
 * rate, then configure the DPLL for bypass.  Otherwise, round the
 * target rate if it hasn't been done already, then program and lock
 * the DPLL.  Returns -EINVAL upon error, or 0 upon success.
 */
int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
{
	struct clk *new_parent = NULL;
	u16 freqsel = 0;
	struct dpll_data *dd;
	int ret;

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

	dd = clk->dpll_data;
	if (!dd)
		return -EINVAL;

	if (rate == omap2_get_dpll_rate(clk))
		return 0;

	/*
	 * Ensure both the bypass and ref clocks are enabled prior to
	 * doing anything; we need the bypass clock running to reprogram
	 * the DPLL.
	 */
	omap2_clk_enable(dd->clk_bypass);
	omap2_clk_enable(dd->clk_ref);

	if (dd->clk_bypass->rate == rate &&
	    (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
		pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);

		ret = _omap3_noncore_dpll_bypass(clk);
		if (!ret)
			new_parent = dd->clk_bypass;
	} else {
		if (dd->last_rounded_rate != rate)
			omap2_dpll_round_rate(clk, rate);

		if (dd->last_rounded_rate == 0)
			return -EINVAL;

		/* No freqsel on OMAP4 or OMAP3630 */
		if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
			freqsel = _omap3_dpll_compute_freqsel(clk,
						dd->last_rounded_n);
			if (!freqsel)
				WARN_ON(1);
		}

		pr_debug("clock: %s: set rate: locking rate to %lu.\n",
			 clk->name, rate);

		ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
						 dd->last_rounded_n, freqsel);
		if (!ret)
			new_parent = dd->clk_ref;
	}
	if (!ret) {
		/*
		 * Switch the parent clock in the heirarchy, and make sure
		 * that the new parent's usecount is correct.  Note: we
		 * enable the new parent before disabling the old to avoid
		 * any unnecessary hardware disable->enable transitions.
		 */
		if (clk->usecount) {
			omap2_clk_enable(new_parent);
			omap2_clk_disable(clk->parent);
		}
		clk_reparent(clk, new_parent);
		clk->rate = rate;
	}
	omap2_clk_disable(dd->clk_ref);
	omap2_clk_disable(dd->clk_bypass);

	return 0;
}
Exemplo n.º 4
0
/*
 * This must be called before _set_clkdiv and _set_sysclk since McBSP register
 * cache is initialized here
 */
static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
				      unsigned int fmt)
{
	struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
	struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
	unsigned int temp_fmt = fmt;

	if (mcbsp_data->configured)
		return 0;

	mcbsp_data->fmt = fmt;
	memset(regs, 0, sizeof(*regs));
	/* Generic McBSP register settings */
	regs->spcr2	|= XINTM(3) | FREE;
	regs->spcr1	|= RINTM(3);
	/* RFIG and XFIG are not defined in 34xx */
	if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) {
		regs->rcr2	|= RFIG;
		regs->xcr2	|= XFIG;
	}
	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
		regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
		regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		/* 1-bit data delay */
		regs->rcr2	|= RDATDLY(1);
		regs->xcr2	|= XDATDLY(1);
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		/* 0-bit data delay */
		regs->rcr2	|= RDATDLY(0);
		regs->xcr2	|= XDATDLY(0);
		regs->spcr1	|= RJUST(2);
		/* Invert FS polarity configuration */
		temp_fmt ^= SND_SOC_DAIFMT_NB_IF;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		/* 1-bit data delay */
		regs->rcr2      |= RDATDLY(1);
		regs->xcr2      |= XDATDLY(1);
		/* Invert FS polarity configuration */
		temp_fmt ^= SND_SOC_DAIFMT_NB_IF;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		/* 0-bit data delay */
		regs->rcr2      |= RDATDLY(0);
		regs->xcr2      |= XDATDLY(0);
		/* Invert FS polarity configuration */
		temp_fmt ^= SND_SOC_DAIFMT_NB_IF;
		break;
	default:
		/* Unsupported data format */
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		/* McBSP master. Set FS and bit clocks as outputs */
		regs->pcr0	|= FSXM | FSRM |
				   CLKXM | CLKRM;
		/* Sample rate generator drives the FS */
		regs->srgr2	|= FSGM;
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
		/* McBSP slave */
		break;
	default:
		/* Unsupported master/slave configuration */
		return -EINVAL;
	}

	/* Set bit clock (CLKX/CLKR) and FS polarities */
	switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		/*
		 * Normal BCLK + FS.
		 * FS active low. TX data driven on falling edge of bit clock
		 * and RX data sampled on rising edge of bit clock.
		 */
		regs->pcr0	|= FSXP | FSRP |
				   CLKXP | CLKRP;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		regs->pcr0	|= CLKXP | CLKRP;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		regs->pcr0	|= FSXP | FSRP;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
Exemplo n.º 5
0
/**
 * omap_hsmmc_reset() - Full reset of each HS-MMC controller
 *
 * Ensure that each MMC controller is fully reset.  Controllers
 * left in an unknown state (by bootloader) may prevent retention
 * or OFF-mode.  This is especially important in cases where the
 * MMC driver is not enabled, _or_ built as a module.
 *
 * In order for reset to work, interface, functional and debounce
 * clocks must be enabled.  The debounce clock comes from func_32k_clk
 * and is not under SW control, so we only enable i- and f-clocks.
 **/
static void __init omap_hsmmc_reset(void)
{
	u32 i, nr_controllers;
	struct clk *iclk, *fclk;

	if (cpu_is_omap242x())
		return;

	nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC :
		(cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC);

	for (i = 0; i < nr_controllers; i++) {
		u32 v, base = 0;
		struct device *dev = &dummy_pdev.dev;

		switch (i) {
		case 0:
			base = OMAP2_MMC1_BASE;
			break;
		case 1:
			base = OMAP2_MMC2_BASE;
			break;
		case 2:
			base = OMAP3_MMC3_BASE;
			break;
		case 3:
			if (!cpu_is_omap44xx())
				return;
			base = OMAP4_MMC4_BASE;
			break;
		case 4:
			if (!cpu_is_omap44xx())
				return;
			base = OMAP4_MMC5_BASE;
			break;
		}

		if (cpu_is_omap44xx())
			base += OMAP4_MMC_REG_OFFSET;

		dummy_pdev.id = i;
		dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
		iclk = clk_get(dev, "ick");
		if (IS_ERR(iclk))
			goto err1;
		if (clk_enable(iclk))
			goto err2;

		fclk = clk_get(dev, "fck");
		if (IS_ERR(fclk))
			goto err3;
		if (clk_enable(fclk))
			goto err4;

		omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
		v = omap_readl(base + MMCHS_SYSSTATUS);
		while (!(omap_readl(base + MMCHS_SYSSTATUS) &
			 MMCHS_SYSSTATUS_RESETDONE))
			cpu_relax();

		clk_disable(fclk);
		clk_put(fclk);
		clk_disable(iclk);
		clk_put(iclk);
	}
	return;

err4:
	clk_put(fclk);
err3:
	clk_disable(iclk);
err2:
	clk_put(iclk);
err1:
	printk(KERN_WARNING "%s: Unable to enable clocks for MMC%d, "
			    "cannot reset.\n",  __func__, i);
}
Exemplo n.º 6
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		audit_performances
 * @BRIEF		audit performances (CPU Load, C-States, OPP,
 *			memory bandwidth, timers, interrrupts, ...).
 * @RETURNS		0 in case of success
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_NOT_AVAILABLE
 * @param[in]		stream: output file (NULL: no output (silent))
 * @param[in]		duration: audit duration, in seconds (>= 1).
 * @param[in]		delay: initial wait delay before starting audit (in sec)
 * @DESCRIPTION		audit performance (CPU Load, C-States, OPP,
 *			memory bandwidth, timers, interrrupts, ...).
 *//*------------------------------------------------------------------------ */
int audit_performances(FILE *stream, unsigned int duration, unsigned int delay)
{
	int ret = 0;
	unsigned short skip_proc_stats_audit = 0;
	unsigned int cpu_cores_cnt = 0, cpu_online_cores_cnt = 0;
	unsigned short *cpu_online = NULL;
	unsigned int *idle_t0 = NULL, *iowait_t0 = NULL, *sum_t0 = NULL;
	unsigned int *idle_t1 = NULL, *iowait_t1 = NULL, *sum_t1 = NULL;
	unsigned int *idle_cnt = NULL, *iowait_cnt = NULL, *sum_cnt = NULL;
	double *load = NULL, load_total = 0;
	unsigned int cstates_nbr = 0;
	uint64_t cstates_usage[MAX_CSTATE][3] = { {0} };
	uint64_t cstates_time[MAX_CSTATE][3] = { {0} };
	unsigned short emif = 0;
	unsigned int emif_busy_cycles[2] = { 0 };
	unsigned int emif_cycles[2] = { 0 };
	unsigned int emif_delta_cycles = 0,
		emif_delta_busy_cycles = 0;
	double emif_load = 0;
	uint64_t *time_in_opp_t0 = NULL;
	uint64_t *time_in_opp_t1 = NULL;
	uint64_t *time_in_opp_cnt = NULL;
	uint64_t total_trans_t0 = 0, total_trans_t1 = 0, total_trans_cnt = 0;
	unsigned int i = 0;
	uint64_t sec = 0, msec = 0, usec = 0, active_c0_time = 0;
	double pct = 0;
	char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];
	unsigned int row = 0;
	char name[16] = { 0 };
	FILE *fp = NULL;
	char perf_summary_file[64];
	FILE *fp_irq_1 = NULL, *fp_irq_2 = NULL, *fp_timerstats = NULL;
	unsigned int irq_total_count = 0, occurred_irq_count = 0, timer_count = 0;
	genlist occurred_irq_list, timerstats_list;
	irq_info irq_inf = { 0 };
	timerstat_info timer_inf = { 0 };
	char irq_snap_file1[32] = { 0 };
	char irq_snap_file2[32] = { 0 };
	char timerstats_file[32] = { 0 };
	char timerstats_summary[256] = { 0 };
	unsigned int skip_irq_audit = 0, skip_cstate_audit = 0;
	int skip_timerstats_audit = 0;
	char *workdir = NULL;
	unsigned short skip_cpufreq_audit = 0;
	unsigned int opp_cnt = 0;


	if (duration == 0) {
		fprintf(stream, "Duration should be at least 1 second ...\n\n");
		ret = OMAPCONF_ERR_ARG;
		goto audit_performances_exit;
	}

	if (!cpu_is_omap44xx() && !cpu_is_omap54xx()) {
		fprintf(stream, "Unsupported platform, sorry...\n\n");
		ret = OMAPCONF_ERR_CPU;
		goto audit_performances_exit;
	}

	/* Retrieve a writable directory */
	workdir = workdir_get();
	if (workdir != NULL) {
		strcpy(irq_snap_file1, workdir);
		strcpy(irq_snap_file2, workdir);
		strcpy(timerstats_file, workdir);
		strcpy(perf_summary_file, workdir);
		strcat(irq_snap_file1, "proc_interrupts_1");
		strcat(irq_snap_file2, "proc_interrupts_2");
		strcat(timerstats_file, "proc_timerstats");
		strcat(perf_summary_file, "performance_audit_report.txt");
		skip_irq_audit = 0;
		skip_timerstats_audit = 0;
	} else {
		skip_irq_audit = 1;
		skip_timerstats_audit = 1;
	}

	/* Open trace output file */
	fp = fopen(perf_summary_file, "w");
	if (fp == NULL) {
		fprintf(stderr, "%s(): could not create %s!\n",
			__func__, perf_summary_file);
	} else {
		fprintf(fp, "OMAP Performance Audit Summary\n\n");
		omapconf_revision_show(fp);
		chips_info_show(fp, 1);
		release_info_show(fp);
	}

	/* Retrieve number of CPU cores and allocate buffers */
	cpu_cores_cnt = cpu_cores_count_get();
	if (cpu_cores_cnt < 1) {
		skip_proc_stats_audit = 1;
	} else {
		dprintf("%s(): found %u cores\n", __func__, cpu_cores_cnt);
		cpu_online = malloc(cpu_cores_cnt * sizeof(unsigned int));
		idle_t0 = malloc(cpu_cores_cnt * sizeof(unsigned int));
		iowait_t0 = malloc(cpu_cores_cnt * sizeof(unsigned int));
		sum_t0 = malloc(cpu_cores_cnt * sizeof(unsigned int));
		idle_t1 = malloc(cpu_cores_cnt * sizeof(unsigned int));
		iowait_t1 = malloc(cpu_cores_cnt * sizeof(unsigned int));
		sum_t1 = malloc(cpu_cores_cnt * sizeof(unsigned int));
		idle_cnt = malloc(cpu_cores_cnt * sizeof(unsigned int));
		iowait_cnt = malloc(cpu_cores_cnt * sizeof(unsigned int));
		sum_cnt = malloc(cpu_cores_cnt * sizeof(unsigned int));
		load = malloc(cpu_cores_cnt * sizeof(double));
		if ((cpu_online == NULL) || (idle_t0 == NULL) ||
			(iowait_t0 == NULL) || (sum_t0 == NULL) ||
			(idle_t1 == NULL) || (iowait_t1 == NULL) ||
			(sum_t1 == NULL) || (iowait_cnt == NULL) ||
			(iowait_cnt == NULL) || (sum_cnt == NULL) ||
			(load == NULL)) {
			fprintf(stderr, "%s(): could not allocate buffers for "
				"CPU stats!\n", __func__);
			skip_proc_stats_audit = 1;
		}
		dprintf("%s(): CPU stats buffers allocated.\n", __func__);
		skip_proc_stats_audit = 0;
	}

	/* Retrieve number of MPU OPPs and allocate buffers */
	opp_cnt = cpufreq_opp_nbr_get();
	if (opp_cnt == 0) {
		skip_cpufreq_audit = 1;
	} else {
		dprintf("%s(): found %u MPU OPPs\n", __func__, opp_cnt);
		time_in_opp_t0 = malloc(opp_cnt * sizeof(uint64_t));
		time_in_opp_t1 = malloc(opp_cnt * sizeof(uint64_t));
		time_in_opp_cnt = malloc(opp_cnt * sizeof(uint64_t));
		if ((time_in_opp_t0 == NULL) || (time_in_opp_t1 == NULL) ||
			(time_in_opp_cnt == NULL)) {
			fprintf(stderr, "%s(): could not allocate buffers for "
				"CPUFREQ stats!\n", __func__);
			skip_cpufreq_audit = 1;
		}
		dprintf("%s(): CPUFREQ stats buffers allocated.\n", __func__);
		skip_cpufreq_audit = 0;
	}

	/* Configure EMIF counters to count data bus busy cycles (OMAP4) */
	if (cpu_is_omap44xx()) {
		ret = emif44xx_perf_cnt_configure(EMIF44XX_0,
			EMIF44XX_PERF_CNT_1,
			EMIF44XX_PERF_CNT_FILTER_DATA_TRANSFER_CYCLES,
			-1, EMIF44XX_MEMADDRSPACE_DISABLED);
		ret |= emif44xx_perf_cnt_configure(EMIF44XX_1,
			EMIF44XX_PERF_CNT_1,
			EMIF44XX_PERF_CNT_FILTER_DATA_TRANSFER_CYCLES,
			-1, EMIF44XX_MEMADDRSPACE_DISABLED);
		if (ret != 0) {
			strncpy(timerstats_summary,
				"Unexpected error occurred while configuring "
				"EMIF performance counters!!!\n\n", 256);
			if (stream != NULL)
				fputs(timerstats_summary, stream);
			if (fp != NULL)
				fputs(timerstats_summary, fp);
			ret = OMAPCONF_ERR_NOT_AVAILABLE;
			goto audit_performances_exit;
		}
		dprintf("%s(): EMIF counters configured.\n", __func__);
	}

	/* Retrieve number of active C-State(s) */
	cstates_nbr = cstate_get_number();
	if (cstates_nbr == 0) {
		cstates_nbr = 0;
		skip_cstate_audit = 1;
	} else {
		skip_cstate_audit = 0;
		dprintf("%s(): found %u C-State(s)\n", __func__, cstates_nbr);
	}

	if (fp != NULL) {
		fprintf(fp, "Audit duration: %us\n", duration);
		fprintf(fp, "Audit initial delay: %us\n\n", delay);
	}
	/* Initial delay before starting capture */
	if (delay >= 1) {
		if (stream != NULL)
			fprintf(stream, "Wait for initial delay (%u sec), then"
				" sample various Key Performance Indicators "
				"over %u second(s) ...\n\n", delay, duration);
		sleep(delay);
	} else {
		if (stream != NULL)
			fprintf(stream,
			"Sampling various Key Performance Indicators "
			"over %u second(s) ...\n\n", duration);
	}

	/* Save current C-State usage & time counters */
	if (skip_cstate_audit == 0) {
		for (i = 0; i < cstates_nbr; i++) {
			cstates_usage[i][0] = cstate_get_usage(i);
			cstates_time[i][0] = cstate_get_time(i);
		}
	}

	/* Save current cpufreq stats */
	if (skip_cpufreq_audit == 0) {
		for (i = 0; i < opp_cnt; i++) {
			time_in_opp_t0[i] = cpufreq_time_in_state_get(i);
			dprintf("%s(): time_in_opp_t0[%u] = %llu\n",
				__func__, i, time_in_opp_t0[i]);
		}
		total_trans_t0 = cpufreq_total_transitions_get();
	}

	/* Save current cpu usage stats */
	if (skip_proc_stats_audit == 0) {
		for (i = 0; i < cpu_cores_cnt; i++) {
			ret = cpu_proc_stats_get(i,
				&idle_t0[i], &iowait_t0[i], &sum_t0[i]);
			if (ret != 0) {
				cpu_online[i] = 0;
				dprintf("%s(): CPU%u offline\n", __func__, i);
			} else {
				cpu_online[i] = 1;
			}

		}
	}

	/* Get current EMIFs total & data transfer cycles */
	if (cpu_is_omap44xx()) {
		emif_busy_cycles[0] = 0;
		for (emif = 0; emif < EMIF44XX_MAX; emif++) {
			emif_busy_cycles[0] += emif44xx_perf_cnt_get_count(
				(emif44xx_ids) emif, EMIF44XX_PERF_CNT_1);
		}
		emif_cycles[0] = emif44xx_perf_cnt_get_time(EMIF44XX_0);
	}

	/* Save current interrupt stats */
	if (skip_irq_audit != 1) {
		ret = irq_snapshot_save(irq_snap_file1);
		if (ret != 0)
			skip_irq_audit = 1;
	}

	/* Save current timer stats */
	/* Stop timer statistic collector, if enabled */
	skip_timerstats_audit = timerstats_stop();
	if (skip_timerstats_audit == 0)
		skip_timerstats_audit = timerstats_start();

	/* Sleep for some time before sampling again usage counters */
	sleep(duration);

	/* Get new EMIFs total & data transfer cycles */
	if (cpu_is_omap44xx()) {
		emif_busy_cycles[1] = 0;
		for (emif = 0; emif < EMIF44XX_MAX; emif++) {
			emif_busy_cycles[1] += emif44xx_perf_cnt_get_count(
				(emif44xx_ids) emif, EMIF44XX_PERF_CNT_1);
		}
		emif_cycles[1] = emif44xx_perf_cnt_get_time(EMIF44XX_0);
	}

	if (skip_timerstats_audit == 0)
		skip_timerstats_audit = timerstats_stop();

	/* Get new interrupts stats */
	if (skip_irq_audit == 0) {
		ret = irq_snapshot_save(irq_snap_file2);
		if (ret != 0) {
			skip_irq_audit = 1;
			remove(irq_snap_file1);
		}
	}

	if (skip_timerstats_audit == 0)
		timerstats_save(timerstats_file);

	/* Get new cpu usage stats*/
	if (skip_proc_stats_audit == 0) {
		for (i = 0; i < cpu_cores_cnt; i++) {
			ret = cpu_proc_stats_get(i,
				&idle_t1[i], &iowait_t1[i], &sum_t1[i]);
			if (ret != 0) {
				cpu_online[i] = 0;
				dprintf("%s(): CPU%u offline\n", __func__, i);
			} else {
				cpu_online[i] = 1;
			}

		}
	}

	/* Get new cpufreq stats */
	if (skip_cpufreq_audit == 0) {
		for (i = 0; i < opp_cnt; i++) {
			time_in_opp_t1[i] = cpufreq_time_in_state_get(i);
			dprintf("%s(): time_in_opp_t1[%u] = %llu\n",
				__func__, i, time_in_opp_t1[i]);
		}
		total_trans_t1 = cpufreq_total_transitions_get();
	}

	/* Get new C-State usage counters */
	if (skip_cstate_audit == 0) {
		for (i = 0; i < cstates_nbr; i++) {
			cstates_usage[i][1] = cstate_get_usage(i);
			cstates_time[i][1] = cstate_get_time(i);
			dprintf("%s(): cstates_usage[%u][0] = "
				"%llu\n", __func__, i, cstates_usage[i][0]);
			dprintf("%s(): cstates_usage[%u][1] = "
				"%llu\n", __func__, i, cstates_usage[i][1]);
			dprintf("%s(): cstates_time[%u][0] = "
				"%llu\n", __func__, i, cstates_time[i][0]);
			dprintf("%s(): cstates_time[%u][1] = "
				"%llu\n", __func__, i, cstates_time[i][1]);
		}
	}

	/* Process data */
	if (cpu_is_omap44xx()) {
		emif_delta_busy_cycles = count32_delta(
			emif_busy_cycles[0], emif_busy_cycles[1]);
		emif_delta_cycles = 2 * count32_delta(
			emif_cycles[0], emif_cycles[1]);
		dprintf("%s(): EMIF delta_busy_cycles=%u, delta_cycles=%u\n",
			__func__, emif_delta_busy_cycles, emif_delta_cycles);
		emif_load = 100.0 * (
			(double) emif_delta_busy_cycles /
				emif_delta_cycles);
		dprintf("%s(): EMIF load = %lf%%\n", __func__, emif_load);
	}

	if (skip_cpufreq_audit == 0) {
		total_trans_cnt = count64_delta(total_trans_t0, total_trans_t1);
		dprintf("CPUFREQ:\n");
		dprintf("  total transitions = %llu\n", total_trans_cnt);
		for (i = 0; i < opp_cnt; i++) {
			time_in_opp_cnt[i] =
				count64_delta(time_in_opp_t0[i],
					time_in_opp_t1[i]);
			#ifdef AUDIT_DEBUG
			/* FIXME: retrieve cpufreq sampling rate (variable) */
			if (cpu_is_omap44xx())
				printf("  time in OPP %s = %llums\n",
					opp44xx_name_get(i + 1, OMAP4_VDD_MPU),
					time_in_opp_cnt[i] * 10);
			else
				printf("  time in OPP %s = %llums\n",
					opp54xx_name_get(i + 1),
					time_in_opp_cnt[i] * 10);
			#endif
		}
	}

	if (skip_cstate_audit == 0) {
		for (i = 0; i < cstates_nbr; i++) {
			cstates_usage[i][2] = count64_delta(
				cstates_usage[i][0], cstates_usage[i][1]);

			cstates_time[i][2] = count64_delta(
				cstates_time[i][0], cstates_time[i][1]);
		}
	}

	/* Compute & Show C-State Statistics */
	if (skip_cstate_audit == 1) {
		strncpy(timerstats_summary,
			"WARNING: could not retrieve C-State number. "
			"Skipping C-States audit.\n\n", 256);
		if (stream != NULL)
			fputs(timerstats_summary, stream);
		if (fp != NULL)
			fputs(timerstats_summary, fp);
	} else {
		autoadjust_table_init(table);
		row = 0;
		strncpy(table[row][0], "C-State", TABLE_MAX_ELT_LEN);
		strncpy(table[row][1], "Entered?", TABLE_MAX_ELT_LEN);
		strncpy(table[row][2], "Hit Number", TABLE_MAX_ELT_LEN);
		strncpy(table[row][3], "Time Spent (s)", TABLE_MAX_ELT_LEN);
		strncpy(table[row][4], "Time Spent (%)", TABLE_MAX_ELT_LEN);
		row++;

		strncpy(table[row][0], "Active + \"C0\"", TABLE_MAX_ELT_LEN);
		strncpy(table[row][1], "Yes", TABLE_MAX_ELT_LEN);
		active_c0_time = duration * 1000000;
		for (i = 0; i < cstates_nbr; i++) {
			if (active_c0_time > cstates_time[i][2])
				active_c0_time -= cstates_time[i][2];
			else
				/*
				 * It may be possible that
				 * active_c0_time is < cstates_time[i][2]
				 * (duration may fluctuate a little depending on
				 * system load). Make sure it doesn't cross 0 as
				 * it's an unsigned interger.
				 */
				active_c0_time = 0;

		}
		sec = active_c0_time / 1000000;
		msec = (active_c0_time % 1000000) / 1000;
		usec = active_c0_time % 1000;
		snprintf(table[row][3], TABLE_MAX_ELT_LEN,
			"%llus %llums %lluus", sec, msec, usec);
		pct = ((double) active_c0_time / (double)
					(duration * 1000000)) * 100.0;
		snprintf(table[row][4], TABLE_MAX_ELT_LEN, "%3.1f%%", pct);
		row++;

		for (i = 0; i < cstates_nbr; i++) {
			snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s",
				cstate_get_name(i, name));
			if (cstates_usage[i][2] != 0) {
				dprintf("%s(): C%u entered\n", __func__, i + 1);
				strncpy(table[row][1], "Yes",
					TABLE_MAX_ELT_LEN);

				snprintf(table[row][2], TABLE_MAX_ELT_LEN,
					"%llu", cstates_usage[i][2]);

				sec = cstates_time[i][2] / 1000000;
				msec = (cstates_time[i][2] % 1000000) / 1000;
				usec = cstates_time[i][2] % 1000;
				snprintf(table[row][3], TABLE_MAX_ELT_LEN,
					"%llus %llums %lluus", sec, msec, usec);

				pct = ((double) cstates_time[i][2] / (double)
					(duration * 1000000)) * 100.0;
				snprintf(table[row][4], TABLE_MAX_ELT_LEN,
					"%3.1f%%", pct);
			} else {
				dprintf("%s(): C%u not entered\n",
					__func__, i + 1);
				strncpy(table[row][1], "No", TABLE_MAX_ELT_LEN);
			}
			row++;
		}

		/* Print results */
		strncpy(timerstats_summary,
			"NB: this table shows statistics about "
			"the ATTEMPTED C-States, not the effectively "
			"entered C-States (not supported by kernel "
			"idle framework yet).\nAs a consequence, these "
			"C-States MAY or MAY NOT have been entered, "
			"depending on HW conditions.\n\n\n", 256);
		if (stream != NULL) {
			autoadjust_table_fprint(stream, table, row, 5);
			fputs(timerstats_summary, stream);
		}
		if (fp != NULL) {
			autoadjust_table_fprint(fp, table, row, 5);
			fputs(timerstats_summary, fp);
		}
	}

	/* Show CPUFreq stats */
	if (skip_cpufreq_audit == 1) {
		strncpy(timerstats_summary, "WARNING: could not retrieve MPU "
			"OPP number. CPUFreq audit skipped.\n\n", 256);
		if (stream != NULL)
			fputs(timerstats_summary, stream);
		if (fp != NULL)
			fputs(timerstats_summary, fp);
	} else {
		autoadjust_table_init(table);
		row = 0;
		strncpy(table[row][0], "MPU OPP", TABLE_MAX_ELT_LEN);
		strncpy(table[row][1], "Time Spent in OPP", TABLE_MAX_ELT_LEN);
		row++;

		for (i = 0; i < opp_cnt; i++) {
			if (cpu_is_omap44xx())
				snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s",
					opp44xx_name_get(i + 1, OMAP4_VDD_MPU));
			else
				snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s",
					opp54xx_name_get(i + 1));
			snprintf(table[row][1], TABLE_MAX_ELT_LEN,
				"%llus%llums",
				time_in_opp_cnt[i] / 100,
				(time_in_opp_cnt[i] % 100) * 10);
			row++;
		}

		cpufreq_scaling_governor_get(name);
		if (name != NULL)
			sprintf(timerstats_summary,
				"CPUFreq Governor: %s\n", name);
		else
			sprintf(timerstats_summary,
				"CPUFreq Governor: not found!\n");
		if (stream != NULL)
			fputs(timerstats_summary, stream);
		if (fp != NULL)
			fputs(timerstats_summary, fp);

		sprintf(timerstats_summary,
			"Total number of OPP transitions: %llu\n\n",
			total_trans_cnt);
		if (stream != NULL) {
			fputs(timerstats_summary, stream);
			autoadjust_table_fprint(stream, table, row, 2);
			fprintf(stream, "\n");
		}
		if (fp != NULL) {
			fputs(timerstats_summary, fp);
			autoadjust_table_fprint(fp, table, row, 2);
			fprintf(fp, "\n");
		}
	}

	/* Show CPU Load stats */
	if (skip_proc_stats_audit == 1) {
		strncpy(timerstats_summary, "WARNING: could not retrieve CPU "
			"cores number. CPU Load audit skipped.\n\n", 256);
		if (stream != NULL)
			fputs(timerstats_summary, stream);
		if (fp != NULL)
			fputs(timerstats_summary, fp);
	} else {
		autoadjust_table_init(table);
		row = 0;
		strncpy(table[row][0], "CPU", TABLE_MAX_ELT_LEN);
		strncpy(table[row][1], "Average Load (*)", TABLE_MAX_ELT_LEN);
		row++;

		cpu_online_cores_cnt = 0;
		load_total = 0.0;
		for (i = 0; i < cpu_cores_cnt; i++) {
			snprintf(table[row][0], TABLE_MAX_ELT_LEN, "CPU%u", i);
			if ((i >= 1) && (cpu_online[i] == 0)) {
				snprintf(table[row][1], TABLE_MAX_ELT_LEN,
					"Offline");
				row++;
				continue;
			}

			idle_cnt[i] =
				count32_delta(idle_t0[i], idle_t1[i]);
			iowait_cnt[i] =
				count32_delta(iowait_t0[i], iowait_t1[i]);
			sum_cnt[i] =
				count32_delta(sum_t0[i], sum_t1[i]);
			dprintf("%s(): idle_cnt[%u] = %u, iowait_cnt[%u] = %u, "
				"sum_cnt[%u] = %u\n", __func__, i, idle_cnt[i],
				i, iowait_cnt[i], i, sum_cnt[i]);
			if (sum_cnt[i] != 0) {
				load[i] = cpu_load_get(idle_cnt[i],
					iowait_cnt[i], sum_cnt[i]);
				cpu_online_cores_cnt++;
			} else {
				/*
				 * Due to tickless feature, it is possible that
				 * that no tick occured during this sampling
				 * window and so /proc/stat counters were not
				 * incremented. => cpu load = 0.
				 */
				load[i] = 0.0;
			}
			load_total += load[i];
			dprintf("%s(): CPU%u load=%.2lf%%\n",
					__func__, i, load[i]);
			snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%.2lf%%",
				load[i]);
			row++;
		}
		dprintf("%s(): cpu_online_cores_cnt=%u\n",
			__func__, cpu_online_cores_cnt);
		load_total = load_total / cpu_online_cores_cnt;
		snprintf(table[row][0], TABLE_MAX_ELT_LEN, "Total");
		snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%.2lf%%",
			load_total);
		row++;

		strncpy(timerstats_summary, "(*) CANNOT be converted to Mhz. "
			"OPP may have changed during the audit.\n\n\n", 256);
		if (stream != NULL) {
			autoadjust_table_fprint(stream, table, row, 2);
			fputs(timerstats_summary, stream);
		}
		if (fp != NULL) {
			autoadjust_table_fprint(fp, table, row, 2);
			fputs(timerstats_summary, fp);
		}
	}

	/* Show EMIF stats */
	if (cpu_is_omap44xx()) {
		autoadjust_table_init(table);
		row = 0;
		strncpy(table[row][0], "EMIF", TABLE_MAX_ELT_LEN);
		strncpy(table[row][1], "Average Load (*)", TABLE_MAX_ELT_LEN);
		row++;
		strncpy(table[row][0], "Total EMIF Data Bus Load",
			TABLE_MAX_ELT_LEN);
		snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%.2lf%%",
				(double) emif_load);
		row++;
		strncpy(timerstats_summary, "(*) CANNOT be converted to memory "
			"bandwidth (MB/s).\n    DDR data busy cycles may be "
			"commands (not data) and data size is unknown.\n\n\n",
			256);
		if (stream != NULL) {
			autoadjust_table_fprint(stream, table, row, 2);
			fputs(timerstats_summary, stream);
		}

		if (fp != NULL) {
			autoadjust_table_fprint(fp, table, row, 2);
			fputs(timerstats_summary, fp);
		}
	}


	/* Show interrupts stats */
	if (skip_irq_audit == 1) {
		strncpy(timerstats_summary,
			"WARNING: could not save a snapshot of "
			"/proc/interrupts file. "
			"IRQ audit skipped.\n\n", 256);
		if (stream != NULL)
			fputs(timerstats_summary, stream);
		if (fp != NULL)
			fputs(timerstats_summary, fp);
	} else {
		fp_irq_1 = fopen(irq_snap_file1, "r");
		fp_irq_2 = fopen(irq_snap_file2, "r");
		if ((fp_irq_1 == NULL) || (fp_irq_2 == NULL)) {
			fprintf(stderr, "%s(): could not open interrupts "
				"snapshot files!\n\n", __func__);
			ret = OMAPCONF_ERR_NOT_AVAILABLE;
			goto audit_performances_exit;
		}

		autoadjust_table_init(table);
		row = 0;
		strncpy(table[row][0], "IRQ #", TABLE_MAX_ELT_LEN);
		strncpy(table[row][1], "Device Name", TABLE_MAX_ELT_LEN);
		strncpy(table[row][2], "Occurrence", TABLE_MAX_ELT_LEN);
		strncpy(table[row][3], "Proportion", TABLE_MAX_ELT_LEN);
		strncpy(table[row][4], "Rate", TABLE_MAX_ELT_LEN);
		row++;

		irq_total_count = irq_total_count_get(fp_irq_2)
			- irq_total_count_get(fp_irq_1);
		dprintf("%s(): irq_total_count=%d\n", __func__,
			irq_total_count);
		occurred_irq_count = irq_occurred_list_get(fp_irq_1, fp_irq_2,
			&occurred_irq_list);
		dprintf("%s(): # of irq lines that occurred = %d\n", __func__,
			occurred_irq_count);
		irq_occurred_list_sort(&occurred_irq_list);
		for (i = 0; i < occurred_irq_count; i++) {
			genlist_get(&occurred_irq_list, i, &irq_inf);
			snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%d",
				irq_inf.nbr);
			strncpy(table[row][1], irq_inf.dev_name,
				TABLE_MAX_ELT_LEN);
			pct = (double) irq_inf.count / (double) irq_total_count;
			pct *= 100.0;
			snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%u",
				irq_inf.count);
			snprintf(table[row][3], TABLE_MAX_ELT_LEN, "%.1lf%%",
				pct);
			pct = (double) irq_inf.count / (double) duration;
			snprintf(table[row][4], TABLE_MAX_ELT_LEN, "%.1lf/sec",
				pct);
			row++;
		}

		genlist_free(&occurred_irq_list);
		fclose(fp_irq_1);
		remove(irq_snap_file1);
		fclose(fp_irq_2);
		remove(irq_snap_file2);

		sprintf(timerstats_summary,
			"CPU was interrupted %d times by the following %d "
			"sources:\n", irq_total_count, occurred_irq_count);
		if (stream != NULL) {
			fputs(timerstats_summary, stream);
			autoadjust_table_fprint(stream, table, row, 5);
		}
		if (fp != NULL) {
			fputs(timerstats_summary, fp);
			autoadjust_table_fprint(fp, table, row, 5);
		}
	}

	/* Show timer stats */
	if (skip_timerstats_audit != 0) {
		strncpy(timerstats_summary,
			"Timer Statistics: unable to capture kernel timer "
			"statistics.\nMake sure that CONFIG_TIMER_STATS "
			"are enabled in the kernel configuration.\n\n", 256);
		if (stream != NULL)
			fputs(timerstats_summary, stream);
		if (fp != NULL)
			fputs(timerstats_summary, fp);
	} else {
		fp_timerstats = fopen(timerstats_file, "r");
		if (fp_timerstats == NULL) {
			fprintf(stderr, "%s(): could not open timer stats "
				"snapshot file!\n\n", __func__);
			ret = OMAPCONF_ERR_NOT_AVAILABLE;
			goto audit_performances_exit;
		}

		autoadjust_table_init(table);
		row = 0;
		strncpy(table[row][0], "# Timer Events", TABLE_MAX_ELT_LEN);
		strncpy(table[row][1], "Deferrable", TABLE_MAX_ELT_LEN);
		strncpy(table[row][2], "Process ID", TABLE_MAX_ELT_LEN);
		strncpy(table[row][3], "Process Name", TABLE_MAX_ELT_LEN);
		strncpy(table[row][4], "Init Function", TABLE_MAX_ELT_LEN);
		strncpy(table[row][5], "Callback Function", TABLE_MAX_ELT_LEN);
		row++;

		timer_count = timerstats_list_get(fp_timerstats,
			&timerstats_list);
		dprintf("%s(): # of timers that occurred = %d\n", __func__,
			timer_count);
		timerstats_list_sort(&timerstats_list);

		for (i = 0; i < timer_count; i++) {
			genlist_get(&timerstats_list, i, &timer_inf);
			snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%d",
				timer_inf.count);
			strncpy(table[row][1], timer_inf.deferrable,
				TABLE_MAX_ELT_LEN);
			snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%d",
				timer_inf.pid);
			strncpy(table[row][3], timer_inf.name,
				TABLE_MAX_ELT_LEN);
			strncpy(table[row][4], timer_inf.init_fxn,
				TABLE_MAX_ELT_LEN);
			strncpy(table[row][5], timer_inf.callback,
				TABLE_MAX_ELT_LEN);
			row++;
		}

		timerstats_get_summary(fp_timerstats, &timerstats_summary[0]);
		genlist_free(&timerstats_list);
		fclose(fp_timerstats);
		remove(timerstats_file);

		if (stream != NULL) {
			fputs(timerstats_summary, stream);
			autoadjust_table_fprint(stream, table, row, 6);
		}
		if (fp != NULL) {
			fputs(timerstats_summary, fp);
			autoadjust_table_fprint(fp, table, row, 6);
		}
	}
	if ((fp != NULL) && (stream != NULL))
		fprintf(stream, "Performance Audit data saved into "
			"\"%s\" file.\n\n", perf_summary_file);

	ret = 0;

audit_performances_exit:
	if (cpu_online != NULL)
		free(cpu_online);
	if (idle_t0 != NULL)
		free(idle_t0);
	if (iowait_t0 != NULL)
		free(iowait_t0);
	if (sum_t0 != NULL)
		free(sum_t0);
	if (idle_t1 != NULL)
		free(idle_t1);
	if (iowait_t1 != NULL)
		free(iowait_t1);
	if (sum_t1 != NULL)
		free(sum_t1);
	if (idle_cnt != NULL)
		free(idle_cnt);
	if (iowait_cnt != NULL)
		free(iowait_cnt);
	if (sum_cnt != NULL)
		free(sum_cnt);
	if (load != NULL)
		free(load);

	if (time_in_opp_t0 != NULL)
		free(time_in_opp_t0);
	if (time_in_opp_t1 != NULL)
		free(time_in_opp_t1);
	if (time_in_opp_cnt != NULL)
		free(time_in_opp_cnt);

	if (fp != NULL)
		fclose(fp);

	return ret;
}
Exemplo n.º 7
0
/*
 * Here we start the McBSP, by enabling transmitter, receiver or both.
 * If no transmitter or receiver is active prior calling, then sample-rate
 * generator and frame sync are started.
 */
void omap_mcbsp_start(unsigned int id, int tx, int rx)
{
	struct omap_mcbsp *mcbsp;
	int enable_srg = 0;
	u16 w;

	if (!omap_mcbsp_check_valid_id(id)) {
		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
		return;
	}
	mcbsp = id_to_mcbsp_ptr(id);

	if (cpu_is_omap34xx())
		omap_st_start(mcbsp);

	/* Only enable SRG, if McBSP is master */
	w = MCBSP_READ_CACHE(mcbsp, PCR0);
	if (w & (FSXM | FSRM | CLKXM | CLKRM))
		enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
				MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);

	if (enable_srg) {
		/* Start the sample generator */
		w = MCBSP_READ_CACHE(mcbsp, SPCR2);
		MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
	}

	/* Enable transmitter and receiver */
	tx &= 1;
	w = MCBSP_READ_CACHE(mcbsp, SPCR2);
	MCBSP_WRITE(mcbsp, SPCR2, w | tx);

	rx &= 1;
	w = MCBSP_READ_CACHE(mcbsp, SPCR1);
	MCBSP_WRITE(mcbsp, SPCR1, w | rx);

	/*
	 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
	 * REVISIT: 100us may give enough time for two CLKSRG, however
	 * due to some unknown PM related, clock gating etc. reason it
	 * is now at 500us.
	 */
	udelay(500);

	if (enable_srg) {
		/* Start frame sync */
		w = MCBSP_READ_CACHE(mcbsp, SPCR2);
		MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
	}

	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
		/* Release the transmitter and receiver */
		w = MCBSP_READ_CACHE(mcbsp, XCCR);
		w &= ~(tx ? XDISABLE : 0);
		MCBSP_WRITE(mcbsp, XCCR, w);
		w = MCBSP_READ_CACHE(mcbsp, RCCR);
		w &= ~(rx ? RDISABLE : 0);
		MCBSP_WRITE(mcbsp, RCCR, w);
	}

	/* Dump McBSP Regs */
	omap_mcbsp_dump_reg(id);
}
Exemplo n.º 8
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		mod44xx_get_standby_mode
 * @BRIEF		retrieve omap module's standby mode
 * @RETURNS		1 if success
 *			0 if omap module's registers NOT accessible
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_NOT_AVAILABLE
 *			OMAPCONF_ERR_INTERNAL
 * @param[in]		module_id: omap module ID
 * @param[in,out]	mode: returned omap module's standby mode
 * @DESCRIPTION		retrieve omap module's standby mode
 *//*------------------------------------------------------------------------ */
int mod44xx_get_standby_mode(mod44xx_id module_id, mod_standby_mode *mode)
{
	int ret_val = 0;
	unsigned int sysconfig;
	mod_interface_type type;
	char name[MOD44XX_MAX_NAME_LENGTH];

	*mode = MOD_STANDBY_MODE_MAX;

	if (!cpu_is_omap44xx()) {
		fprintf(stderr, "%s(): unsupported cpu!!!\n", __func__);
		ret_val = OMAPCONF_ERR_CPU;
		goto mod44xx_get_standby_mode_end;
	}

	if (module_id >= OMAP4_MODULE_ID_MAX) {
		fprintf(stderr, "%s(): incorrect module id!!! (%u)\n",
			__func__, module_id);
		ret_val = OMAPCONF_ERR_ARG;
		goto mod44xx_get_standby_mode_end;
	}

	mod44xx_get_interface_type(module_id, &type);
	if ((module_id != OMAP4_MPU_M3) &&
		(type != MOD_INTERFACE_MASTER) &&
		(type != MOD_INTERFACE_DUAL)) {
		dprintf("%s(): module #%d name = %s has no master interface\n",
			__func__, module_id, mod44xx_get_name(module_id, name));
		ret_val = OMAPCONF_ERR_NOT_AVAILABLE;
		goto mod44xx_get_standby_mode_end;
	}

	ret_val = mod44xx_is_accessible(module_id);
	if (ret_val == 0) {
		/* Module is NOT accessible */
		ret_val = 0;
		dprintf("%s(): module #%d name = %s is NOT accessible\n",
			__func__, module_id, mod44xx_get_name(module_id, name));
		goto mod44xx_get_standby_mode_end;
	} else if (ret_val != 1) {
		/* Internal error */
		dprintf("%s(): mod44xx_is_accessible() returned with %d!!!\n",
			__func__, ret_val);
		goto mod44xx_get_standby_mode_end;
	}

	/* Module is accessible */
	dprintf("%s(): module #%d name = %s is accessible\n",
		__func__, module_id, mod44xx_get_name(module_id, name));


	if ((module_id != OMAP4_MPU_M3) &&
		(mod44xx_info_table[module_id].sysconfig_addr == NULL)) {
		fprintf(stderr,
			"%s(): error module %s interface type is not NONE but SYSCONFIG ADDR == NULL\n",
			__func__, mod44xx_get_name(module_id, name));
		ret_val = OMAPCONF_ERR_INTERNAL;
		goto mod44xx_get_standby_mode_end;
	}

	if (module_id != OMAP4_MPU_M3) {
		OMAP_READREG((unsigned int)
			mod44xx_info_table[module_id].sysconfig_addr,
			sysconfig);
		dprintf("%s(): SYSCONFIG ADDR = 0x%08X SYSCONFIG = 0x%08X\n",
			__func__, (unsigned int)
				mod44xx_info_table[module_id].sysconfig_addr,
			sysconfig);
	} else {
		OMAP_READREG((unsigned int) OMAP4430_STANDBY_CORE_SYSCONFIG,
			sysconfig);
		dprintf(
			"%s(): SYSCONFIG ADDR = 0x%08X, STANDBY_CORE_SYSCONFIG = 0x%08X\n",
			__func__, (unsigned int) OMAP4430_IDLE_CORE_SYSCONFIG,
			sysconfig);
	}

	/* Check module's standby mode */
	switch (module_id) {
	case OMAP4_IVAHD:
	case OMAP4_ICONT1:
	case OMAP4_ICONT2:
	case OMAP4_VDMA:
	case OMAP4_IME3:
	case OMAP4_ILF3:
	case OMAP4_AESS:
	case OMAP4_ISP5:
	case OMAP4_SIMCOP:
	case OMAP4_SIMCOP_DMA:
	case OMAP4_FDIF:
	case OMAP4_GFX:
	case OMAP4_MMC1_HL:
	case OMAP4_MMC2_HL:
	case OMAP4_MMC3_HL:
	case OMAP4_MMC4_HL:
	case OMAP4_MMC5_HL:
	case OMAP4_UNIPRO1:
	case OMAP4_FSUSBHOST:
	case OMAP4_HSUSBHOST:
	case OMAP4_ISS:
		*mode = (mod_standby_mode) extract_bitfield(sysconfig, 4, 2);
		ret_val = 1;
		dprintf("%s(): module %s standby mode (bits [5:4])=%d\n",
			__func__, mod44xx_get_name(module_id, name), *mode);
		break;
	case OMAP4_MPU_M3:
		*mode = (mod_standby_mode) extract_bitfield(sysconfig, 0, 2);
		ret_val = 1;
		dprintf("%s(): module %s standby mode (bits [0:12])=%d\n",
			__func__, mod44xx_get_name(module_id, name), *mode);
		break;
	default:
		*mode = (mod_standby_mode) extract_bitfield(sysconfig, 12, 2);
		ret_val = 1;
		dprintf("%s(): module %s standby mode (bits [13:12])=%d\n",
			__func__, mod44xx_get_name(module_id, name), *mode);
	}

mod44xx_get_standby_mode_end:
	return ret_val;
}
Exemplo n.º 9
0
void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
{
	struct omap_hwmod		*oh;
	struct omap_device		*od;
	struct platform_device		*pdev;
	struct device			*dev = NULL;
	int				bus_id = -1;
	const char			*oh_name, *name;
	struct omap_musb_board_data	*board_data;

	if (musb_board_data)
		board_data = musb_board_data;
	else
		board_data = &musb_default_board_data;

	/*
	 * REVISIT: This line can be removed once all the platforms using
	 * musb_core.c have been converted to use use clkdev.
	 */
	musb_plat.clock = "ick";
	musb_plat.board_data = board_data;
	musb_plat.power = board_data->power >> 1;
	musb_plat.mode = board_data->mode;
	musb_plat.extvbus = board_data->extvbus;

	if (cpu_is_omap44xx())
		omap4430_phy_init(dev); /* power down the phy */

	if (cpu_is_omap3517() || cpu_is_omap3505()) {
		oh_name = "am35x_otg_hs";
		name = "musb-am35x";
	} else {
		oh_name = "usb_otg_hs";
		name = "musb-omap2430";
	}

	oh = omap_hwmod_lookup(oh_name);
	if (!oh) {
		pr_err("Could not look up %s\n", oh_name);
		return;
	}

	od = omap_device_build(name, bus_id, oh, &musb_plat,
			       sizeof(musb_plat), omap_musb_latency,
			       ARRAY_SIZE(omap_musb_latency), false);
	if (IS_ERR(od)) {
		pr_err("Could not build omap_device for %s %s\n",
						name, oh_name);
		return;
	}

	pdev = &od->pdev;
	dev = &pdev->dev;
	get_device(dev);
	dev->dma_mask = &musb_dmamask;
	dev->coherent_dma_mask = musb_dmamask;
	put_device(dev);

	if (cpu_is_omap44xx())
		omap4430_phy_init(dev);

#ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE
	platform_device_register(&android_usb_device);
#endif
}
Exemplo n.º 10
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		mod44xx_get_autoidle_mode
 * @BRIEF		retrieve omap module's autoidle mode
 * @RETURNS		1 if success
 *			0 if omap module's registers NOT accessible
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_NOT_AVAILABLE
 *			OMAPCONF_ERR_INTERNAL
 * @param[in]		module_id: omap module ID
 * @param[in,out]	mode: returned omap module's autoidle mode
 * @DESCRIPTION		retrieve omap module's autoidle mode
 *//*------------------------------------------------------------------------ */
int mod44xx_get_autoidle_mode(mod44xx_id module_id,
	mod_autoidle_mode *mode)
{
	int ret_val = 0;
	unsigned int sysconfig;
	char name[MOD44XX_MAX_NAME_LENGTH];

	mod_interface_type type;

	*mode = MOD_AUTOIDLE_MODE_MAX;

	if (!cpu_is_omap44xx())
		return OMAPCONF_ERR_CPU;

	if (module_id >= OMAP4_MODULE_ID_MAX)
		return OMAPCONF_ERR_ARG;

	mod44xx_get_interface_type(module_id, &type);
	if (type == MOD_INTERFACE_NONE) {
		dprintf("%s(): module #%d name = %s has no SYSCONFIG\n",
			__func__, module_id,
			mod44xx_get_name(module_id, name));
		return OMAPCONF_ERR_NOT_AVAILABLE;
	}

	ret_val = mod44xx_is_accessible(module_id);
	if (ret_val == 1) {
		/* Module is accessible */
		dprintf("%s(): module #%d name = %s is accessible\n",
			__func__, module_id,
			mod44xx_get_name(module_id, name));

		if (mod44xx_info_table[module_id].sysconfig_addr != NULL) {
			OMAP_READREG((unsigned int)
				mod44xx_info_table[module_id].sysconfig_addr,
				sysconfig);
			dprintf(
				"%s(): SYSCONFIG ADDR = 0x%08X SYSCONFIG = 0x%08X\n",
				__func__,
				(unsigned int)
				mod44xx_info_table[module_id].sysconfig_addr,
				sysconfig);

			/* Check module's autoidle bit */
			switch (module_id) {
			case OMAP4_CONTROL_GEN_WKUP:
			case OMAP4_CONTROL_PADCONF_WKUP:
			case OMAP4_SYNCTIMER:
			case OMAP4_WDT2:
			case OMAP4_WDT3:
			case OMAP4_TIMER3:
			case OMAP4_TIMER4:
			case OMAP4_TIMER5:
			case OMAP4_TIMER6:
			case OMAP4_TIMER7:
			case OMAP4_TIMER8:
			case OMAP4_TIMER9:
			case OMAP4_TIMER11:
			case OMAP4_MCASP:
			case OMAP4_IVAHD:
			case OMAP4_ICONT1:
			case OMAP4_ICONT2:
			case OMAP4_VDMA:
			case OMAP4_IME3:
			case OMAP4_ILF3:
			case OMAP4_MC3:
			case OMAP4_CALC3:
			case OMAP4_ECD3:
			case OMAP4_SMARTREFLEX_CORE:
			case OMAP4_SMARTREFLEX_MPU:
			case OMAP4_SMARTREFLEX_IVA:
			case OMAP4_CONTROL_GEN_CORE:
			case OMAP4_CONTROL_PADCONF_CORE:
			case OMAP4_SYSTEM_MAILBOX:
			case OMAP4_DMM:
			case OMAP4_AESS:
			case OMAP4_SIMCOP:
			case OMAP4_SIMCOP_DMA:
			case OMAP4_FDIF:
			case OMAP4_HDMI:
			case OMAP4_GFX:
			case OMAP4_MMC1_HL:
			case OMAP4_MMC2_HL:
			case OMAP4_MMC3_HL:
			case OMAP4_MMC4_HL:
			case OMAP4_MMC5_HL:
			case OMAP4_UNIPRO1:
			case OMAP4_FSUSBHOST:
			case OMAP4_HSUSBHOST:
			case OMAP4_MCSPI1_HL:
			case OMAP4_MCSPI2_HL:
			case OMAP4_MCSPI3_HL:
			case OMAP4_MCSPI4_HL:
			case OMAP4_DMIC:
			case OMAP4_MCBSP1:
			case OMAP4_MCBSP2:
			case OMAP4_MCBSP3:
			case OMAP4_MCPDM:
			case OMAP4_SDMA:
			case OMAP4_ISS:
			case OMAP4_BTE:
			case OMAP4_CBUFF:
				ret_val = OMAPCONF_ERR_NOT_AVAILABLE;
				dprintf("%s(): module %s has no AUTOIDLE bit\n",
					__func__,
					mod44xx_get_name(module_id, name));
				break;
			case OMAP4_SLIMBUS1:
			case OMAP4_SLIMBUS2:
				/*
				 * NB: AUTOGATINGDISABLE instead of AUTOGATING,
				 * bit is inverted compared to other modules
				 */
				*mode = (mod_autoidle_mode)
					!extract_bit(sysconfig, 8);
				ret_val = 1;
				dprintf("%s(): module %s AUTOIDLE bit 8 = %d\n",
					__func__,
					mod44xx_get_name(module_id, name),
					*mode);
				break;
			case OMAP4_SIMCOP_DCT:
				*mode = (mod_autoidle_mode)
					extract_bit(sysconfig, 5);
				ret_val = 1;
				dprintf("%s(): module %s AUTOIDLE bit 5 = %d\n",
					__func__,
					mod44xx_get_name(module_id, name),
					*mode);
				break;
			case OMAP4_SIMCOP_VLCDJ:
				*mode = (mod_autoidle_mode)
					extract_bit(sysconfig, 3);
				ret_val = 1;
				dprintf("%s(): module %s AUTOIDLE bit 3 = %d\n",
					__func__,
					mod44xx_get_name(module_id, name),
					*mode);
				break;
			case OMAP4_SIMCOP_ROT:
				*mode = (mod_autoidle_mode)
					extract_bit(sysconfig, 9);
				ret_val = 1;
				dprintf("%s(): module %s AUTOIDLE bit 9 = %d\n",
					mod44xx_get_name(module_id, name),
					*mode);
				break;
			default:
				*mode = (mod_autoidle_mode)
					extract_bit(sysconfig, 0);
				ret_val = 1;
				dprintf("%s(): module %s AUTOIDLE bit 0 = %d\n",
					__func__,
					mod44xx_get_name(module_id, name),
					*mode);
			}
		} else {
			fprintf(stderr,
				"omapconf (%s): error module's %s interface type is not NONE but SYSCONFIG ADDR == NULL\n",
				__func__, mod44xx_get_name(module_id, name));
			ret_val = OMAPCONF_ERR_INTERNAL;
		}
	} else if (ret_val == 0) {
		/* Module is NOT accessible */
		ret_val = 0;
		dprintf("%s(): module is NOT accessible\n", __func__);
	} else {
		/* internal error */
		dprintf("%s(): mod44xx_is_accessible() returned with %d\n",
			__func__, ret_val);
	}

	return ret_val;
}
Exemplo n.º 11
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		mod44xx_get_idle_mode
 * @BRIEF		retrieve omap module's idle mode
 * @RETURNS		1 if success
 *			0 if omap module's registers NOT accessible
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_NOT_AVAILABLE
 *			OMAPCONF_ERR_INTERNAL
 * @param[in]		module_id: omap module ID
 * @param[in,out]	mode: returned omap module's idle mode
 * @DESCRIPTION		retrieve omap module's idle mode
 *//*------------------------------------------------------------------------ */
int mod44xx_get_idle_mode(mod44xx_id module_id, mod_idle_mode *mode)
{
	int ret_val = 0;
	unsigned int sysconfig;
	mod_interface_type type;
	char name[MOD44XX_MAX_NAME_LENGTH];

	*mode = MOD_IDLE_MODE_MAX;

	if (!cpu_is_omap44xx()) {
		fprintf(stderr, "%s(): unsupported cpu!!!\n", __func__);
		ret_val = OMAPCONF_ERR_CPU;
		goto mod44xx_get_idle_mode_end;
	}

	if (module_id >= OMAP4_MODULE_ID_MAX) {
		fprintf(stderr, "%s(): incorrect module id!!! (%u)\n",
			__func__, module_id);
		ret_val = OMAPCONF_ERR_ARG;
		goto mod44xx_get_idle_mode_end;
	}

	mod44xx_get_interface_type(module_id, &type);
	if ((module_id != OMAP4_MPU_M3) &&
		(type != MOD_INTERFACE_SLAVE) && (type != MOD_INTERFACE_DUAL)) {
		dprintf("%s(): module #%d name = %s has no slave interface\n",
			__func__, module_id, mod44xx_get_name(module_id, name));
		ret_val = OMAPCONF_ERR_NOT_AVAILABLE;
		goto mod44xx_get_idle_mode_end;
	}

	ret_val = mod44xx_is_accessible(module_id);
	if (ret_val == 0) {
		/* Module is NOT accessible */
		ret_val = 0;
		dprintf("%s(): module #%d name = %s is NOT accessible\n",
			__func__, module_id, mod44xx_get_name(module_id, name));
		goto mod44xx_get_idle_mode_end;
	} else if (ret_val != 1) {
		/* internal error */
		dprintf("%s(): mod44xx_is_accessible() returned with %d!!!\n",
			__func__, ret_val);
		goto mod44xx_get_idle_mode_end;
	}

	/* Module is accessible */
	dprintf("%s(): module #%d name = %s is accessible\n",
		__func__, module_id, mod44xx_get_name(module_id, name));

	if ((module_id != OMAP4_MPU_M3) &&
		(mod44xx_info_table[module_id].sysconfig_addr == NULL)) {
		fprintf(stderr,
			"%s(): error module %s interface type is not NONE but SYSCONFIG ADDR == NULL\n",
			__func__, mod44xx_get_name(module_id, name));
		ret_val = OMAPCONF_ERR_INTERNAL;
		goto mod44xx_get_idle_mode_end;
	}


	if (module_id != OMAP4_MPU_M3) {
		OMAP_READREG((unsigned int)
			mod44xx_info_table[module_id].sysconfig_addr,
			sysconfig);
		dprintf("%s(): SYSCONFIG ADDR = 0x%08X, SYSCONFIG = 0x%08X\n",
			__func__, (unsigned int)
			mod44xx_info_table[module_id].sysconfig_addr,
			sysconfig);
	} else {
		OMAP_READREG((unsigned int) OMAP4430_IDLE_CORE_SYSCONFIG,
			sysconfig);
		dprintf(
			"%s(): SYSCONFIG ADDR = 0x%08X, IDLE_CORE_SYSCONFIG = 0x%08X\n",
			__func__, (unsigned int) OMAP4430_IDLE_CORE_SYSCONFIG,
			sysconfig);
	}

	/* get module's idle mode */
	switch (module_id) {
	case OMAP4_MCASP:
	case OMAP4_MPU_M3:
		*mode = (mod_idle_mode) extract_bitfield(sysconfig, 0, 2);
		ret_val = 1;
		dprintf("%s(): module %s idle mode (bits [1:0])=%d\n",
			__func__, mod44xx_get_name(module_id, name), *mode);
		break;
	case OMAP4_CONTROL_GEN_WKUP:
	case OMAP4_CONTROL_PADCONF_WKUP:
	case OMAP4_SLIMBUS1:
	case OMAP4_SLIMBUS2:
	case OMAP4_IVAHD:
	case OMAP4_ICONT1:
	case OMAP4_ICONT2:
	case OMAP4_VDMA:
	case OMAP4_IME3:
	case OMAP4_IPE3:
	case OMAP4_ILF3:
	case OMAP4_MC3:
	case OMAP4_CALC3:
	case OMAP4_ECD3:
	case OMAP4_CONTROL_GEN_CORE:
	case OMAP4_CONTROL_PADCONF_CORE:
	case OMAP4_SYSTEM_MAILBOX:
	case OMAP4_DMM:
	case OMAP4_AESS:
	case OMAP4_BTE:
	case OMAP4_CBUFF:
	case OMAP4_FDIF:
	case OMAP4_HDMI:
	case OMAP4_GFX:
	case OMAP4_MMC1_HL:
	case OMAP4_MMC2_HL:
	case OMAP4_MMC3_HL:
	case OMAP4_MMC4_HL:
	case OMAP4_MMC5_HL:
	case OMAP4_UNIPRO1:
	case OMAP4_FSUSBHOST:
	case OMAP4_HSUSBHOST:
	case OMAP4_MCSPI1_HL:
	case OMAP4_MCSPI2_HL:
	case OMAP4_MCSPI3_HL:
	case OMAP4_MCSPI4_HL:
	case OMAP4_DMIC:
	case OMAP4_MCPDM:
	case OMAP4_TIMER1:
	case OMAP4_TIMER2:
	case OMAP4_TIMER3:
	case OMAP4_TIMER4:
	case OMAP4_TIMER5:
	case OMAP4_TIMER6:
	case OMAP4_TIMER7:
	case OMAP4_TIMER8:
	case OMAP4_TIMER9:
	case OMAP4_TIMER10:
	case OMAP4_TIMER11:
	case OMAP4_ISS:
		*mode = (mod_idle_mode) extract_bitfield(sysconfig, 2, 2);
		ret_val = 1;
		dprintf("%s(): module %s idle mode (bits [3:2])=%d\n",
			__func__, mod44xx_get_name(module_id, name), *mode);
		break;
	case OMAP4_DSP:
	case OMAP4_DSP_WUGEN:
	case OMAP4_TCTRL:
	case OMAP4_RSZ:
	case OMAP4_SIMCOP_DCT:
	case OMAP4_SIMCOP_VLCDJ:
	case OMAP4_SIMCOP_ROT:
	case OMAP4_HDQ1W:
		ret_val = OMAPCONF_ERR_NOT_AVAILABLE;
		dprintf("%s(): module %s does not have IDLE mode\n",
			__func__, mod44xx_get_name(module_id, name));
		break;
	case OMAP4_SMARTREFLEX_CORE:
	case OMAP4_SMARTREFLEX_MPU:
	case OMAP4_SMARTREFLEX_IVA:
		*mode = (mod_idle_mode) extract_bitfield(sysconfig, 24, 2);
		ret_val = 1;
		dprintf("%s(): module %s idle mode (bits [25:24])=%d\n",
			__func__, mod44xx_get_name(module_id, name), *mode);
		break;
	default:
		*mode = (mod_idle_mode) extract_bitfield(sysconfig, 3, 2);
		ret_val = 1;
		dprintf("%s(): module %s idle mode (bits [4:3])=%d\n",
			__func__, mod44xx_get_name(module_id, name), *mode);
	}


mod44xx_get_idle_mode_end:
	return ret_val;
}
Exemplo n.º 12
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		mod44xx_is_accessible
 * @BRIEF		check omap module's registers accessibility
 * @RETURNS		1 if omap module's registers accessible
 *			0 if omap module's registers NOT accessible
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_CPU
 * @param[in]		module_id: omap module ID
 * @DESCRIPTION		check omap module's registers accessibility
 *//*------------------------------------------------------------------------ */
int mod44xx_is_accessible(mod44xx_id module_id)
{
	unsigned int cm_clkctrl_addr, cm_clkctrl;
	int ret = 0;
	mod_module_mode mmode;
	#ifdef MODULE44XX_DEBUG
	char name[MOD44XX_MAX_NAME_LENGTH];
	#endif

	if (!cpu_is_omap44xx()) {
		fprintf(stderr, "%s(): cpu is not omap44xx!!!\n", __func__);
		ret = OMAPCONF_ERR_CPU;
		goto mod44xx_is_accessible_exit;
	}

	if (module_id >= OMAP4_MODULE_ID_MAX) {
		fprintf(stderr, "%s(): module_id >= OMAP4_MODULE_ID_MAX!!!\n",
			__func__);
		ret = OMAPCONF_ERR_ARG;
		goto mod44xx_is_accessible_exit;
	}

	/* Retrieve module mode */
	mod44xx_get_mode(module_id, &mmode);
	if (mmode == MOD_DISABLED_MODE) {
		dprintf(
			"%s(): module #%d name = %s mode is disabled => NOT accessible\n",
			__func__,
			module_id, mod44xx_get_name(module_id, name));
		ret = 0;
		goto mod44xx_is_accessible_exit;
	} else if (mmode == MOD_ENABLED_MODE) {
		dprintf(
			"%s(): module #%d name = %s mode is enabled => accessible\n",
			__func__,
			module_id, mod44xx_get_name(module_id, name));
		ret = 1;
		goto mod44xx_is_accessible_exit;
	}
	/* Module mode is HW Auto, need to check status */
	/* Retrieve CM_CLKCTRL address */
	cm_clkctrl_addr = (unsigned int)
		mod44xx_info_table[module_id].cm_clkctrl_addr;
	dprintf("%s(): module #%d name = %s CM_CLKCTRL ADDR = 0x%08X\n",
		__func__, module_id, mod44xx_get_name(module_id, name),
		cm_clkctrl_addr);

	/* Retrieve module state */
	if ((void *) cm_clkctrl_addr != NULL) {
		if (mem_read(cm_clkctrl_addr, &cm_clkctrl) != 0) {
			fprintf(stderr, "%s(): could not read register!!!\n",
				__func__);
			ret = OMAPCONF_ERR_REG_ACCESS;
			goto mod44xx_is_accessible_exit;
		}

		dprintf(
			"%s(): CM_CLKCTRL ADDR = 0x%08X CM_CLKCTRL = 0x%08X IDLEST = %d\n",
			__func__, (unsigned int)
				mod44xx_info_table[module_id].cm_clkctrl_addr,
			cm_clkctrl, extract_bitfield(cm_clkctrl, 16, 2));

		/* Check if module is accessible */
		switch (extract_bitfield(cm_clkctrl, 16, 2)) {
		case 0:
			/* Module is fully functional, including OCP */
			dprintf(
				"%s(): module is fully functional, including OCP\n",
				__func__);
			ret = 1;
			break;
		case 1:
			/*
			 * Module is performing transition: wakeup, or sleep,
			 * or sleep abortion
			 */
			dprintf(
				"%s(): module is performing transition: wakeup, or sleep, or sleep abortion\n",
				__func__);
			ret = 0;
			break;
		case 2:
			/* Module is in Idle mode (only OCP part) */
			dprintf(
				"%s(): module is in Idle mode (only OCP part)\n",
				__func__);
			ret = 0;
			break;
		case 3:
			/* Module is disabled and cannot be accessed */
			dprintf(
				"%s(): module is disabled and cannot be accessed\n",
				__func__);
			ret = 0;
		}
	} else {
		/* mod44xx_is_accessible():
		 * module has NO CM_CLKCTRL, it's always ON
		 */
		dprintf("%s(): module has NO CM_CLKCTRL, always ON\n",
			__func__);
		ret = 1;
	}

mod44xx_is_accessible_exit:
	dprintf("%s(%d) = %d\n", __func__, module_id, ret);
	return ret;
}
Exemplo n.º 13
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		mod44xx_get_clock_activity_mode
 * @BRIEF		retrieve omap module's clockactivity mode
 * @RETURNS		1 if success
 *			0 if omap module's registers NOT accessible
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_NOT_AVAILABLE
 *			OMAPCONF_ERR_INTERNAL
 * @param[in]		module_id: omap module ID
 * @param[in,out]	mode: returned omap module's clockactivity mode
 * @DESCRIPTION		retrieve omap module's clockactivity mode
 *//*------------------------------------------------------------------------ */
int mod44xx_get_clock_activity_mode(mod44xx_id module_id,
	mod_clock_activity_mode *mode)
{
	int ret_val = 0;
	unsigned int sysconfig;
	char name[MOD44XX_MAX_NAME_LENGTH];

	*mode = MOD_CLOCK_ACTIVITY_MODE_MAX;

	if (!cpu_is_omap44xx())
		return OMAPCONF_ERR_CPU;

	if (module_id >= OMAP4_MODULE_ID_MAX)
		return OMAPCONF_ERR_ARG;

	if (mod44xx_has_clockactivity_bit(module_id) != 1)
		return OMAPCONF_ERR_NOT_AVAILABLE;

	ret_val = mod44xx_is_accessible(module_id);
	if (ret_val == 1) {
		/* Module is accessible */
		dprintf("%s(): module #%d name = %s is accessible\n",
			__func__, module_id,
			mod44xx_get_name(module_id, name));

		if (mod44xx_info_table[module_id].sysconfig_addr != NULL) {
			OMAP_READREG((unsigned int)
				mod44xx_info_table[module_id].sysconfig_addr,
				sysconfig);
			dprintf(
				"%s(): SYSCONFIG ADDR = 0x%08X SYSCONFIG = 0x%08X\n",
				__func__, (unsigned int)
				mod44xx_info_table[module_id].sysconfig_addr,
				sysconfig);

			/* Check module's idle mode */
			switch (module_id) {
			case OMAP4_SPINLOCK:
			case OMAP4_ELM:
				*mode = (mod_clock_activity_mode)
					extract_bit(sysconfig, 8);
				ret_val = 1;
				dprintf(
					"%s(): module %s clockactivity bit 8 = %d\n",
					__func__,
					mod44xx_get_name(module_id, name),
					*mode);
				break;
			default:
				*mode = (mod_clock_activity_mode)
					extract_bitfield(sysconfig, 8, 2);
				ret_val = 1;
				dprintf(
					"%s(): module %s clockactivity (bits [9:8]) = %d\n",
					__func__,
					mod44xx_get_name(module_id, name),
					*mode);
			}
		} else {
			fprintf(stderr,
				"%s(): error module's %s interface type is not NONE but SYSCONFIG ADDR == NULL\n",
				__func__, mod44xx_get_name(module_id, name));
			ret_val = OMAPCONF_ERR_INTERNAL;
		}
	} else if (ret_val == 0) {
		/* Module is NOT accessible */
		ret_val = 0;
		dprintf("%s(): module is NOT accessible\n", __func__);
	} else {
		/* internal error */
		dprintf("%s(): mod44xx_is_accessible() returned with %d\n",
			__func__, ret_val);
	}

	return ret_val;
}
Exemplo n.º 14
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		help
 * @BRIEF		display omapconf help
 * @RETURNS		none
 * @param[in]		cat: help category to display
 * @DESCRIPTION		display omapconf help
 *//*------------------------------------------------------------------------ */
void help(help_category cat)
{
	if (cat >= HELP_CATEGORY_MAX) {
		fprintf(stderr, "help called with incorrect category!!! (%d)\n",
			cat);
		return;
	}

	if ((cat == HELP_ALL) || (cat == HELP_USAGE)) {
		printf("\nNAME\n");
		printf("\tomapconf - TI OMAP Configuration Diagnostic Tool\n");

		printf("\nSYNOPSIS\n");
		printf("\tomapconf [--version] [--help] [--cpuinfo] "
			"[--buildinfo] [--import <file>] [--force <cpu>] "
			"[--norw] <command> [<args>]\n");
		if (cat == HELP_USAGE)
			printf("\n\tSee 'omapconf --help' for more "
			"information.\n\n");
	}

	if (cat == HELP_ALL) {
		printf("\nDESCRIPTION\n");
		printf("\tomaconf is standalone application designed to provide"
			" a quick'n easy way to diagnose/monitor/debug/audit "
			"TI OMAP processors configuration at runtime, with no "
			"particular kernel dependency.\n");
		printf("\tomapconf is designed to be as much platform-agnostic "
			"as possible, being able to run on any Linux platform ("
			"Ubuntu, Android, ...) and easily ported to "
			"other OS.\n");
		printf("\tEven if omapconf today focuses mainly on "
			"power management and performances diagnostic, it is "
			"intended to be extended to any other area.\n");

		printf("\nOPTIONS\n");
		printf("\t--help\n");
		printf("\t    Print omapconf help.\n");

		printf("\n\t--version\n");
		printf("\t    Print omapconf version.\n");

		printf("\n\t--cpuinfo\n");
		printf(
			"\t    Print CPU details (revision, type, DIE ID, ...).\n");

		printf("\n\t--buildinfo\n");
		printf("\t    Print SW Build Details (kernel, release).\n");

		printf("\n\t--import <file> (### OMAP5 ONLY ###)\n");
		printf("\t    Import OMAP registers content from XML <file> "
			"(generated with command \"export <file>\").\n");
		printf("\t    Must be used in conjunction with option "
			"\"--force\".\n");

		printf("\n\t--norw\n");
		printf("\t    Fake memory access (no real R/W done): write "
			"accesses are discarded, read accesses return physical "
			"address.\n");

		printf("\n\t--trace_read\n");
		printf(
			"\t    Enable console tracing of all omapconf memory read access.\n");

		printf("\n\t--trace_write\n");
		printf(
			"\t    Enable console tracing of all omapconf memory write access.\n");
	}

	if ((cat == HELP_ALL) || (cat == HELP_FORCEDETECT)) {
		printf("\n\t--force <cpu>\n");
		printf("\t    Force CPU detection.\n");
		printf(
			"\t    Supported supported <cpu>: "
			"omap4430, omap4460, omap4470, "
			"omap5430es1, omap5432es1, omap5430, omap5432, "
			"dra75x, dra72x"
			"\n");

	}

	if ((cat != HELP_USAGE) && (cat != HELP_FORCEDETECT))
		printf("\nCOMMANDS\n");

	if ((cat == HELP_ALL) || (cat == HELP_RW)) {
		printf("\n\t### WARNING ###: use the following [read | write | "
			"set bit | clear bit | dump] commands at your own "
			"risk!\n");
		printf("\tNo address check done, may generate:\n");
		printf("\t  - bus error (invalid or not accessible "
			"<physical address>,\n");
		printf("\t  - platform crash/hang (bad <value>).\n");

		printf("\n\tomapconf read [0x<physical address> | <name>]\n");
		printf("\t    Read any OMAP memory address (register), given "
			"its <physical address> or <name> as listed in TRM.\n");
		printf("\t    e.g: omapconf read 0x4A306300, omapconf read "
			"PM_MPU_PWRSTCTRL\n");

		printf("\n\tomapconf write [0x<physical address> | <name>] "
			"0x<value>\n");
		printf("\t    Write <value> at any OMAP memory address "
			"(register), given its <physical address> or <name> as "
			"listed in TRM.\n");
		printf("\t    e.g: omapconf write 0x4A306300 0xDEADBEEF, "
			"omapconf write PM_MPU_PWRSTCTRL 0xDEADBEEF\n");

		printf("\n\tomapconf set bit [0x<physical address> | <name>] "
			"<position>"
			"\n");
		printf("\t    Set bit at <position> into any OMAP memory "
			"address (register), given its <physical address> "
			"or <name> as listed in TRM.\n");
		printf("\t    e.g: omapconf set bit 0x4A306300 1, "
			"omapconf set bit PM_MPU_PWRSTCTRL 1\n");

		printf("\n\tomapconf clear bit [0x<physical address> | <name>] "
			"<position>\n");
		printf("\t    Clear bit at <position> into any OMAP memory "
			"address (register), given its <physical address> "
			"or <name> as listed in TRM.\n");
		printf("\t    e.g: omapconf clear bit 0x4A306300 1, "
			"omapconf clear bit PM_MPU_PWRSTCTRL 1\n");

		printf("\n\tomapconf dump 0x<start address> 0x<end address>\n");
		printf("\t    Dump a range of OMAP memory addresses, from "
			"<start address> to <end address>.\n");
		printf("\t    Note all addresses within given range must be "
			"valid and accessible.\n");
		printf("\t    e.g: omapconf dump 0x48243400 0x4824340C\n");
	}


	if ((cat == HELP_ALL) || (cat == HELP_RW) || (cat == HELP_I2C_RW)) {
		printf("\n\t### WARNING ###: use the following I2C "
			"[read | write] commands at your own risk!\n");
		printf("\tNo address check done, may generate:\n");
		printf("\t  - I2C bus error (invalid or not accessible "
			"<physical address>,\n");
		printf("\t  - platform crash/hang (bad <value>).\n");


		printf("\n\tomapconf read i2c <bus> 0x<chip-addr> 0x<addr>\n");
		printf("\t    Read I2C register at address <addr> from I2C chip"
			" at <chip-addr> on I2C <bus>.\n");
		printf("\t    e.g: omapconf i2c read 1 0x49 0x02\n");

		printf("\n\tomapconf write i2c <bus> 0x<chip-addr> 0x<addr> "
			"0x<value>\n");
		printf("\t    Write <value> in I2C register at address <addr> "
			"from I2C chip at <chip-addr> on I2C <bus>.\n");
		printf("\t    e.g: omapconf i2c write 1 0x49 0x02 0xAA\n");
	}

	if ((cat == HELP_RW) || (cat == HELP_I2C_RW) ||
		(cat == HELP_FORCEDETECT))
		goto help_end;

	/* OMAP4-specific commands */
	if (cpu_is_omap44xx())
		help44xx(cat, "all");

	/* OMAP5-specific commands */
	if (cpu_is_omap54xx())
		help54xx(cat, "None");

	/* DRA7-specific commands */
	if (cpu_is_dra7xx())
		help_dra7xx(cat, "None");

	if (cat == HELP_ALL) {
		printf("\nREPORTING BUGS\n");
		printf("\tReport bugs to <*****@*****.**> "
			"mailing-list.\n");
		printf("\tYou do not have to be subsribed to the list to send "
			"a message there.\n");

		printf("\nSUGGESTIONS\n");
		printf("\tSuggest any new idea to "
			"<*****@*****.**> mailing-list.\n");
		printf("\tYou do not have to be subsribed to the list to send "
			"a message there.\n");

		printf("\nCONTRIBUTIONS\n");
		printf("\tSend patch to <*****@*****.**> "
			"mailing-list.\n");
		printf("\tYou do not have to be subsribed to the list to send "
			"a message there.\n");

		printf("\nNOTIFICATIONS\n");
		printf("\tSubscribe to <*****@*****.**> "
			"mailing-list for automatic update notification.\n");
		printf("\tYou do not have to be subsribed to the list to send "
			"a message there.\n");

		printf("\nFURTHER DOCUMENTATION\n");
		printf("\tVisit omapconf wiki:\n");
		printf("\t\t<https://github.com/omapconf/omapconf/wiki>\n");

		printf("\n");
	}

help_end:
	return;
}
Exemplo n.º 15
0
static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
			  const char *buf, size_t n)
{
	unsigned long value;
	static unsigned long prev_mpu_freq = 0;
	if (sscanf(buf, "%lu", &value) != 1)
		return -EINVAL;

	if (attr == &tick_control_attr) {
		if (value == 1)
			tick_nohz_disable(1);
		else if (value == 0)
			tick_nohz_disable(0);
	}
	/* Check locks */
	if (attr == &vdd1_lock_attr) {
		if (vdd1_locked) {
			/* vdd1 currently locked */
			if (value == 0) {
				omap_pm_cpu_set_freq(prev_mpu_freq * 1000);
				vdd1_locked = 0;
				return n;
			} else {
				printk(KERN_ERR "%s: vdd1 already locked to %d\n", __func__, vdd1_locked);
				return -EINVAL;
			}
		} else {
			/* vdd1 currently unlocked */
			if (value != 0) {
				u8 i = 0;
				unsigned long freq = 0;
				struct cpufreq_frequency_table *freq_table = *omap_pm_cpu_get_freq_table();
				if (freq_table == NULL) {
					printk(KERN_ERR "%s: Could not get freq_table\n", __func__);
					return -ENODEV;
				}
				for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
					if (freq_table[i].index == value - 1) {
						freq = freq_table[i].frequency;
						break;
					}
				}
				if (freq_table[i].frequency == CPUFREQ_TABLE_END) {
					printk(KERN_ERR "%s: Invalid value [0..%d]\n", __func__, i-1);
					return -EINVAL;
				}
				prev_mpu_freq = omap_pm_cpu_get_freq();
				omap_pm_cpu_set_freq(freq * 1000);
				vdd1_locked = value;

			} else {
				printk(KERN_ERR "%s: vdd1 already unlocked\n", __func__);
				return -EINVAL;
			}
		}
	} else if (attr == &vdd2_lock_attr) {
		if (vdd2_locked) {
			/* vdd2 currently locked */
			if (value == 0) {
				int tmp_lock = vdd2_locked;
				vdd2_locked = 0;
				if (omap_pm_set_min_bus_tput(&sysfs_cpufreq_dev, OCP_INITIATOR_AGENT, -1)) {
					printk(KERN_ERR "%s: Failed to remove vdd2_lock\n", __func__);
					vdd2_locked = tmp_lock; /* restore previous lock */
				} else {
					return n;
				}
			} else {
				printk(KERN_ERR "%s: vdd2 already locked to %d\n", __func__, vdd2_locked);
				return -EINVAL;
			}
		} else {
			/* vdd2 currently unlocked */
			if (value != 0) {
				unsigned long freq = 0;
				if (cpu_is_omap3630()) {
					if(value == 1) {
						freq = 100*1000*4;
					} else if (value == 2) {
						freq = 200*1000*4;
					} else {
						printk(KERN_ERR "%s: Invalid value [1,2]\n", __func__);
						return -EINVAL;
					}
				}
				else if (cpu_is_omap44xx()) {
					if (omap_rev() <= OMAP4430_REV_ES2_0) {
						if(value == 1) {
							freq = 100*1000*4;
						} else if (value == 2) {
							freq = 200*1000*4;
						} else {
							printk(KERN_ERR "%s: Invalid value [1,2]\n", __func__);
							return -EINVAL;
						}
					} else {
						if(value == 1) {
							freq = 98304*4;
						} else if (value == 2) {
							freq = 100*1000*4;
						} else if (value == 3) {
							freq = 200*1000*4;
						} else {
							printk(KERN_ERR "%s: Invalid value [1,2,3]\n", __func__);
							return -EINVAL;
						}
					}
				} else {
					printk(KERN_ERR "%s: Unsupported HW [OMAP3630, OMAP44XX]\n", __func__);
					return -ENODEV;
				}
				if (omap_pm_set_min_bus_tput(&sysfs_cpufreq_dev, OCP_INITIATOR_AGENT, freq)) {
					printk(KERN_ERR "%s: Failed to add vdd2_lock\n", __func__);
				} else {
					vdd2_locked = value;
				}
				return n;
			} else {
				printk(KERN_ERR "%s: vdd2 already unlocked\n", __func__);
				return -EINVAL;
			}
		}
	} else if (attr == &dsp_freq_attr) {
		u8 i, opp_id = 0;
		struct omap_opp *opp_table = omap_pm_dsp_get_opp_table();
		if (opp_table == NULL) {
			printk(KERN_ERR "%s: Could not get dsp opp_table\n", __func__);
			return -ENODEV;
		}
		for (i = 1; opp_table[i].rate; i++) {
			if (opp_table[i].rate >= value) {
				opp_id = i;
				break;
			}
		}
		if (opp_id == 0) {
			printk(KERN_ERR "%s: Invalid value\n", __func__);
			return -EINVAL;
		}
		omap_pm_dsp_set_min_opp(opp_id);

	} else if (attr == &vdd1_opp_attr) {
		printk(KERN_ERR "%s: changing vdd1_opp is not supported\n", __func__);
		return -EINVAL;
	} else if (attr == &vdd2_opp_attr) {
		printk(KERN_ERR "%s: changing vdd2_opp is not supported\n", __func__);
		return -EINVAL;
	} else {
		return -EINVAL;
	}
	return n;
}
Exemplo n.º 16
0
void __init usb_musb_init(struct omap_musb_board_data *board_data)
{
	if (cpu_is_omap44xx())
		omap4430_phy_init(NULL);
}
Exemplo n.º 17
0
void dss_init_overlays(struct platform_device *pdev)
{
	int i, r;

	INIT_LIST_HEAD(&overlay_list);

	num_overlays = 0;

	for (i = 0; i < MAX_DSS_OVERLAYS; ++i) {
		struct omap_overlay *ovl;
		ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);

		BUG_ON(ovl == NULL);

		mutex_init(&ovl->lock);
		mutex_lock(&ovl->lock);

		switch (i) {
		case 0:
			ovl->name = "gfx";
			ovl->id = OMAP_DSS_GFX;
			ovl->supported_modes = (cpu_is_omap44xx() |
				cpu_is_omap34xx()) ?
				OMAP_DSS_COLOR_GFX_OMAP3 :
				OMAP_DSS_COLOR_GFX_OMAP2;
			ovl->caps = OMAP_DSS_OVL_CAP_DISPC;
			ovl->info.global_alpha = 255;
			ovl->info.zorder = OMAP_DSS_OVL_ZORDER_3;
			break;
		case 1:
			ovl->name = "vid1";
			ovl->id = OMAP_DSS_VIDEO1;
			ovl->supported_modes = (cpu_is_omap44xx() |
				cpu_is_omap34xx()) ?
				OMAP_DSS_COLOR_VID1_OMAP3 :
				OMAP_DSS_COLOR_VID_OMAP2;
			ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
				OMAP_DSS_OVL_CAP_DISPC;
			ovl->info.yuv2rgb_conv.type =
				OMAP_DSS_COLOR_CONV_BT601_5_LR;
			ovl->info.yuv2rgb_conv.dirty = true;
			ovl->info.global_alpha = 255;
			ovl->info.zorder = OMAP_DSS_OVL_ZORDER_2;
			break;
		case 2:
			ovl->name = "vid2";
			ovl->id = OMAP_DSS_VIDEO2;
			ovl->supported_modes = (cpu_is_omap44xx() |
				cpu_is_omap34xx()) ?
				OMAP_DSS_COLOR_VID2_OMAP3 :
				OMAP_DSS_COLOR_VID_OMAP2;
			ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
				OMAP_DSS_OVL_CAP_DISPC;
			ovl->info.yuv2rgb_conv.type =
				OMAP_DSS_COLOR_CONV_BT601_5_LR;
			ovl->info.yuv2rgb_conv.dirty = true;
			ovl->info.global_alpha = 255;
			ovl->info.zorder = OMAP_DSS_OVL_ZORDER_1;
			break;
		case 3:
			ovl->name = "vid3";
			ovl->id = OMAP_DSS_VIDEO3;
			ovl->supported_modes = OMAP_DSS_COLOR_VID3_OMAP3;
			ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
				OMAP_DSS_OVL_CAP_DISPC;
			ovl->info.yuv2rgb_conv.type =
				OMAP_DSS_COLOR_CONV_BT601_5_LR;
			ovl->info.yuv2rgb_conv.dirty = true;
			ovl->info.global_alpha = 255;
			ovl->info.zorder = OMAP_DSS_OVL_ZORDER_0;
		}

		ovl->info.min_x_decim = ovl->info.min_y_decim = 1;
		ovl->info.max_x_decim = ovl->info.max_y_decim =
			cpu_is_omap44xx() ? 16 : 1;

		ovl->info_dirty = true;

		ovl->set_manager = &omap_dss_set_manager;
		ovl->unset_manager = &omap_dss_unset_manager;
		ovl->set_overlay_info = &dss_ovl_set_overlay_info;
		ovl->get_overlay_info = &dss_ovl_get_overlay_info;
		ovl->wait_for_go = &dss_ovl_wait_for_go;

		omap_dss_add_overlay(ovl);
		dispc_overlays[i] = ovl;

		r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
				&pdev->dev.kobj, "overlay%d", i);
		if (r)
			DSSERR("failed to create sysfs file\n");

		mutex_unlock(&ovl->lock);
	}

#ifdef L4_EXAMPLE
	{
		struct omap_overlay *ovl;
		ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);

		BUG_ON(ovl == NULL);

		ovl->name = "l4";
		ovl->supported_modes = OMAP_DSS_COLOR_RGB24U;

		ovl->set_manager = &omap_dss_set_manager;
		ovl->unset_manager = &omap_dss_unset_manager;
		ovl->set_overlay_info = &dss_ovl_set_overlay_info;
		ovl->get_overlay_info = &dss_ovl_get_overlay_info;

		omap_dss_add_overlay(ovl);

		r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
				&pdev->dev.kobj, "overlayl4");

		if (r)
			DSSERR("failed to create sysfs file\n");

		l4_overlays[0] = ovl;
	}
#endif
}
Exemplo n.º 18
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 timeout;
	unsigned long internal_clk = 0;
	struct clk *fclk;

	if (dev->rev >= OMAP_I2C_REV_2) {
		/* Disable I2C controller before soft reset */
		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
			omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) &
				~(OMAP_I2C_CON_EN));

		omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK);
		/* For some reason we need to set the EN bit before the
		 * reset done bit gets set. */
		timeout = jiffies + OMAP_I2C_TIMEOUT;
		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
		while (!(omap_i2c_read_reg(dev, OMAP_I2C_SYSS_REG) &
			 SYSS_RESETDONE_MASK)) {
			if (time_after(jiffies, timeout)) {
				dev_warn(dev->dev, "timeout waiting "
						"for controller reset\n");
				return -ETIMEDOUT;
			}
			msleep(1);
		}

		/* SYSC register is cleared by the reset; rewrite it */
		if (dev->rev == OMAP_I2C_REV_ON_2430) {

			omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
					   SYSC_AUTOIDLE_MASK);

		} else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
			dev->syscstate = SYSC_AUTOIDLE_MASK;
			dev->syscstate |= SYSC_ENAWAKEUP_MASK;
			dev->syscstate |= (SYSC_IDLEMODE_SMART <<
			      __ffs(SYSC_SIDLEMODE_MASK));
			dev->syscstate |= (SYSC_CLOCKACTIVITY_FCLK <<
			      __ffs(SYSC_CLOCKACTIVITY_MASK));

			omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
							dev->syscstate);
			/*
			 * 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 */
	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;
		dev->scllstate = scll;
		dev->sclhstate = sclh;
		dev->bufstate = buf;
	}
	return 0;
}
Exemplo n.º 19
0
static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
					struct omap_mmc_platform_data *mmc)
{
	char *hc_name;

	hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL);
	if (!hc_name) {
		pr_err("Cannot allocate memory for controller slot name\n");
		kfree(hc_name);
		return -ENOMEM;
	}

	if (c->name)
		strncpy(hc_name, c->name, HSMMC_NAME_LEN);
	else
		snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i",
								c->mmc, 1);
	mmc->slots[0].name = hc_name;
	mmc->nr_slots = 1;
	mmc->slots[0].caps = c->caps;
	mmc->slots[0].pm_caps = c->pm_caps;
	mmc->slots[0].internal_clock = !c->ext_clock;
	mmc->dma_mask = 0xffffffff;
	mmc->max_freq = c->max_freq;
	if (cpu_is_omap44xx())
		mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
	else
		mmc->reg_offset = 0;

	mmc->get_context_loss_count = hsmmc_get_context_loss;

	mmc->slots[0].switch_pin = c->gpio_cd;
	mmc->slots[0].gpio_wp = c->gpio_wp;

	mmc->slots[0].remux = c->remux;
	mmc->slots[0].init_card = c->init_card;

	if (c->cover_only)
		mmc->slots[0].cover = 1;

	if (c->nonremovable)
		mmc->slots[0].nonremovable = 1;

	if (c->power_saving)
		mmc->slots[0].power_saving = 1;

	if (c->no_off)
		mmc->slots[0].no_off = 1;

	if (c->no_off_init)
		mmc->slots[0].no_regulator_off_init = c->no_off_init;

	if (c->vcc_aux_disable_is_sleep)
		mmc->slots[0].vcc_aux_disable_is_sleep = 1;

	/*
	 * NOTE:  MMC slots should have a Vcc regulator set up.
	 * This may be from a TWL4030-family chip, another
	 * controllable regulator, or a fixed supply.
	 *
	 * temporary HACK: ocr_mask instead of fixed supply
	 */
	if (cpu_is_omap3505() || cpu_is_omap3517())
		mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
					 MMC_VDD_26_27 |
					 MMC_VDD_27_28 |
					 MMC_VDD_29_30 |
					 MMC_VDD_30_31 |
					 MMC_VDD_31_32;
	else
		mmc->slots[0].ocr_mask = c->ocr_mask;

	if (!cpu_is_omap3517() && !cpu_is_omap3505())
		mmc->slots[0].features |= HSMMC_HAS_PBIAS;

	if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
		mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;

	switch (c->mmc) {
	case 1:
		if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
			/* on-chip level shifting via PBIAS0/PBIAS1 */
			if (cpu_is_omap44xx()) {
				mmc->slots[0].before_set_reg =
						omap4_hsmmc1_before_set_reg;
				mmc->slots[0].after_set_reg =
						omap4_hsmmc1_after_set_reg;
			} else {
				mmc->slots[0].before_set_reg =
						omap_hsmmc1_before_set_reg;
				mmc->slots[0].after_set_reg =
						omap_hsmmc1_after_set_reg;
			}
		}

		if (cpu_is_omap3517() || cpu_is_omap3505())
			mmc->slots[0].set_power = nop_mmc_set_power;

		/* OMAP3630 HSMMC1 supports only 4-bit */
		if (cpu_is_omap3630() &&
				(c->caps & MMC_CAP_8_BIT_DATA)) {
			c->caps &= ~MMC_CAP_8_BIT_DATA;
			c->caps |= MMC_CAP_4_BIT_DATA;
			mmc->slots[0].caps = c->caps;
		}
		break;
	case 2:
		if (cpu_is_omap3517() || cpu_is_omap3505())
			mmc->slots[0].set_power = am35x_hsmmc2_set_power;

		if (c->ext_clock)
			c->transceiver = 1;
		if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
			c->caps &= ~MMC_CAP_8_BIT_DATA;
			c->caps |= MMC_CAP_4_BIT_DATA;
		}
		if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
			/* off-chip level shifting, or none */
			mmc->slots[0].before_set_reg = hsmmc2_before_set_reg;
			mmc->slots[0].after_set_reg = NULL;
		}
		break;
	case 3:
	case 4:
	case 5:
		mmc->slots[0].before_set_reg = NULL;
		mmc->slots[0].after_set_reg = NULL;
		break;
	default:
		pr_err("MMC%d configuration not supported!\n", c->mmc);
		kfree(hc_name);
		return -ENODEV;
	}
	return 0;
}
Exemplo n.º 20
0
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{
	int r;

	if (cpu_is_omap44xx() && dssdev->channel != OMAP_DSS_CHANNEL_LCD2) {
		/* Only LCD2 channel is connected to DPI on OMAP4 */
		return -EINVAL;
	}

	r = omap_dss_start_device(dssdev);
	if (r) {
		DSSERR("failed to start device\n");
		return r;
	}

	if (cpu_is_omap34xx() && !cpu_is_omap3630()) {
		r = regulator_enable(dpi.vdds_dsi_reg);
		if (r)
			goto err0;
	}

	/* turn on clock(s) */
	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
	if (!cpu_is_omap44xx())
		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
	dss_mainclk_state_enable();

	dpi_basic_init(dssdev);

#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	r = dsi_pll_init(dssdev, 0, 1);
	if (r)
		goto err1;
#endif /* CONFIG_OMAP2_DSS_USE_DSI_PLL */

	r = dpi_set_mode(dssdev);
	if (r)
		goto err2;

	mdelay(2);

	if (dssdev->manager) {
		if (cpu_is_omap44xx())
			dpi_start_auto_update(dssdev);

		dssdev->manager->enable(dssdev->manager);
	}

	return 0;

err2:
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
	dsi_pll_uninit(dssdev->channel == OMAP_DSS_CHANNEL_LCD ? DSI1 : DSI2);
err1:
#endif
	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
	if (!cpu_is_omap44xx())
		dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
	dss_mainclk_state_disable(true);
	if (cpu_is_omap34xx() && !cpu_is_omap3630())
		regulator_disable(dpi.vdds_dsi_reg);
err0:
	omap_dss_stop_device(dssdev);
	return r;
}
Exemplo n.º 21
0
static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
				    struct snd_pcm_hw_params *params,
				    struct snd_soc_dai *cpu_dai)
{
	struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
	struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
	struct omap_pcm_dma_data *dma_data;
	int dma, bus_id = mcbsp_data->bus_id;
	int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
	int pkt_size = 0;
	unsigned long port;
	unsigned int format, div, framesize, master;

	dma_data = &omap_mcbsp_dai_dma_params[cpu_dai->id][substream->stream];
	if (cpu_class_is_omap1()) {
		dma = omap1_dma_reqs[bus_id][substream->stream];
		port = omap1_mcbsp_port[bus_id][substream->stream];
	} else if (cpu_is_omap2420()) {
		dma = omap24xx_dma_reqs[bus_id][substream->stream];
		port = omap2420_mcbsp_port[bus_id][substream->stream];
	} else if (cpu_is_omap2430()) {
		dma = omap24xx_dma_reqs[bus_id][substream->stream];
		port = omap2430_mcbsp_port[bus_id][substream->stream];
	} else if (cpu_is_omap34xx()) {
		dma = omap24xx_dma_reqs[bus_id][substream->stream];
		port = omap34xx_mcbsp_port[bus_id][substream->stream];
	 } else if (cpu_is_omap44xx()) {
		dma = omap44xx_dma_reqs[bus_id][substream->stream];
		port = omap44xx_mcbsp_port[bus_id][substream->stream];
	} else {
		return -ENODEV;
	}
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		dma_data->data_type = OMAP_DMA_DATA_TYPE_S16;
		wlen = 16;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		dma_data->data_type = OMAP_DMA_DATA_TYPE_S32;
		wlen = 32;
		break;
	default:
		return -EINVAL;
	}
	if (cpu_is_omap34xx()) {
		dma_data->set_threshold = omap_mcbsp_set_threshold;
		/* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
		if (omap_mcbsp_get_dma_op_mode(bus_id) ==
						MCBSP_DMA_MODE_THRESHOLD) {
			int period_words, max_thrsh;

			period_words = params_period_bytes(params) / (wlen / 8);
			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
				max_thrsh = omap_mcbsp_get_max_tx_threshold(
							    mcbsp_data->bus_id);
			else{
				max_thrsh = omap_mcbsp_get_max_rx_threshold(
							    mcbsp_data->bus_id);
				max_thrsh=1;
			}
			/*
				 * If the period contains less or equal number of words,
				 * we are using the original threshold mode setup:
				 * McBSP threshold = sDMA frame size = period_size
				 * Otherwise we switch to sDMA packet mode:
				 * McBSP threshold = sDMA packet size
			 * sDMA frame size = period size
			 */
			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			if (period_words > max_thrsh) {
				int divider = 0;

					/*
					 * Look for the biggest threshold value, which
					 * divides the period size evenly.
				 */
				divider = period_words / max_thrsh;
				if (period_words % max_thrsh)
					divider++;
				while (period_words % divider &&
					divider < period_words)
					divider++;
				if (divider == period_words)
						return -EINVAL;

				pkt_size = period_words / divider;
				sync_mode = OMAP_DMA_SYNC_PACKET;
			} else {
				sync_mode = OMAP_DMA_SYNC_FRAME;
			}
		}	else {
				printk("DMA Element Sync Mode for recording \n");
				sync_mode=OMAP_DMA_SYNC_ELEMENT;				
			}
		}
	}

	dma_data->name = substream->stream ? "Audio Capture" : "Audio Playback";
	dma_data->dma_req = dma;
	dma_data->port_addr = port;
	dma_data->sync_mode = sync_mode;
	dma_data->packet_size = pkt_size;

	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);

	if (mcbsp_data->configured) {
		/* McBSP already configured by another stream */
		return 0;
	}

	format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
	wpf = channels = params_channels(params);
	if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
			      format == SND_SOC_DAIFMT_LEFT_J)) {
		/* Use dual-phase frames */
		regs->rcr2	|= RPHASE;
		regs->xcr2	|= XPHASE;
		/* Set 1 word per (McBSP) frame for phase1 and phase2 */
		wpf--;
		regs->rcr2	|= RFRLEN2(wpf - 1);
		regs->xcr2	|= XFRLEN2(wpf - 1);
	}

	regs->rcr1	|= RFRLEN1(wpf - 1);
	regs->xcr1	|= XFRLEN1(wpf - 1);

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		/* Set word lengths */
		regs->rcr2	|= RWDLEN2(OMAP_MCBSP_WORD_16);
		regs->rcr1	|= RWDLEN1(OMAP_MCBSP_WORD_16);
		regs->xcr2	|= XWDLEN2(OMAP_MCBSP_WORD_16);
		regs->xcr1	|= XWDLEN1(OMAP_MCBSP_WORD_16);
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		/* Set word lengths */
		regs->rcr2	|= RWDLEN2(OMAP_MCBSP_WORD_32);
		regs->rcr1	|= RWDLEN1(OMAP_MCBSP_WORD_32);
		regs->xcr2	|= XWDLEN2(OMAP_MCBSP_WORD_32);
		regs->xcr1	|= XWDLEN1(OMAP_MCBSP_WORD_32);
		break;
	default:
		/* Unsupported PCM format */
		return -EINVAL;
	}

	/* In McBSP master modes, FRAME (i.e. sample rate) is generated
	 * by _counting_ BCLKs. Calculate frame size in BCLKs */
	master = mcbsp_data->fmt & SND_SOC_DAIFMT_MASTER_MASK;
	if (master ==	SND_SOC_DAIFMT_CBS_CFS) {
		div = mcbsp_data->clk_div ? mcbsp_data->clk_div : 1;
		framesize = (mcbsp_data->in_freq / div) / params_rate(params);

		if (framesize < wlen * channels) {
			printk(KERN_ERR "%s: not enough bandwidth for desired rate and "
					"channels\n", __func__);
			return -EINVAL;
		}
	} else
		framesize = wlen * channels;

	/* Set FS period and length in terms of bit clock periods */
	switch (format) {
	case SND_SOC_DAIFMT_I2S:
	case SND_SOC_DAIFMT_LEFT_J:
		regs->srgr2	|= FPER(framesize - 1);
		regs->srgr1	|= FWID((framesize >> 1) - 1);
		break;
	case SND_SOC_DAIFMT_DSP_A:
	case SND_SOC_DAIFMT_DSP_B:
		regs->srgr2	|= FPER(framesize - 1);
		regs->srgr1	|= FWID(0);
		break;
	}

	omap_mcbsp_config(bus_id, &mcbsp_data->regs);
	mcbsp_data->wlen = wlen;
	mcbsp_data->configured = 1;

	return 0;
}
Exemplo n.º 22
0
int dss_init(struct platform_device *pdev)
{
	int r = 0, dss_irq;
	u32 rev;
	struct resource *dss_mem;

#if defined(CONFIG_MACH_LGE_OMAP3)
	// LGE_UPDATE /* to prevent LG logo blinking, it doesn't need to execute below section.*/
	bool skip_init = true;
	// LGE_UPDATE /* to prevent LG logo blinking, it doesn't need to execute below section.*/
#else
	bool skip_init = false;
#endif
	dss.pdata = pdev->dev.platform_data;
	dss.pdev = pdev;
	if (cpu_is_omap44xx())
		dss_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	else
		dss_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!dss_mem) {
		WARN_ON(1);
		r = -ENODEV;
		goto fail0;
	}

	dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
	if (!dss.base) {
		DSSERR("can't ioremap DSS\n");
		r = -ENOMEM;
		goto fail0;
	}
	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M | DSS_CLK_96M);
	dss_mainclk_enable();

#if defined(CONFIG_MACH_LGE_OMAP3)
#else
#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
	/* DISPC_CONTROL */
	if (omap_readl(0x48050440) & 1)	/* LCD enabled? */
		skip_init = true;
#endif
#endif

	if (!skip_init) {
		/* disable LCD and DIGIT output. This seems to fix the synclost
		 * problem that we get, if the bootloader starts the DSS and
		 * the kernel resets it */
		omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);

		/* We need to wait here a bit, otherwise we sometimes start to
		 * get synclost errors, and after that only power cycle will
		 * restore DSS functionality. I have no idea why this happens.
		 * And we have to wait _before_ resetting the DSS, but after
		 * enabling clocks.
		 */
		msleep(50);
	}

	/* autoidle */
	REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);

	/* Select DPLL */
	REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);

#ifdef CONFIG_OMAP2_DSS_VENC
	REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);	/* venc dac demen */
	REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);	/* venc clock 4x enable */
	REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);	/* venc clock mode = normal */
#endif

	if (!cpu_is_omap44xx())
		r = request_irq(INT_24XX_DSS_IRQ,
				cpu_is_omap24xx()
				? dss_irq_handler_omap2
				: dss_irq_handler_omap3,
				0, "OMAP DSS", NULL);
	else {
		dss_irq = platform_get_irq(pdev, 0);
		r = request_irq(dss_irq,
				dss_irq_handler_omap2,
				0, "OMAP DSS", NULL);
	}

	if (r < 0) {
		DSSERR("omap2 dss: request_irq failed\n");
		goto fail1;
	}

	if (cpu_is_omap34xx()) {
		dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
		if (IS_ERR(dss.dpll4_m4_ck)) {
			DSSERR("Failed to get dpll4_m4_ck\n");
			r = PTR_ERR(dss.dpll4_m4_ck);
			goto fail2;
		}
	}

	dss.dsi1_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
	dss.dsi2_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
	dss.lcd1_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
	dss.lcd2_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
	dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK;

	dss_save_context();

	rev = dss_read_reg(DSS_REVISION);
	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M | DSS_CLK_96M);

	return 0;

fail2:
	if (!cpu_is_omap44xx())
		free_irq(INT_24XX_DSS_IRQ, NULL);
fail1:
	iounmap(dss.base);
fail0:
	return r;
}
Exemplo n.º 23
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		powerdm_config_show
 * @BRIEF		decode and display power domain configuration
 * @RETURNS		0 in case of success
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_NOT_AVAILABLE
 * @param[in,out]	stream: output file
 * @param[in]		powerdm: power domain name
 * @DESCRIPTION		decode and display power domain configuration
 *//*------------------------------------------------------------------------ */
int powerdm_config_show(FILE *stream, const char *powerdm)
{
	int ret;
	powerdm_info data;
	pwrdm_state st_last, st_curr, st_tgt;
	reg *pm_pwrstctrl;
	reg *pm_pwrstst;
	char s[64];
	char s1[32], s2[32];

	CHECK_NULL_ARG(stream, OMAPCONF_ERR_ARG);
	CHECK_NULL_ARG(powerdm, OMAPCONF_ERR_ARG);

	ret = _powerdm_info_get(powerdm, &data);
	if (ret != 0) {
		dprintf("%s(%s): could not retrieve powerdm_info struct!\n",
			__func__, powerdm);
		return OMAPCONF_ERR_NOT_AVAILABLE;
	}

	fprintf(stream,
		"|----------------------------------------------------------------|\n");
	strcpy(s, powerdm);
	strcat(s, " Power Domain Configuration");
	fprintf(stream, "| %-62s |\n", s);
	fprintf(stream,
		"|----------------------------------------------------------------|\n");
	fprintf(stream, "| %-32s | %-7s | %-7s | %-7s |\n", "Power State",
		"Current", "Target", "Last");
	fprintf(stream,
		"|----------------------------------|---------|---------|---------|\n");

	st_last = powerdm_state_get(powerdm, PWRDM_STATE_PREVIOUS);
	st_curr = powerdm_state_get(powerdm, PWRDM_STATE_CURRENT);
	st_tgt = powerdm_state_get(powerdm, PWRDM_STATE_TARGET);
	fprintf(stream, "| %-32s | %-7s | %-7s | %-7s |\n",
		"Domain", pwrdm_state_name_get(st_curr),
		pwrdm_state_name_get(st_tgt), pwrdm_state_name_get(st_last));

	if ((!powerdm_has_logic_ret_state_ctrl_bit(powerdm)) &&
		(data.pwrstst == NULL))
		goto powerdm_config_show_mem;

	st_tgt = powerdm_target_logic_ret_state_get(powerdm);
	if (st_tgt != PWRDM_STATE_MAX)
		strcpy(s1, pwrdm_state_name_get(st_tgt));
	else
		strcpy(s1, "");
	st_curr = powerdm_logic_state_get(powerdm);
	if (st_curr != PWRDM_STATE_MAX)
		strcpy(s2, pwrdm_state_name_get(st_curr));
	else
		strcpy(s2, "");
	fprintf(stream, "| %-32s | %-7s | %-7s |         |\n", "Logic", s2, s1);

powerdm_config_show_mem:
	if (cpu_is_omap44xx()) {
		pm_pwrstctrl = powerdm_pwrstctrl_reg_get(powerdm);
		pm_pwrstst = powerdm_pwrstst_reg_get(powerdm);
		ret = pwrdm44xx_config_show(stream, powerdm,
			reg_addr_get(pm_pwrstctrl),
			reg_read(pm_pwrstctrl),
			reg_addr_get(pm_pwrstst),
			reg_read(pm_pwrstst));
	} else if (cpu_is_omap54xx()) {
		ret = pwrdm54xx_config_show(stream, data);
	} else {
		fprintf(stderr,
			"omapconf: %s(): cpu not supported!!!\n", __func__);
		ret = OMAPCONF_ERR_CPU;
	}

	if (data.pwrstst != NULL) {
		fprintf(stream,
			"|----------------------------------------------------------------|\n");

		fprintf(stream, "| %-32s | %-27s |\n",
			"Ongoing Power Transition?",
			((powerdm_in_transition(powerdm) == 1) ? "YES" : "NO"));
	}
	fprintf(stream,
		"|----------------------------------------------------------------|\n\n");

	return ret;
}
Exemplo n.º 24
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;
	int ret;

	/* Soft reset the I2C module */
	ret = omap_i2c_reset(dev);
	if (ret) {
		dev_err(dev->dev, "Unable to softreset I2C module\n");
		return ret;
	}

	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 */
	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;
		dev->scllstate = scll;
		dev->sclhstate = sclh;
		dev->bufstate = buf;
	}
	return 0;
}
Exemplo n.º 25
0
void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
			int nr_controllers)
{
	int i;
	char *name;

	for (i = 0; i < nr_controllers; i++) {
		unsigned long base, size;
		unsigned int irq = 0;

		if (!mmc_data[i])
			continue;

		omap2_mmc_mux(mmc_data[i], i);

		switch (i) {
		case 0:
			base = OMAP2_MMC1_BASE;
			irq = INT_24XX_MMC_IRQ;
			break;
		case 1:
			base = OMAP2_MMC2_BASE;
			irq = INT_24XX_MMC2_IRQ;
			break;
		case 2:
			if (!cpu_is_omap44xx() && !cpu_is_omap34xx())
				return;
			base = OMAP3_MMC3_BASE;
			irq = INT_34XX_MMC3_IRQ;
			break;
		case 3:
			if (!cpu_is_omap44xx())
				return;
			base = OMAP4_MMC4_BASE;
			irq = OMAP44XX_IRQ_MMC4;
			break;
		case 4:
			if (!cpu_is_omap44xx())
				return;
			base = OMAP4_MMC5_BASE;
			irq = OMAP44XX_IRQ_MMC5;
			break;
		default:
			continue;
		}

		if (cpu_is_omap2420()) {
			size = OMAP2420_MMC_SIZE;
			name = "mmci-omap";
		} else if (cpu_is_omap44xx()) {
			if (i < 3)
				irq += OMAP44XX_IRQ_GIC_START;
			size = OMAP4_HSMMC_SIZE;
			name = "mmci-omap-hs";
		} else {
			size = OMAP3_HSMMC_SIZE;
			name = "mmci-omap-hs";
		}
		omap_mmc_add(name, i, base, size, irq, mmc_data[i]);
	};
}
Exemplo n.º 26
0
void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
{
	struct omap_hwmod	*uhh_hwm, *tll_hwm;
	struct platform_device	*pdev;
	int			bus_id = -1;
	int			i;

	for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
		usbhs_data.port_mode[i] = pdata->port_mode[i];
		usbtll_data.port_mode[i] = pdata->port_mode[i];
		ohci_data.port_mode[i] = pdata->port_mode[i];
		ehci_data.port_mode[i] = pdata->port_mode[i];
		ehci_data.reset_gpio_port[i] = pdata->reset_gpio_port[i];
		ehci_data.regulator[i] = pdata->regulator[i];
	}
	ehci_data.phy_reset = pdata->phy_reset;
	ehci_data.phy_clk = pdata->phy_clk;
	ohci_data.es2_compatibility = pdata->es2_compatibility;
	ehci_data.usbhs_update_sar = &usbhs_update_sar;
	ohci_data.usbhs_update_sar = &usbhs_update_sar;
	usbhs_data.ehci_data = &ehci_data;
	usbhs_data.ohci_data = &ohci_data;

	uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
	if (!uhh_hwm) {
		pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
		return;
	}

	tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
	if (!tll_hwm) {
		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
		return;
	}

	l3init_clkdm = clkdm_lookup("l3_init_clkdm");
	if (!l3init_clkdm) {
		pr_err("Failed to get l3_init_clkdm\n");
	}

	pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
				(void *)&usbtll_data, sizeof(usbtll_data),
				omap_uhhtll_latency,
				ARRAY_SIZE(omap_uhhtll_latency), false);
	if (IS_ERR(pdev)) {
		pr_err("Could not build hwmod device %s\n",
			USBHS_TLL_HWMODNAME);
		return;
	}

	pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
				(void *)&usbhs_data, sizeof(usbhs_data),
				omap_uhhtll_latency,
				ARRAY_SIZE(omap_uhhtll_latency), false);
	if (IS_ERR(pdev)) {
		pr_err("Could not build hwmod devices %s\n",
			USBHS_UHH_HWMODNAME);
		return;
	}

	pdev_usbhs = pdev;

	if (cpu_is_omap34xx()) {
		setup_ehci_io_mux(pdata->port_mode);
		setup_ohci_io_mux(pdata->port_mode);
	} else if (cpu_is_omap44xx() || cpu_is_omap54xx())
		uhh_hwm->mux = setup_4430_usbhs_io_mux(pdev, pdata->port_mode);
}
Exemplo n.º 27
0
void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
{
	struct omap_hwmod	*oh[4];
	struct omap_device	*od;
	int			bus_id = -1;
	int			i;

	for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
		usbhs_data.port_mode[i] = pdata->port_mode[i];
		ohci_data.port_mode[i] = pdata->port_mode[i];
		ehci_data.port_mode[i] = pdata->port_mode[i];
		ehci_data.reset_gpio_port[i] = pdata->reset_gpio_port[i];
		ehci_data.regulator[i] = pdata->regulator[i];
		ehci_data.transceiver_clk[i] = pdata->transceiver_clk[i];
	}
	ehci_data.phy_reset = pdata->phy_reset;
	ehci_data.ehci_phy_vbus_not_used = pdata->ehci_phy_vbus_not_used;
	ohci_data.es2_compatibility = pdata->es2_compatibility;
	ohci_data.ohci_phy_suspend = pdata->ohci_phy_suspend;
	usbhs_data.ehci_data = &ehci_data;
	usbhs_data.ohci_data = &ohci_data;

	oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
	if (!oh[0]) {
		pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
		return;
	}

	oh[1] = omap_hwmod_lookup(USBHS_OHCI_HWMODNAME);
	if (!oh[1]) {
		pr_err("Could not look up %s\n", USBHS_OHCI_HWMODNAME);
		return;
	}

	oh[2] = omap_hwmod_lookup(USBHS_EHCI_HWMODNAME);
	if (!oh[2]) {
		pr_err("Could not look up %s\n", USBHS_EHCI_HWMODNAME);
		return;
	}

	oh[3] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
	if (!oh[3]) {
		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
		return;
	}

	if (cpu_is_omap34xx()) {
		setup_ehci_io_mux(pdata->port_mode);
		setup_ohci_io_mux(pdata->port_mode);
	} else if (cpu_is_omap44xx()) {
		oh[2]->mux = setup_4430ehci_io_mux(pdata->port_mode);
		if (oh[2]->mux)
			omap_hwmod_mux(oh[2]->mux, _HWMOD_STATE_ENABLED);
		oh[1]->mux = setup_4430ohci_io_mux(pdata->port_mode);
		if (oh[1]->mux)
			omap_hwmod_mux(oh[1]->mux, _HWMOD_STATE_ENABLED);
	}

	if (cpu_is_omap44xx()) {
		setup_4430ehci_drvstrength(pdata->port_mode);
		/* TODO - implement for OHCI*/
	}

	od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 4,
				(void *)&usbhs_data, sizeof(usbhs_data),
				omap_uhhtll_latency,
				ARRAY_SIZE(omap_uhhtll_latency), false);

	if (IS_ERR(od)) {
		pr_err("Could not build hwmod devices %s, %s\n",
			USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
		return;
	}

	usbhs_wake = kmalloc(sizeof(*usbhs_wake), GFP_KERNEL);
	if (!usbhs_wake) {
		pr_err("Could not allocate usbhs_wake\n");
		return;
	}

	INIT_WORK(&usbhs_wake->wakeup_work, usbhs_resume_work);
	usbhs_wake->oh_ehci = oh[2];
	usbhs_wake->oh_ohci = oh[1];
	usbhs_wake->dev = &od->pdev.dev;
}
Exemplo n.º 28
0
static int __init hdcp_init(void)
{
	HDCP_DBG("hdcp_init() %ums\n", jiffies_to_msecs(jiffies));

	if (cpu_is_omap44xx()) {
	        /* Map HDMI WP address */
	        hdcp.hdmi_wp_base_addr = ioremap(HDMI_WP, 0x1000);
	        if (!hdcp.hdmi_wp_base_addr) {
	                printk(KERN_ERR "HDCP: HDMI WP IOremap error\n");
	                return -EFAULT;
	        }
	} else {
		hdcp.hdmi_wp_base_addr = NULL;
	}

	hdcp.hdcp_work = kzalloc(sizeof(struct hdcp_worker_data), GFP_KERNEL);
	if (!hdcp.hdcp_work) {
		HDCP_ERR("Could not allocate HDCP worker  structure\n");
		goto err_alloc_work;
	}

	hdcp.mdev = kzalloc(sizeof(struct miscdevice), GFP_KERNEL);
	if (!hdcp.mdev) {
		HDCP_ERR("Could not allocate misc device memory\n");
		goto err_alloc_mdev;
	}

	/* Map DESHDCP in kernel address space */
	hdcp.deshdcp_base_addr = ioremap(DSS_SS_FROM_L3__DESHDCP, 0x34);

	if (!hdcp.deshdcp_base_addr) {
		HDCP_ERR("DESHDCP IOremap error\n");
		goto err_map_deshdcp;
	}

	mutex_init(&hdcp.lock);

	hdcp.mdev->minor = MISC_DYNAMIC_MINOR;
	hdcp.mdev->name = "hdcp";
	hdcp.mdev->mode = 0666;
	hdcp.mdev->fops = &hdcp_fops;

	if (misc_register(hdcp.mdev)) {
		HDCP_ERR("Could not add character driver\n");
		goto err_misc_register;
	}

	mutex_lock(&hdcp.lock);

        /* Variable init */
        hdcp.en_ctrl  = 0;
        hdcp.hdcp_state = HDCP_DISABLED;
        hdcp.pending_start = 0;
        hdcp.pending_wq_event = 0;
        hdcp.retry_cnt = 0;
        hdcp.auth_state = HDCP_STATE_DISABLED;
        hdcp.pending_disable = 0;
        hdcp.hdcp_up_event = 0;
        hdcp.hdcp_down_event = 0;
        hdcp_wait_re_entrance = 0;
        hdcp.hpd_low = 0;

        spin_lock_init(&hdcp.spinlock);

        init_completion(&hdcp_comp);

	hdcp.workqueue = create_singlethread_workqueue("hdcp");
	if (hdcp.workqueue == NULL) {
		HDCP_ERR("Could not create HDCP workqueue\n");
		goto err_add_driver;
	}

	INIT_DELAYED_WORK(&hdcp.hdcp_work->dwork, hdcp_work_queue);

	mutex_init(&hdcp.re_entrant_lock);

	if (hdmi_runtime_get()) {
		HDCP_ERR("%s Error enabling clocks\n", __func__);
		goto err_runtime;
	}

	/* Register HDCP callbacks to HDMI library */
	if (cpu_is_omap44xx())
		omapdss_hdmi_register_hdcp_callbacks(&omap4_hdcp_start_frame_cb,
				 &omap4_hdcp_3des_cb, &omap4_hdcp_irq_cb);
	else
		omapdss_hdmi_register_hdcp_callbacks(&hdcp_start_frame_cb,
				 &hdcp_3des_cb, &hdcp_irq_cb);

	hdmi_runtime_put();

        mutex_unlock(&hdcp.lock);

	hdcp_load_keys();

	return 0;

err_runtime:
	mutex_destroy(&hdcp.re_entrant_lock);

	destroy_workqueue(hdcp.workqueue);

err_add_driver:
	misc_deregister(hdcp.mdev);

	mutex_unlock(&hdcp.lock);

err_misc_register:
	mutex_destroy(&hdcp.lock);

	iounmap(hdcp.deshdcp_base_addr);

err_map_deshdcp:
	kfree(hdcp.mdev);

err_alloc_mdev:
	kfree(hdcp.hdcp_work);

err_alloc_work:
	if (cpu_is_omap44xx())
		iounmap(hdcp.hdmi_wp_base_addr);

	return -EFAULT;
}
Exemplo n.º 29
0
static __devinit int omap_hdmi_probe(struct platform_device *pdev)
{
    int ret;
    struct resource *hdmi_rsrc;
    struct omap_dss_device *dssdev = NULL;
    bool hdmi_dev_found = false;

    hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!hdmi_rsrc) {
        dev_err(&pdev->dev, "Cannot obtain IORESOURCE_MEM HDMI\n");
        return -ENODEV;
    }

    omap_hdmi_dai_dma_params.port_addr =  hdmi_rsrc->start
                                          + OMAP_HDMI_AUDIO_DMA_PORT;

    hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0);
    if (!hdmi_rsrc) {
        dev_err(&pdev->dev, "Cannot obtain IORESOURCE_DMA HDMI\n");
        return -ENODEV;
    }

    hdmi.oh = omap_hwmod_lookup("dss_hdmi");
    if (!hdmi.oh) {
        dev_err(&pdev->dev, "can't find omap_hwmod for hdmi\n");
        return -ENODEV;
    }

    omap_hdmi_dai_dma_params.dma_req =  hdmi_rsrc->start;

    /*
     * Find an HDMI device. In the future, registers all the HDMI devices
     * it finds and create a PCM for each.
     */
    for_each_dss_dev(dssdev) {
        omap_dss_get_device(dssdev);

        if (!dssdev->driver) {
            omap_dss_put_device(dssdev);
            continue;
        }

        if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
            hdmi_dev_found = true;
            break;
        }
    }

    if (!hdmi_dev_found) {
        dev_err(&pdev->dev, "no driver for HDMI display found");
        return -ENODEV;
    }

    hdmi.dssdev = dssdev;

    /* the supported rates and sample format depend on the cpu */
    if (cpu_is_omap44xx()) {
        omap_hdmi_dai.playback.rates = OMAP4_HDMI_RATES;
        omap_hdmi_dai.playback.formats = OMAP4_HDMI_FORMATS;
        omap_hdmi_dai.playback.channels_max	= 8;
    } else { /* OMAP5 */
        omap_hdmi_dai.playback.rates = OMAP5_HDMI_RATES;
        omap_hdmi_dai.playback.formats = OMAP5_HDMI_FORMATS;
#ifdef CONFIG_ARCH_OMAP5_ES1
        omap_hdmi_dai.playback.channels_max	= 2;
#else
        omap_hdmi_dai.playback.channels_max	= 8;
#endif
    }
    ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai);

    hdmi.notifier.notifier_call = hdmi_audio_notifier_callback;
    blocking_notifier_chain_register(&hdmi.dssdev->state_notifiers,
                                     &hdmi.notifier);

    return ret;
}
Exemplo n.º 30
0
int __init musb_platform_init(struct musb *musb)
{
	u32 l;
	struct device *dev = musb->controller;
	struct musb_hdrc_platform_data *plat = dev->platform_data;
	struct omap_musb_board_data *data = plat->board_data;
	int status;

	/* We require some kind of external transceiver, hooked
	 * up through ULPI.  TWL4030-family PMICs include one,
	 * which needs a driver, drivers aren't always needed.
	 */
	musb->xceiv = otg_get_transceiver();
	if (!musb->xceiv) {
		pr_err("HS USB OTG: no transceiver configured\n");
		return -ENODEV;
	}

	if (cpu_is_omap44xx()) {
		/* disable the optional 60M clock if enabled by romcode*/
		l = omap_readl(0x4A009360);
		l &= ~0x00000100;
		omap_writel(l, 0x4A009360);
		omap_writel(0x1, 0x4A002300);
	}

	/* Fixme this can be enabled when load the gadget driver also*/
	musb_platform_resume(musb);

	/*powerup the phy as romcode would have put the phy in some state
	* which is impacting the core retention if the gadget driver is not
	* loaded.
	*/
	l = musb_readl(musb->mregs, OTG_INTERFSEL);

	if (data->interface_type == MUSB_INTERFACE_UTMI) {
		/* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
		l &= ~ULPI_12PIN;       /* Disable ULPI */
		l |= UTMI_8BIT;         /* Enable UTMI  */
	} else {
		l |= ULPI_12PIN;
	}

	musb_writel(musb->mregs, OTG_INTERFSEL, l);

	pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
			"sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
			musb_readl(musb->mregs, OTG_REVISION),
			musb_readl(musb->mregs, OTG_SYSCONFIG),
			musb_readl(musb->mregs, OTG_SYSSTATUS),
			musb_readl(musb->mregs, OTG_INTERFSEL),
			musb_readl(musb->mregs, OTG_SIMENABLE));

	if (is_host_enabled(musb))
		musb->board_set_vbus = omap_set_vbus;

	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
	plat->is_usb_active = is_musb_active;

	if (cpu_is_omap44xx()) {
		wake_lock_init(&usb_lock, WAKE_LOCK_SUSPEND, "musb_wake_lock");

		/* register for transciever notification*/
		status = otg_register_notifier(musb->xceiv, &musb->nb);

		if (status) {
			DBG(1, "notification register failed\n");
			wake_lock_destroy(&usb_lock);
		}
	}
	return 0;
}