Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/nvidia Fix fractional divider calculations and ...



details:   https://anonhg.NetBSD.org/src/rev/e08e419b90ba
branches:  trunk
changeset: 823426:e08e419b90ba
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Apr 22 17:40:47 2017 +0000

description:
Fix fractional divider calculations and round down for sdmmc clocks.

diffstat:

 sys/arch/arm/nvidia/tegra124_car.c |  36 ++++++++++++++++++++++++++++++++----
 1 files changed, 32 insertions(+), 4 deletions(-)

diffs (76 lines):

diff -r 3fca5fdae995 -r e08e419b90ba sys/arch/arm/nvidia/tegra124_car.c
--- a/sys/arch/arm/nvidia/tegra124_car.c        Sat Apr 22 16:02:39 2017 +0000
+++ b/sys/arch/arm/nvidia/tegra124_car.c        Sat Apr 22 17:40:47 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra124_car.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $ */
+/* $NetBSD: tegra124_car.c,v 1.11 2017/04/22 17:40:47 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.11 2017/04/22 17:40:47 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -1204,6 +1204,16 @@
 }
 
 static u_int
+tegra124_car_clock_calc_rate_frac_div(u_int rate, u_int raw_div)
+{
+       raw_div += 2;
+       rate *= 2;
+       rate += raw_div - 1;
+       rate /= raw_div;
+       return rate;
+}
+
+static u_int
 tegra124_car_clock_get_rate_div(struct tegra124_car_softc *sc,
     struct tegra_clk *tclk)
 {
@@ -1235,13 +1245,15 @@
        case CAR_CLKSRC_UARTC_REG:
        case CAR_CLKSRC_UARTD_REG:
                if (v & CAR_CLKSRC_UART_DIV_ENB) {
-                       rate = parent_rate * 2 / (raw_div + 2);
+                       rate = tegra124_car_clock_calc_rate_frac_div(
+                           parent_rate, raw_div);
                } else {
                        rate = parent_rate;
                }
                break;
        default:
-               rate = parent_rate * 2 / (raw_div + 2);
+               rate = tegra124_car_clock_calc_rate_frac_div(parent_rate,
+                   raw_div);
                break;
        }
 
@@ -1301,6 +1313,22 @@
                if (rate)
                        raw_div = parent_rate / rate - 1;
                break;
+       case CAR_CLKSRC_SDMMC1_REG:
+       case CAR_CLKSRC_SDMMC2_REG:
+       case CAR_CLKSRC_SDMMC3_REG:
+       case CAR_CLKSRC_SDMMC4_REG:
+               if (rate) {
+                       for (raw_div = 0x00; raw_div <= 0xff; raw_div++) {
+                               u_int calc_rate =
+                                   tegra124_car_clock_calc_rate_frac_div(
+                                       parent_rate, raw_div);
+                               if (calc_rate <= rate)
+                                       break;
+                       }
+                       if (raw_div == 0x100)
+                               return EINVAL;
+               }
+               break;
        default:
                if (rate)
                        raw_div = (parent_rate * 2) / rate - 2;



Home | Main Index | Thread Index | Old Index