Hello, I feel like intruding posting to this list, let me know if that is the case.
This post: https://marc.info/?l=openbsd-arm&m=159333005826561&w=2 made me try again OpenBSD on an H3 board, an Orange Pi One unusable with random faults at boot. The firs thing I noticed was that PLL_CPUX wasn't stabilized although LOCK was read as set. Gating the PLL before setting the factors solved the problem. I added a delay(1) after switching the CPUX clock source, the datasheet advises of a delay of at least 8 cycles of the current clock. No more random faults at boot. ================================================================== --- /usr/src/sys/dev/fdt/sxiccmu.c.orig Wed Jul 8 21:23:35 2020 +++ /usr/src/sys/dev/fdt/sxiccmu.c Fri Jul 10 21:35:49 2020 @@ -1158,6 +1158,7 @@ /* Allwinner H3/H5 */ #define H3_PLL_CPUX_CTRL_REG 0x0000 +#define H3_PLL_CPUX_ENABLE (1 << 31) #define H3_PLL_CPUX_LOCK (1 << 28) #define H3_PLL_CPUX_OUT_EXT_DIVP(x) (((x) >> 16) & 0x3) #define H3_PLL_CPUX_OUT_EXT_DIVP_MASK (0x3 << 16) @@ -1644,7 +1645,12 @@ while (n >= 1 && (24000000 * n * k) > freq) n--; + /* Gate the PLL first */ reg = SXIREAD4(sc, H3_PLL_CPUX_CTRL_REG); + reg &= ~H3_PLL_CPUX_ENABLE; + SXIWRITE4(sc, H3_PLL_CPUX_CTRL_REG, reg); + + /* Set factors and external divider. */ reg &= ~H3_PLL_CPUX_OUT_EXT_DIVP_MASK; reg &= ~H3_PLL_CPUX_FACTOR_N_MASK; reg &= ~H3_PLL_CPUX_FACTOR_K_MASK; @@ -1653,6 +1659,10 @@ reg |= ((k - 1) << H3_PLL_CPUX_FACTOR_K_SHIFT); SXIWRITE4(sc, H3_PLL_CPUX_CTRL_REG, reg); + /* Ungate the PLL */ + reg |= H3_PLL_CPUX_ENABLE; + SXIWRITE4(sc, H3_PLL_CPUX_CTRL_REG, reg); + /* Wait for PLL to lock. */ while ((SXIREAD4(sc, H3_PLL_CPUX_CTRL_REG) & H3_PLL_CPUX_LOCK) == 0) @@ -1665,6 +1675,8 @@ reg &= ~H3_CPUX_CLK_SRC_SEL; reg |= H3_CPUX_CLK_SRC_SEL_OSC24M; SXIWRITE4(sc, H3_CPUX_AXI_CFG_REG, reg); + /* Must wait at least 8 cycles of the current clock. */ + delay(1); error = sxiccmu_h3_set_frequency(sc, H3_CLK_PLL_CPUX, freq); @@ -1673,6 +1685,7 @@ reg &= ~H3_CPUX_CLK_SRC_SEL; reg |= H3_CPUX_CLK_SRC_SEL_PLL_CPUX; SXIWRITE4(sc, H3_CPUX_AXI_CFG_REG, reg); + delay(1); return error; case H3_CLK_MMC0: case H3_CLK_MMC1: ================================================================== Next thing: DVFS failed, low voltage for the frequency and randoms traps in thermal_sensor_update. In src/sys/arch/arm/arm/cpu.c, cpu_opp_dotask() tries to set the cpux regulator's voltage to the preferred value (first element in the triplet of opp-microvolt) of the operating point in the opp_table. The problem is that this table doesn't correspond with the states of the regulator on the board, a SY8113B that will output just 1,1v or 1,3v. There are two options, patch the dts to match the regulator or change the code. One approach is to set opp_microvolt in cpu_opp_init() to the most appropriate of the supported volts of the cpu supply that are between min and max. Another is to change regulator_set_voltage() in sys/dev/ofw/ofw_regulator.c to admit 3 parameters: desired voltage, min and max and make the selection there. I prefer just to adjust the dtb. [...] opp_table0 { compatible = "operating-points-v2"; opp-shared; phandle = <0x29>; opp-648000000 { opp-hz = <0x00 0x269fb200>; opp-microvolt = <0x10c8e0 0x10c8e0 0x13d620>; clock-latency-ns = <0x3b9b0>; }; opp-816000000 { opp-hz = <0x00 0x30a32c00>; opp-microvolt = <0x10c8e0 0x10c8e0 0x13d620>; clock-latency-ns = <0x3b9b0>; }; opp-1008000000 { opp-hz = <0x00 0x3c14dc00>; opp-microvolt = <0x13d620 0x13d620 0x13d620>; clock-latency-ns = <0x3b9b0>; }; }; [...] The board seams to be stable now. Regards, adr.
