|
@@ -231,6 +231,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
|
|
|
u32 round, ick;
|
|
|
u32 scl;
|
|
|
u32 cdf_width;
|
|
|
+ unsigned long rate;
|
|
|
|
|
|
if (!clkp) {
|
|
|
dev_err(dev, "there is no peripheral_clk\n");
|
|
@@ -264,15 +265,14 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
|
|
|
* clkp : peripheral_clk
|
|
|
* F[] : integer up-valuation
|
|
|
*/
|
|
|
- for (cdf = 0; cdf < (1 << cdf_width); cdf++) {
|
|
|
- ick = clk_get_rate(clkp) / (1 + cdf);
|
|
|
- if (ick < 20000000)
|
|
|
- goto ick_find;
|
|
|
+ rate = clk_get_rate(clkp);
|
|
|
+ cdf = rate / 20000000;
|
|
|
+ if (cdf >= 1 << cdf_width) {
|
|
|
+ dev_err(dev, "Input clock %lu too high\n", rate);
|
|
|
+ return -EIO;
|
|
|
}
|
|
|
- dev_err(dev, "there is no best CDF\n");
|
|
|
- return -EIO;
|
|
|
+ ick = rate / (cdf + 1);
|
|
|
|
|
|
-ick_find:
|
|
|
/*
|
|
|
* it is impossible to calculate large scale
|
|
|
* number on u32. separate it
|
|
@@ -290,6 +290,12 @@ ick_find:
|
|
|
*
|
|
|
* Calculation result (= SCL) should be less than
|
|
|
* bus_speed for hardware safety
|
|
|
+ *
|
|
|
+ * We could use something along the lines of
|
|
|
+ * div = ick / (bus_speed + 1) + 1;
|
|
|
+ * scgd = (div - 20 - round + 7) / 8;
|
|
|
+ * scl = ick / (20 + (scgd * 8) + round);
|
|
|
+ * (not fully verified) but that would get pretty involved
|
|
|
*/
|
|
|
for (scgd = 0; scgd < 0x40; scgd++) {
|
|
|
scl = ick / (20 + (scgd * 8) + round);
|