On Sun, Jan 31, 2016 at 01:14:35AM +0100, Patrick Wildt wrote:
> Hi,
> 
> one of the reasons Allwinner A20/sun7i-based boards, like the
> Cubieboard 2 or Banana Pi, don't boot is that the sxitimer does
> not work for us.  We are getting no hardclock ticks and so the
> system can't work.
> 
> There's a simple fix for that.  We can just not use the sxitimer
> and instead use the ARM architected timer (agtimer) that is
> supposed to be a generic implementation for all new cores and
> already attaches anyway.  The sxitimer attachment currently
> overrides the agtimer.  Removing sxitimer thus allows agtimer
> to actually do its work.
> 
> Currently sxirtc uncondtionally ties into sxitimer.  To make
> this work, just make sxirtc map its own page instead of relying
> on the existence of a mapping created by sxitimer.
> 
> The address/size used for the sxirtc is from a device tree
> source.
> 
> Patrick
> 

Hi,

nothing i would change about your diff, given now there's agtimer,
but it doesn't really seem to even try fixing rtc on A20, and leaves
ugly glue into sxitimer written just for A20, which imho should also
get cleaned up.

-Artturi


diff --git a/sys/arch/armv7/sunxi/sun7i.c b/sys/arch/armv7/sunxi/sun7i.c
index 0d06b31..d8fcd45 100644
--- a/sys/arch/armv7/sunxi/sun7i.c
+++ b/sys/arch/armv7/sunxi/sun7i.c
@@ -39,19 +39,6 @@ struct armv7_dev sxia20_devs[] = {
          .mem = { { CCMU_ADDR, CCMU_SIZE } },
        },
 
-       /* Timers/Counters, resources mapped on first unit */
-       { .name = "sxitimer",
-         .unit = 0,
-         .mem = {      { TIMER_ADDR, TIMERx_SIZE },
-                       { CPUCNTRS_ADDR, CPUCNTRS_ADDR } }
-       },
-       { .name = "sxitimer",
-         .unit = 1,
-       },
-       { .name = "sxitimer",
-         .unit = 2,
-       },
-
        /* Watchdog Timer */
        { .name = "sxidog",
          .unit = 0,
diff --git a/sys/arch/armv7/sunxi/sxirtc.c b/sys/arch/armv7/sunxi/sxirtc.c
index 32460d6..cdd6716 100644
--- a/sys/arch/armv7/sunxi/sxirtc.c
+++ b/sys/arch/armv7/sunxi/sxirtc.c
@@ -15,9 +15,6 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
-/* XXX this doesn't support A20 yet. */
-       /* year & 0xff on A20, 0x3f on A10 */
-       /* leap << 24 on A20, << 22 on A10 */
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -40,9 +37,6 @@
     (y) % 400 == 0) 
 
 
