Index: sys/arm/allwinner/clkng/aw_ccung.h =================================================================== --- sys/arm/allwinner/clkng/aw_ccung.h +++ sys/arm/allwinner/clkng/aw_ccung.h @@ -29,6 +29,29 @@ #ifndef __CCU_NG_H__ #define __CCU_NG_H__ +#ifdef __aarch64__ +#include "opt_soc.h" +#endif + +#if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) +#define H3_CCU 1 +#define H3_R_CCU 2 +#endif + +#if defined(SOC_ALLWINNER_A31) +#define A31_CCU 3 +#endif + +#if defined(SOC_ALLWINNER_A64) +#define A64_CCU 4 +#define A64_R_CCU 5 +#endif + +#if defined(SOC_ALLWINNER_A83T) +#define A83T_CCU 6 +#define A83T_R_CCU 7 +#endif + struct aw_ccung_softc { device_t dev; struct resource *res; Index: sys/arm/allwinner/clkng/aw_ccung.c =================================================================== --- sys/arm/allwinner/clkng/aw_ccung.c +++ sys/arm/allwinner/clkng/aw_ccung.c @@ -54,10 +54,6 @@ #include #include -#ifdef __aarch64__ -#include "opt_soc.h" -#endif - #if defined(SOC_ALLWINNER_A31) #include #endif @@ -67,6 +63,11 @@ #include #endif +#if defined(SOC_ALLWINNER_A83T) +#include +#include +#endif + #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) #include #include @@ -80,20 +81,6 @@ { -1, 0 } }; -#if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) -#define H3_CCU 1 -#define H3_R_CCU 2 -#endif - -#if defined(SOC_ALLWINNER_A31) -#define A31_CCU 3 -#endif - -#if defined(SOC_ALLWINNER_A64) -#define A64_CCU 4 -#define A64_R_CCU 5 -#endif - static struct ofw_compat_data compat_data[] = { #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) { "allwinner,sun8i-h3-ccu", H3_CCU }, @@ -105,6 +92,10 @@ #if defined(SOC_ALLWINNER_A64) { "allwinner,sun50i-a64-ccu", A64_CCU }, { "allwinner,sun50i-a64-r-ccu", A64_R_CCU }, +#endif +#if defined(SOC_ALLWINNER_A83T) + { "allwinner,sun8i-a83t-ccu", A83T_CCU }, + { "allwinner,sun8i-a83t-r-ccu", A83T_R_CCU }, #endif {NULL, 0 } }; @@ -342,6 +333,14 @@ case A64_R_CCU: ccu_sun8i_r_register_clocks(sc); break; +#endif +#if defined(SOC_ALLWINNER_A83T) + case A83T_CCU: + ccu_a83t_register_clocks(sc); + break; + case A83T_R_CCU: + ccu_sun8i_r_register_clocks(sc); + break; #endif } Index: sys/arm/allwinner/clkng/aw_clk.h =================================================================== --- sys/arm/allwinner/clkng/aw_clk.h +++ sys/arm/allwinner/clkng/aw_clk.h @@ -48,6 +48,7 @@ Clock Source/Divider N/Divider M Clock Source/Divider N/Divider M/2 +Clock Source*N/(Divider M+1)/(Divider P+1) */ @@ -70,6 +71,8 @@ #define AW_CLK_FACTOR_ZERO_BASED 0x0002 #define AW_CLK_FACTOR_HAS_COND 0x0004 #define AW_CLK_FACTOR_FIXED 0x0008 +#define AW_CLK_FACTOR_POWER_OF_FOUR 0x0010 +#define AW_CLK_FACTOR_HAS_BIT_COND 0x0020 struct aw_clk_factor { uint32_t shift; /* Shift bits for the factor */ @@ -98,9 +101,14 @@ uint32_t factor_val; uint32_t cond; - if (factor->flags & AW_CLK_FACTOR_HAS_COND) { + if ((factor->flags & AW_CLK_FACTOR_HAS_COND) || + (factor->flags & AW_CLK_FACTOR_HAS_BIT_COND)) { cond = (val & factor->cond_mask) >> factor->cond_shift; - if (cond != factor->cond_value) + if (!(factor->flags & AW_CLK_FACTOR_HAS_BIT_COND) && + cond != factor->cond_value) + return (1); + if ((factor->flags & AW_CLK_FACTOR_HAS_BIT_COND) && + (cond & factor->cond_value) == 0) return (1); } @@ -112,10 +120,24 @@ factor_val += 1; else if (factor->flags & AW_CLK_FACTOR_POWER_OF_TWO) factor_val = 1 << factor_val; + else if (factor->flags & AW_CLK_FACTOR_POWER_OF_FOUR) + factor_val = 1 << (2 * factor_val); return (factor_val); } +static inline uint32_t +aw_clk_factor_get_incremented(uint32_t val, struct aw_clk_factor *factor) +{ + + if (factor->flags & AW_CLK_FACTOR_POWER_OF_TWO) + return (val << 1); + else if (factor->flags & AW_CLK_FACTOR_POWER_OF_FOUR) + return (val << 2); + else + return (val + 1); +} + static inline uint32_t aw_clk_factor_get_max(struct aw_clk_factor *factor) { @@ -125,6 +147,8 @@ max = factor->value; else if (factor->flags & AW_CLK_FACTOR_POWER_OF_TWO) max = 1 << ((1 << factor->width) - 1); + else if (factor->flags & AW_CLK_FACTOR_POWER_OF_FOUR) + max = 1 << (2 * ((1 << factor->width) - 1)); else { max = (1 << factor->width); } @@ -160,6 +184,9 @@ else if (factor->flags & AW_CLK_FACTOR_POWER_OF_TWO) { for (val = 0; raw != 1; val++) raw >>= 1; + } else if (factor->flags & AW_CLK_FACTOR_POWER_OF_FOUR) { + for (val = 0; raw != 1; val++) + raw >>= 2; } else val = raw - 1; Index: sys/arm/allwinner/clkng/aw_clk_nkmp.c =================================================================== --- sys/arm/allwinner/clkng/aw_clk_nkmp.c +++ sys/arm/allwinner/clkng/aw_clk_nkmp.c @@ -168,25 +168,13 @@ } if (best == *fout) return (best); - if ((sc->p.flags & AW_CLK_FACTOR_POWER_OF_TWO) != 0) - p <<= 1; - else - p++; + p = aw_clk_factor_get_incremented(p, &sc->p); } - if ((sc->m.flags & AW_CLK_FACTOR_POWER_OF_TWO) != 0) - m <<= 1; - else - m++; + m = aw_clk_factor_get_incremented(m, &sc->m); } - if ((sc->k.flags & AW_CLK_FACTOR_POWER_OF_TWO) != 0) - k <<= 1; - else - k++; + k = aw_clk_factor_get_incremented(k, &sc->k); } - if ((sc->n.flags & AW_CLK_FACTOR_POWER_OF_TWO) != 0) - n <<= 1; - else - n++; + n = aw_clk_factor_get_incremented(n, &sc->n); } return best; Index: sys/arm/allwinner/clkng/aw_clk_nm.c =================================================================== --- sys/arm/allwinner/clkng/aw_clk_nm.c +++ sys/arm/allwinner/clkng/aw_clk_nm.c @@ -160,15 +160,9 @@ *factor_m = m; } - if ((sc->n.flags & AW_CLK_FACTOR_POWER_OF_TWO) != 0) - n <<= 1; - else - n++; + n = aw_clk_factor_get_incremented(n, &sc->n); } - if ((sc->m.flags & AW_CLK_FACTOR_POWER_OF_TWO) != 0) - m <<= 1; - else - m++; + m = aw_clk_factor_get_incremented(m, &sc->m); } return (best);