Пример #1
0
static int clk_di_get_parent(struct clk *clk)
{
	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
	u32 val;

	val = ipu_di_read(di, DI_GENERAL);

	return val & DI_GEN_DI_CLK_EXT ? 1 : 0;
}
Пример #2
0
static void ipu_di_data_pin_config(struct ipu_di *di, int wave_gen, int di_pin,
		int set, int up, int down)
{
	u32 reg;

	reg = ipu_di_read(di, DI_DW_GEN(wave_gen));
	reg &= ~(0x3 << (di_pin * 2));
	reg |= set << (di_pin * 2);
	ipu_di_write(di, reg, DI_DW_GEN(wave_gen));

	ipu_di_write(di, (down << 16) | up, DI_DW_SET(wave_gen, set));
}
Пример #3
0
static unsigned long clk_di_recalc_rate(struct clk *clk,
		unsigned long parent_rate)
{
	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
	unsigned long outrate;
	u32 div = ipu_di_read(di, DI_BS_CLKGEN0);

	if (div < 0x10)
		div = 0x10;

	outrate = (parent_rate / div) * 16;

	return outrate;
}
Пример #4
0
static int clk_di_set_parent(struct clk *clk, u8 index)
{
	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
	u32 val;

	val = ipu_di_read(di, DI_GENERAL);

	if (index)
		val |= DI_GEN_DI_CLK_EXT;
	else
		val &= ~DI_GEN_DI_CLK_EXT;

	ipu_di_write(di, val, DI_GENERAL);

	return 0;
}
Пример #5
0
static int clk_di_set_rate(struct clk *clk, unsigned long rate,
				unsigned long parent_rate)
{
	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
	int div;
	u32 clkgen0;

	clkgen0 = ipu_di_read(di, DI_BS_CLKGEN0) & ~0xfff;

	div = ipu_di_clk_calc_div(parent_rate, rate);

	ipu_di_write(di, clkgen0 | div, DI_BS_CLKGEN0);

	dev_dbg(di->ipu->dev, "%s: inrate: %ld desired: %ld div: 0x%08x\n",
			__func__, parent_rate, rate, div);
	return 0;
}
Пример #6
0
static void ipu_di_sync_config(struct ipu_di *di, struct di_sync_config *config,
		int start, int count)
{
	u32 reg;
	int i;

	for (i = 0; i < count; i++) {
		struct di_sync_config *c = &config[i];
		int wave_gen = start + i + 1;

		if ((c->run_count >= 0x1000) || (c->offset_count >= 0x1000) ||
				(c->repeat_count >= 0x1000) ||
				(c->cnt_up >= 0x400) ||
				(c->cnt_down >= 0x400)) {
			dev_err(di->ipu->dev, "DI%d counters out of range.\n",
					di->id);
			return;
		}

		reg = DI_SW_GEN0_RUN_COUNT(c->run_count) |
			DI_SW_GEN0_RUN_SRC(c->run_src) |
			DI_SW_GEN0_OFFSET_COUNT(c->offset_count) |
			DI_SW_GEN0_OFFSET_SRC(c->offset_src);
		ipu_di_write(di, reg, DI_SW_GEN0(wave_gen));

		reg = DI_SW_GEN1_CNT_POL_GEN_EN(c->cnt_polarity_gen_en) |
			DI_SW_GEN1_CNT_CLR_SRC(c->cnt_clr_src) |
			DI_SW_GEN1_CNT_POL_TRIGGER_SRC(
					c->cnt_polarity_trigger_src) |
			DI_SW_GEN1_CNT_POL_CLR_SRC(c->cnt_polarity_clr_src) |
			DI_SW_GEN1_CNT_DOWN(c->cnt_down) |
			DI_SW_GEN1_CNT_UP(c->cnt_up);

		/* Enable auto reload */
		if (c->repeat_count == 0)
			reg |= DI_SW_GEN1_AUTO_RELOAD;

		ipu_di_write(di, reg, DI_SW_GEN1(wave_gen));

		reg = ipu_di_read(di, DI_STP_REP(wave_gen));
		reg &= ~(0xffff << (16 * ((wave_gen - 1) & 0x1)));
		reg |= c->repeat_count << (16 * ((wave_gen - 1) & 0x1));
		ipu_di_write(di, reg, DI_STP_REP(wave_gen));
	}
}
static int _ipu_pixel_clk_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_di_mux *mux = to_clk_di_mux(hw);
	struct ipu_soc *ipu = ipu_get_soc(mux->ipu_id);
	u32 di_gen;

	di_gen = ipu_di_read(ipu, mux->di_id, DI_GENERAL);
	if (index == 0)
		/* ipu1_clk or ipu2_clk internal clk */
		di_gen &= ~DI_GEN_DI_CLK_EXT;
	else
		di_gen |= DI_GEN_DI_CLK_EXT;

	ipu_di_write(ipu, mux->di_id, di_gen, DI_GENERAL);
	mux->index = index;
	pr_debug("ipu_pixel_clk: di_clk_ext:0x%x, di_gen reg:0x%x.\n",
			!(di_gen & DI_GEN_DI_CLK_EXT), di_gen);
	return 0;
}
static unsigned long _ipu_pixel_clk_div_recalc_rate(struct clk_hw *hw,
					unsigned long parent_rate)
{
	struct clk_di_div *di_div = to_clk_di_div(hw);
	struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
	u32 div;
	u64 final_rate = (unsigned long long)parent_rate * 16;

	_ipu_get(ipu);
	div = ipu_di_read(ipu, di_div->di_id, DI_BS_CLKGEN0);
	_ipu_put(ipu);
	pr_debug("ipu_di%d read BS_CLKGEN0 div:%d, final_rate:%lld, prate:%ld\n",
			di_div->di_id, div, final_rate, parent_rate);

	if (div == 0)
		return 0;
	final_rate = udiv64(final_rate, div);

	return (unsigned long)final_rate;
}
Пример #9
0
static long clk_di_round_rate(struct clk *clk, unsigned long rate,
				unsigned long *prate)
{
	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
	unsigned long outrate;
	int div;
	u32 val;

	div = ipu_di_clk_calc_div(*prate, rate);

	outrate = (*prate / div) * 16;

	val = ipu_di_read(di, DI_GENERAL);

	if (!(val & DI_GEN_DI_CLK_EXT) && outrate > *prate / 2)
		outrate = *prate / 2;

	dev_dbg(di->ipu->dev,
		"%s: inrate: %ld div: 0x%08x outrate: %ld wanted: %ld\n",
			__func__, *prate, div, outrate, rate);

	return outrate;
}
Пример #10
0
			.repeat_count = sig->mode.hactive,
			.cnt_clr_src = 5,
		}, {
			.run_count = v_total - 1,
			.run_src = DI_SYNC_INT_HSYNC,
			.offset_count = v_total / 2,
			.offset_src = DI_SYNC_INT_HSYNC,
			.cnt_clr_src = DI_SYNC_HSYNC,
			.cnt_down = 4,
		}
	};

	ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));

	/* set gentime select and tag sel */
	reg = ipu_di_read(di, DI_SW_GEN1(9));
	reg &= 0x1FFFFFFF;
	reg |= (3 - 1) << 29 | 0x00008000;
	ipu_di_write(di, reg, DI_SW_GEN1(9));

	ipu_di_write(di, v_total / 2 - 1, DI_SCR_CONF);
}

static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
		struct ipu_di_signal_cfg *sig, int div)
{
	u32 h_total = sig->mode.hactive + sig->mode.hsync_len +
		sig->mode.hback_porch + sig->mode.hfront_porch;
	u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
		sig->mode.vback_porch + sig->mode.vfront_porch;
	struct di_sync_config cfg[] = {