-/* XXX other way around than bus_space_subregion? */
-extern bus_space_handle_t sxitimer_ioh;
-
 extern todr_chip_handle_t todr_handle;
 
 struct sxirtc_softc {
@@ -61,6 +55,8 @@ struct cfdriver sxirtc_cd = {
        NULL, "sxirtc", DV_DULL
 };
 
+uint32_t sxirtc_a20 = 0;
+
 int    sxirtc_gettime(todr_chip_handle_t, struct timeval *);
 int    sxirtc_settime(todr_chip_handle_t, struct timeval *);
 
@@ -78,7 +74,10 @@ sxirtc_attach(struct device *parent, struct device *self, 
void *args)
        sc->sc_iot = aa->aa_iot;
        if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
            aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
-               panic("sxirtc_attach: bus_space_subregion failed!");
+               panic("sxirtc_attach: bus_space_map failed!");
+
+       if (BOARD_ID_SUN7I_A20)
+               sxirtc_a20 = 1;
 
        handle->cookie = self;
        handle->todr_gettime = sxirtc_gettime;
@@ -97,6 +96,8 @@ sxirtc_gettime(todr_chip_handle_t handle, struct timeval *tv)
 {
        struct sxirtc_softc *sc = (struct sxirtc_softc *)handle->cookie;
        struct clock_ymdhms dt;
+       uint32_t base_year = sxirtc_a20 ? 1970 : 2010;
+       uint32_t year_mask = sxirtc_a20 ? 0xff : 0x3f;
        uint32_t reg;
 
        reg = SXIREAD4(sc, SXIRTC_HHMMSS);
@@ -108,7 +109,7 @@ sxirtc_gettime(todr_chip_handle_t handle, struct timeval 
*tv)
        reg = SXIREAD4(sc, SXIRTC_YYMMDD);
        dt.dt_day = reg & 0x1f;
        dt.dt_mon = reg >> 8 & 0x0f;
-       dt.dt_year = (reg >> 16 & 0x3f) + 2010; /* 0xff on A20 */
+       dt.dt_year = (reg >> 16 & year_mask) + base_year;
 
        if (dt.dt_sec > 59 || dt.dt_min > 59 ||
            dt.dt_hour > 23 || dt.dt_wday > 6 ||
@@ -126,6 +127,8 @@ sxirtc_settime(todr_chip_handle_t handle, struct timeval 
*tv)
 {
        struct sxirtc_softc *sc = (struct sxirtc_softc *)handle->cookie;
        struct clock_ymdhms dt;
+       uint32_t base_year = sxirtc_a20 ? 1970 : 2010;
+       uint32_t leap_shift = sxirtc_a20 ? 24 : 22;
 
        clock_secs_to_ymdhms(tv->tv_sec, &dt);
 
@@ -140,8 +143,8 @@ sxirtc_settime(todr_chip_handle_t handle, struct timeval 
*tv)
            (dt.dt_wday << 29));
 
        SXICMS4(sc, SXIRTC_YYMMDD, 0x00400000 | 0x003f0000 | 0x0f00 | 0x1f,
-          dt.dt_day | (dt.dt_mon << 8) | ((dt.dt_year - 2010) << 16) |
-          (LEAPYEAR(dt.dt_year) << 22));
+          dt.dt_day | (dt.dt_mon << 8) | ((dt.dt_year - base_year) << 16) |
+          (LEAPYEAR(dt.dt_year) << leap_shift));
 
        return 0;
 }
diff --git a/sys/arch/armv7/sunxi/sxitimer.c b/sys/arch/armv7/sunxi/sxitimer.c
index c07f85a..97eb51b 100644
--- a/sys/arch/armv7/sunxi/sxitimer.c
+++ b/sys/arch/armv7/sunxi/sxitimer.c
@@ -44,11 +44,6 @@
 #define        TIMER_INTV(x)           (0x14 + (0x10 * (x)))
 #define        TIMER_CURR(x)           (0x18 + (0x10 * (x)))
 
-/* A20 counter, relative to CPUCNTRS_ADDR */
-#define        OSC24M_CNT64_CTRL       0x80
-#define        OSC24M_CNT64_LOW        0x84
-#define        OSC24M_CNT64_HIGH       0x88
-
 /* A1X counter */
 #define        CNT64_CTRL              0xa0
 #define        CNT64_LOW               0xa4
@@ -56,7 +51,6 @@
 
 #define        CNT64_CLR_EN            (1 << 0) /* clear enable */
 #define        CNT64_RL_EN             (1 << 1) /* read latch enable */
-#define        CNT64_SYNCH             (1 << 4) /* sync to OSC24M counter */
 
 #define        LOSC_CTRL               0x100
 #define        OSC32K_SRC_SEL          (1 << 0)
@@ -99,7 +93,6 @@ static struct timecounter sxitimer_timecounter = {
 
 bus_space_tag_t                sxitimer_iot;
 bus_space_handle_t     sxitimer_ioh;
-bus_space_handle_t     sxitimer_cntr_ioh;
 
 uint32_t sxitimer_freq[] = {
        TIMER0_FREQUENCY,
@@ -120,10 +113,6 @@ uint32_t sxitimer_statvar, sxitimer_statmin;
 uint32_t sxitimer_tick_nextevt, sxitimer_stat_nextevt;
 uint32_t sxitimer_ticks_err_cnt, sxitimer_ticks_err_sum;
 
-bus_addr_t cntr64_ctrl = CNT64_CTRL;
-bus_addr_t cntr64_low = CNT64_LOW;
-bus_addr_t cntr64_high = CNT64_HIGH;
-
 struct sxitimer_softc {
        struct device           sc_dev;
 };
@@ -140,7 +129,7 @@ void
 sxitimer_attach(struct device *parent, struct device *self, void *args)
 {
        struct armv7_attach_args *aa = args;
-       uint32_t freq, ival, now, cr, v;
+       uint32_t freq, ival, now, cr;
        int unit = self->dv_unit;
 
        if (unit != 0)
@@ -152,29 +141,10 @@ sxitimer_attach(struct device *parent, struct device 
*self, void *args)
            aa->aa_dev->mem[0].size, 0, &sxitimer_ioh))
                panic("sxitimer_attach: bus_space_map failed!");
 
-
-       if (board_id == BOARD_ID_SUN7I_A20) {
-               if (bus_space_map(sxitimer_iot, CPUCNTRS_ADDR, CPUCNTRS_SIZE,
-                   0, &sxitimer_cntr_ioh))
-                       panic("sxitimer_attach: bus_space_map failed!");
-
-               cntr64_ctrl = OSC24M_CNT64_CTRL;
-               cntr64_low = OSC24M_CNT64_LOW;
-               cntr64_high = OSC24M_CNT64_HIGH;
-
-               v = bus_space_read_4(sxitimer_iot, sxitimer_cntr_ioh,
-                   cntr64_ctrl);
-               bus_space_write_4(sxitimer_iot, sxitimer_cntr_ioh, cntr64_ctrl,
-                   v | CNT64_SYNCH);
-               bus_space_write_4(sxitimer_iot, sxitimer_cntr_ioh, cntr64_ctrl,
-                   v & ~CNT64_SYNCH);
-       } else
-               sxitimer_cntr_ioh = sxitimer_ioh;
-
        /* clear counter, loop until ready */
-       bus_space_write_4(sxitimer_iot, sxitimer_cntr_ioh, cntr64_ctrl,
+       bus_space_write_4(sxitimer_iot, sxitimer_ioh, CNT64_CTRL,
            CNT64_CLR_EN); /* XXX as a side-effect counter clk src=OSC24M */
-       while (bus_space_read_4(sxitimer_iot, sxitimer_cntr_ioh, cntr64_ctrl)
+       while (bus_space_read_4(sxitimer_iot, sxitimer_ioh, CNT64_CTRL)
            & CNT64_CLR_EN)
                continue;
 
@@ -398,9 +368,8 @@ sxitimer_readcnt64(void)
        uint32_t low, high;
 
        /* latch counter, loop until ready */
-       bus_space_write_4(sxitimer_iot, sxitimer_cntr_ioh,
-           cntr64_ctrl, CNT64_RL_EN);
-       while (bus_space_read_4(sxitimer_iot, sxitimer_cntr_ioh, cntr64_ctrl)
+       bus_space_write_4(sxitimer_iot, sxitimer_ioh, CNT64_CTRL, CNT64_RL_EN);
+       while (bus_space_read_4(sxitimer_iot, sxitimer_ioh, CNT64_CTRL)
            & CNT64_RL_EN)
                continue;
 
@@ -409,8 +378,8 @@ sxitimer_readcnt64(void)
         * iirc. A20 manual mentions that low should be read first.
         */
        /* XXX check above */
-       low = bus_space_read_4(sxitimer_iot, sxitimer_cntr_ioh, cntr64_low);
-       high = bus_space_read_4(sxitimer_iot, sxitimer_cntr_ioh, cntr64_high);
+       low = bus_space_read_4(sxitimer_iot, sxitimer_ioh, CNT64_LOW);
+       high = bus_space_read_4(sxitimer_iot, sxitimer_ioh, CNT64_HIGH);
        return (uint64_t)high << 32 | low;
 }
 

Reply via email to