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; }
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; }
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; }