static int _ipu_pixel_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long parent_clk_rate)
{
	struct clk_di_div *di_div = to_clk_di_div(hw);
	struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
	u64 div, parent_rate;
	u64 remainder;

	parent_rate = (unsigned long long)parent_clk_rate * 16;
	div = parent_rate;
	div = do_udiv64(div, rate, &remainder);
	/* 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)
		pr_err("Overflow, di:%d, DI_BS_CLKGEN0 div:0x%x\n",
				di_div->di_id, (u32)div);
	_ipu_get(ipu);
	ipu_di_write(ipu, di_div->di_id, (u32)div, DI_BS_CLKGEN0);

	/* Setup pixel clock timing */
	/* FIXME: needs to be more flexible */
	/* Down time is half of period */
	ipu_di_write(ipu, di_div->di_id, ((u32)div / 16) << 16, DI_BS_CLKGEN1);
	_ipu_put(ipu);

	return 0;
}
static long _ipu_pixel_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long *parent_clk_rate)
{
	u64 div, final_rate;
	u64 remainder;
	u64 parent_rate = (unsigned long long)(*parent_clk_rate) * 16;

	/*
	 * Calculate divider
	 * Fractional part is 4 bits,
	 * so simply multiply by 2^4 to get fractional part.
	 */
	div = parent_rate;
	div = do_udiv64(div, rate, &remainder);
	/* Round the divider value */
	if (remainder > (rate/2))
		div++;
	if (div < 0x10)            /* Min DI disp clock divider is 1 */
		div = 0x10;
	if (div & ~0xFEF)
		div &= 0xFF8;
	else {
		/* Round up divider if it gets us closer to desired pix clk */
		if ((div & 0xC) == 0xC) {
			div += 0x10;
			div &= ~0xF;
		}
	}
	final_rate = parent_rate;
	final_rate = udiv64(final_rate, div);

	return final_rate;
}
Example #3
0
static int printi(char **out, u32 *out_len, long long i, int b, int sg,
		  int width, int flags, int letbase)
{
	char print_buf[PRINT_BUF_LEN];
	char *s;
	int neg = 0, pc = 0;
	u64 t;
	unsigned long long u = i;

	if (sg && b == 10 && i < 0) {
		neg = 1;
		u = -i;
	}

	s = print_buf + PRINT_BUF_LEN - 1;
	*s = '\0';

	if (!u) {
		*--s = '0';
	} else {
		while (u) {
                	u = do_udiv64(u, b, &t);
			if (t >= 10)
				t += letbase - '0' - 10;
			*--s = t + '0';
		}
	}

	if (flags & PAD_ALTERNATE) {
		if ((b == 16) && (letbase == 'A')) {
			*--s = 'X';
		} else if ((b == 16) && (letbase == 'a')) {
			*--s = 'x';
		}
		*--s = '0';
	}

	if (neg) {
		if (width && (flags & PAD_ZERO)) {
			printc(out, out_len, '-');
			++pc;
			--width;
		} else {
			*--s = '-';
		}
	}

	return pc + prints(out, out_len, s, width, flags);
}