Exemple #1
0
int tegra_mipi_calibrate(struct tegra_mipi_device *device)
{
	const struct tegra_mipi_config *cfg = device->config;
	unsigned long value, clk_value;
	unsigned int i;
	int err;

	value = tegra_mipi_readl(device->mipi, MIPI_CAL_BIAS_PAD_CFG0);
	value &= ~MIPI_CAL_BIAS_PAD_PDVCLAMP;
	value |= MIPI_CAL_BIAS_PAD_E_VCLAMP_REF;
	tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG0);

	tegra_mipi_writel(device->mipi, MIPI_CAL_BIAS_PAD_CFG1_DEFAULT,
			 MIPI_CAL_BIAS_PAD_CFG1);

	value = tegra_mipi_readl(device->mipi, MIPI_CAL_BIAS_PAD_CFG2);
	value &= ~MIPI_CAL_BIAS_PAD_PDVREG;
	tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG2);

	for (i = 0; i < cfg->num_pads; i++) {
		if (device->pads & BIT(i)) {
			value = MIPI_CAL_CONFIG_SELECT |
				MIPI_CAL_CONFIG_HSPDOS(0) |
				MIPI_CAL_CONFIG_HSPUOS(4) |
				MIPI_CAL_CONFIG_TERMOS(5);
			clk_value = MIPI_CAL_CONFIG_SELECT |
				    MIPI_CAL_CONFIG_HSCLKPDOSD(0) |
				    MIPI_CAL_CONFIG_HSCLKPUOSD(4);
		} else {
			value = 0;
			clk_value = 0;
		}

		tegra_mipi_writel(device->mipi, value, cfg->regs[i].data);

		if (cfg->calibrate_clk_lane)
			tegra_mipi_writel(device->mipi, clk_value,
					cfg->regs[i].clk);
	}

	value = tegra_mipi_readl(device->mipi, MIPI_CAL_CTRL);
	value |= MIPI_CAL_CTRL_START;
	tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);

	err = tegra_mipi_wait(device->mipi);

	return err;
}
Exemple #2
0
int tegra_mipi_calibrate(struct tegra_mipi_device *device)
{
	const struct tegra_mipi_soc *soc = device->mipi->soc;
	unsigned int i;
	u32 value;
	int err;

	err = clk_enable(device->mipi->clk);
	if (err < 0)
		return err;

	mutex_lock(&device->mipi->lock);

	value = MIPI_CAL_BIAS_PAD_DRV_DN_REF(soc->pad_drive_down_ref) |
		MIPI_CAL_BIAS_PAD_DRV_UP_REF(soc->pad_drive_up_ref);
	tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG1);

	value = tegra_mipi_readl(device->mipi, MIPI_CAL_BIAS_PAD_CFG2);
	value &= ~MIPI_CAL_BIAS_PAD_VCLAMP(0x7);
	value &= ~MIPI_CAL_BIAS_PAD_VAUXP(0x7);
	value |= MIPI_CAL_BIAS_PAD_VCLAMP(soc->pad_vclamp_level);
	value |= MIPI_CAL_BIAS_PAD_VAUXP(soc->pad_vauxp_level);
	tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG2);

	for (i = 0; i < soc->num_pads; i++) {
		u32 clk = 0, data = 0;

		if (device->pads & BIT(i)) {
			data = MIPI_CAL_CONFIG_SELECT |
			       MIPI_CAL_CONFIG_HSPDOS(soc->hspdos) |
			       MIPI_CAL_CONFIG_HSPUOS(soc->hspuos) |
			       MIPI_CAL_CONFIG_TERMOS(soc->termos);
			clk = MIPI_CAL_CONFIG_SELECT |
			      MIPI_CAL_CONFIG_HSCLKPDOSD(soc->hsclkpdos) |
			      MIPI_CAL_CONFIG_HSCLKPUOSD(soc->hsclkpuos);
		}

		tegra_mipi_writel(device->mipi, data, soc->pads[i].data);

		if (soc->has_clk_lane && soc->pads[i].clk != 0)
			tegra_mipi_writel(device->mipi, clk, soc->pads[i].clk);
	}

	value = tegra_mipi_readl(device->mipi, MIPI_CAL_CTRL);
	value &= ~MIPI_CAL_CTRL_NOISE_FILTER(0xf);
	value &= ~MIPI_CAL_CTRL_PRESCALE(0x3);
	value |= MIPI_CAL_CTRL_NOISE_FILTER(0xa);
	value |= MIPI_CAL_CTRL_PRESCALE(0x2);

	if (!soc->clock_enable_override)
		value &= ~MIPI_CAL_CTRL_CLKEN_OVR;
	else
		value |= MIPI_CAL_CTRL_CLKEN_OVR;

	tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);

	/* clear any pending status bits */
	value = tegra_mipi_readl(device->mipi, MIPI_CAL_STATUS);
	tegra_mipi_writel(device->mipi, value, MIPI_CAL_STATUS);

	value = tegra_mipi_readl(device->mipi, MIPI_CAL_CTRL);
	value |= MIPI_CAL_CTRL_START;
	tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);

	err = tegra_mipi_wait(device->mipi);

	mutex_unlock(&device->mipi->lock);
	clk_disable(device->mipi->clk);

	return err;
}