sifive/freedom-metal

__metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz returns wrong clock

Opened this issue · 2 comments

On FE310 G002 (HiFive RevB), attempting to utilize get_rate_hz on lfrosc is returning 0, but should return 32768 for the external clock.

From tracing, this appears to be because the MUX flag is being read and tested for incorrectly, causing this driver to attempt to read from the internal clock source (which I think is unset, thus resulting in the return value of 0)

The problem appears to be twofold:

  1. The mux/cfg reg values read from the devicetree are read as raw addresses and not as offsets into the base address for the aon block
  2. The MUX flag (AON 0x7C:31) is low for selecting the external clock (it's high in lfextclksel, or 0x7C:0), but the logic appears to be testing for a high bit in bit 31
__metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz (clock=0x80000a78 <__metal_dt_clock_7>)
    at reedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c:36
36	    if (LFROSC_REGW(mux_reg) & METAL_LFCLKMUX_EXT_MUX_STATUS) {
(gdb) print mux_reg
$1 = 124
(gdb) print cfg_reg
$2 = 112
(gdb) monitor mdw 0x0000007c
0x0000007c: 00000000 

0x0000007c: 00000000 

(gdb) monitor mdw 0x1000007c
0x1000007c: 00000000 

0x1000007c: 00000000 

(gdb) monitor mdw 0x10000070
0x10000070: c0100004 

0x10000070: c0100004 

(gdb) monitor mdw 0x00000070
0x00000070: 00000000 

0x00000070: 00000000 

Ah ha, appears that freedom-devicetree-tools will attempt to add the base address to this register when generating the metal-bsp, but there is a discontinuity between the two--the DTS in freedom-e-sdk uses a named tuple for the aon node of name "mem", but the devicetree tools is looking for "control" and will default to a base address of 0 if it cannot find it.

https://github.com/sifive/freedom-devicetree-tools/blob/master/metal_header/sifive_fe310_g000_lfrosc.c++#L93
https://github.com/sifive/freedom-e-sdk/blob/master/bsp/sifive-hifive1-revb/core.dts#L126

I can see examples of both in the DTS--which is the preferred register name for block base addresses? My guess is "control" as this controls AON behavior (and mem seems to be used for things like ITIM/DTIM), which I guess would make half of this issue a freedom-e-sdk issue?