On Sun, Jan 31, 2016 at 10:12:05AM +0200, Artturi Alm wrote:
> 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

There seem to be at least two diffs here, the different rtc handling
for a20 should be split out, store sxirtc_a20 in the softc and fix
the test from
if (BOARD_ID_SUN7I_A20)
to
if (board_id == BOARD_ID_SUN7I_A20)

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