static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
{
	u64 div, parent_rate;
	u32 remainder;

	parent_rate = (unsigned long long)clk->parent->rate * 16;
	div = parent_rate;
	remainder = do_div(div, rate);
	/* Round the divider value */
	if (remainder > (rate / 2))
		div++;

	/* Round up divider if it gets us closer to desired pix clk */
	if ((div & 0xC) == 0xC) {
		div += 0x10;
		div &= ~0xF;
	}
	if (div > 0x1000)
		debug("Overflow, DI_BS_CLKGEN0 div:0x%x\n", (u32)div);

	__raw_writel(div, DI_BS_CLKGEN0(clk->id));

	/*
	 * Setup pixel clock timing
	 * Down time is half of period
	 */
	__raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id));

	clk->rate = (u64)(clk->parent->rate * 16) / div;

	return 0;
}
Example #2
0
static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
{
	u32 div = (clk->parent->rate * 16) / rate;

	__raw_writel(div, DI_BS_CLKGEN0(clk->id));

	/* Setup pixel clock timing */
	__raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id));

	clk->rate = (clk->parent->rate * 16) / div;
	return 0;
}
Example #3
0
static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
{
	u32 div = (clk->parent->rate * 16) / rate;

	__raw_writel(div, DI_BS_CLKGEN0(clk->id));

	/* Setup pixel clock timing */
	/* Shift the pixel clock a little bit (1/4 - 3/4) */
	__raw_writel( ((div * 3 / 32) << 16) | (div / 32), DI_BS_CLKGEN1(clk->id) );

	clk->rate = (clk->parent->rate * 16) / div;
	return 0;
}