Re: [PATCH] clk: rockchip: Fix overflow rate during fractional approximation
ommit: commit <88a5404a2277> ("clk: rockchip: fix up the rockchip_fractional_approximation") commit <4186a0e4239b> ("clk: rockchip: Add supprot to limit input rate for fractional divider") Signed-off-by: Jagan Teki Signed-off-by: Finley Xiao --- drivers/clk/rockchip/clk-px30.c | 12 ++-- drivers/clk/rockchip/clk.c | 9 + 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c index 6fb9c98b7d24..06d3ff39d12f 100644 --- a/drivers/clk/rockchip/clk-px30.c +++ b/drivers/clk/rockchip/clk-px30.c @@ -660,7 +660,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE(SCLK_UART1_SRC, "clk_uart1_src", mux_uart_src_p, CLK_SET_RATE_NO_REPARENT, PX30_CLKSEL_CON(34), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(10), 12, GFLAGS), - COMPOSITE_NOMUX_HALFDIV(0, "clk_uart1_np5", "clk_uart1_src", 0, + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart1_np5", "clk_uart1_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(35), 0, 5, DFLAGS, PX30_CLKGATE_CON(10), 13, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT, @@ -673,7 +673,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE(SCLK_UART2_SRC, "clk_uart2_src", mux_uart_src_p, 0, PX30_CLKSEL_CON(37), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 0, GFLAGS), - COMPOSITE_NOMUX_HALFDIV(0, "clk_uart2_np5", "clk_uart2_src", 0, + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart2_np5", "clk_uart2_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(38), 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 1, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT, @@ -686,7 +686,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE(0, "clk_uart3_src", mux_uart_src_p, 0, PX30_CLKSEL_CON(40), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 4, GFLAGS), - COMPOSITE_NOMUX_HALFDIV(0, "clk_uart3_np5", "clk_uart3_src", 0, + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart3_np5", "clk_uart3_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(41), 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 5, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT, @@ -699,7 +699,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE(0, "clk_uart4_src", mux_uart_src_p, 0, PX30_CLKSEL_CON(43), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 8, GFLAGS), - COMPOSITE_NOMUX_HALFDIV(0, "clk_uart4_np5", "clk_uart4_src", 0, + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart4_np5", "clk_uart4_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(44), 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 9, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT, @@ -712,7 +712,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE(0, "clk_uart5_src", mux_uart_src_p, 0, PX30_CLKSEL_CON(46), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 12, GFLAGS), - COMPOSITE_NOMUX_HALFDIV(0, "clk_uart5_np5", "clk_uart5_src", 0, + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart5_np5", "clk_uart5_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(47), 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 13, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT, @@ -934,7 +934,7 @@ static struct rockchip_clk_branch px30_clk_pmu_branches[] __initdata = { COMPOSITE(0, "clk_uart0_pmu_src", mux_uart_src_p, 0, PX30_PMU_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_PMU_CLKGATE_CON(1), 0, GFLAGS), - COMPOSITE_NOMUX_HALFDIV(0, "clk_uart0_np5", "clk_uart0_pmu_src", 0, + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart0_np5", "clk_uart0_pmu_src", CLK_SET_RATE_PARENT, PX30_PMU_CLKSEL_CON(4), 0, 5, DFLAGS, PX30_PMU_CLKGATE_CON(1), 1, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_pmu_src",
[PATCH v1] thermal/of: Introduce k-po, k-pu and k-i for a thermal zone
The default value for k_pu is: 2 * sustainable_power / (desired_temperature - switch_on_temp) The default value for k_po is: sustainable_power / (desired_temperature - switch_on_temp) The default value for k_i is 10. Even though these parameters of the PID controller can be changed by the following sysfs files: /sys/class/thermal/thermal_zoneX/k_pu /sys/class/thermal/thermal_zoneX/k_po /sys/class/thermal/thermal_zoneX/k_i But it's still more convenient to change the default values by devicetree, so introduce these three optional properties. If provided these properties, they will be parsed and associated with the thermal zone via the thermal zone parameters. Signed-off-by: Finley Xiao --- Documentation/devicetree/bindings/thermal/thermal.txt | 14 ++ drivers/thermal/thermal_of.c | 7 +++ 2 files changed, 21 insertions(+) diff --git a/Documentation/devicetree/bindings/thermal/thermal.txt b/Documentation/devicetree/bindings/thermal/thermal.txt index f78bec19ca35..ebe936b57ded 100644 --- a/Documentation/devicetree/bindings/thermal/thermal.txt +++ b/Documentation/devicetree/bindings/thermal/thermal.txt @@ -165,6 +165,20 @@ Optional property: 2000mW, while on a 10'' tablet is around 4500mW. +- k-po:Proportional parameter of the PID controller when + current temperature is above the target. + Type: signed + Size: one cell + +- k-pu:Proportional parameter of the PID controller when + current temperature is below the target. + Type: signed + Size: one cell + +- k-i: Integral parameter of the PID controller. + Type: signed + Size: one cell + Note: The delay properties are bound to the maximum dT/dt (temperature derivative over time) in two situations for a thermal zone: (i) - when passive cooling is activated (polling-delay-passive); and diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index ddf88dbe7ba2..b2a9f92cd8d2 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -1089,6 +1089,7 @@ int __init of_parse_thermal_zones(void) struct thermal_zone_params *tzp; int i, mask = 0; u32 prop; + s32 sval; tz = thermal_of_build_thermal_zone(child); if (IS_ERR(tz)) { @@ -1113,6 +1114,12 @@ int __init of_parse_thermal_zones(void) if (!of_property_read_u32(child, "sustainable-power", &prop)) tzp->sustainable_power = prop; + if (!of_property_read_s32(child, "k-po", &sval)) + tzp->k_po = sval; + if (!of_property_read_s32(child, "k-pu", &sval)) + tzp->k_pu = sval; + if (!of_property_read_s32(child, "k-i", &sval)) + tzp->k_i = sval; for (i = 0; i < tz->ntrips; i++) mask |= 1 << i; -- 2.11.0
[PATCH] thermal/drivers/cpufreq_cooling: Fix wrong frequency converted from power
The function cpu_power_to_freq is used to find a frequency and set the cooling device to consume at most the power to be converted. For example, if the power to be converted is 80mW, and the em table is as follow. struct em_cap_state table[] = { /* KHz mW */ { 1008000, 36, 0 }, { 120, 49, 0 }, { 1296000, 59, 0 }, { 1416000, 72, 0 }, { 1512000, 86, 0 }, }; The target frequency should be 1416000KHz, not 1512000KHz. Fixes: 349d39dc5739 ("thermal: cpu_cooling: merge frequency and power tables") Cc: # v4.13+ Signed-off-by: Finley Xiao Acked-by: Viresh Kumar --- drivers/thermal/cpufreq_cooling.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 9e124020519f..6c0e1b053126 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -123,12 +123,12 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev, { int i; - for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) { - if (power > cpufreq_cdev->em->table[i].power) + for (i = cpufreq_cdev->max_level; i >= 0; i--) { + if (power >= cpufreq_cdev->em->table[i].power) break; } - return cpufreq_cdev->em->table[i + 1].frequency; + return cpufreq_cdev->em->table[i].frequency; } /** -- 2.11.0
[PATCH] thermal/drivers/cpufreq_cooling: Fix wrong frequency converted from power
The function cpu_power_to_freq is used to find a frequency and set the cooling device to consume at most the power to be converted. For example, if the power to be converted is 80mW, and the em table is as follow. struct em_cap_state table[] = { /* KHz mW */ { 1008000, 36, 0 }, { 120, 49, 0 }, { 1296000, 59, 0 }, { 1416000, 72, 0 }, { 1512000, 86, 0 }, }; The target frequency should be 1416000KHz, not 1512000KHz. Fixes: 349d39dc5739 ("thermal: cpu_cooling: merge frequency and power tables") Signed-off-by: Finley Xiao --- drivers/thermal/cpufreq_cooling.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 9e124020519f..6c0e1b053126 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -123,12 +123,12 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev, { int i; - for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) { - if (power > cpufreq_cdev->em->table[i].power) + for (i = cpufreq_cdev->max_level; i >= 0; i--) { + if (power >= cpufreq_cdev->em->table[i].power) break; } - return cpufreq_cdev->em->table[i + 1].frequency; + return cpufreq_cdev->em->table[i].frequency; } /** -- 2.11.0
[PATCH v1 3/3] clk: rockchip: Add clock controller for the RK3308
Add the clock tree definition for the new RK3308 SoC. Signed-off-by: Finley Xiao --- drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk-rk3308.c | 955 ++ drivers/clk/rockchip/clk.h| 13 + 3 files changed, 969 insertions(+) create mode 100644 drivers/clk/rockchip/clk-rk3308.c diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index ff35ab463a6f..7c5b5813a87c 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -20,6 +20,7 @@ obj-y += clk-rk3128.o obj-y += clk-rk3188.o obj-y += clk-rk3228.o obj-y += clk-rk3288.o +obj-y += clk-rk3308.o obj-y += clk-rk3328.o obj-y += clk-rk3368.o obj-y += clk-rk3399.o diff --git a/drivers/clk/rockchip/clk-rk3308.c b/drivers/clk/rockchip/clk-rk3308.c new file mode 100644 index ..b0baf87a283e --- /dev/null +++ b/drivers/clk/rockchip/clk-rk3308.c @@ -0,0 +1,955 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2019 Rockchip Electronics Co. Ltd. + * Author: Finley Xiao + */ + +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define RK3308_GRF_SOC_STATUS0 0x380 + +enum rk3308_plls { + apll, dpll, vpll0, vpll1, +}; + +static struct rockchip_pll_rate_table rk3308_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(160800, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(158400, 1, 66, 1, 1, 1, 0), + RK3036_PLL_RATE(156000, 1, 65, 1, 1, 1, 0), + RK3036_PLL_RATE(153600, 1, 64, 1, 1, 1, 0), + RK3036_PLL_RATE(151200, 1, 63, 1, 1, 1, 0), + RK3036_PLL_RATE(148800, 1, 62, 1, 1, 1, 0), + RK3036_PLL_RATE(146400, 1, 61, 1, 1, 1, 0), + RK3036_PLL_RATE(144000, 1, 60, 1, 1, 1, 0), + RK3036_PLL_RATE(141600, 1, 59, 1, 1, 1, 0), + RK3036_PLL_RATE(139200, 1, 58, 1, 1, 1, 0), + RK3036_PLL_RATE(136800, 1, 57, 1, 1, 1, 0), + RK3036_PLL_RATE(134400, 1, 56, 1, 1, 1, 0), + RK3036_PLL_RATE(132000, 1, 55, 1, 1, 1, 0), + RK3036_PLL_RATE(129600, 1, 54, 1, 1, 1, 0), + RK3036_PLL_RATE(127200, 1, 53, 1, 1, 1, 0), + RK3036_PLL_RATE(124800, 1, 52, 1, 1, 1, 0), + RK3036_PLL_RATE(12, 1, 50, 1, 1, 1, 0), + RK3036_PLL_RATE(118800, 2, 99, 1, 1, 1, 0), + RK3036_PLL_RATE(110400, 1, 46, 1, 1, 1, 0), + RK3036_PLL_RATE(11, 12, 550, 1, 1, 1, 0), + RK3036_PLL_RATE(100800, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(10, 6, 500, 2, 1, 1, 0), + RK3036_PLL_RATE(98400, 1, 82, 2, 1, 1, 0), + RK3036_PLL_RATE(96000, 1, 80, 2, 1, 1, 0), + RK3036_PLL_RATE(93600, 1, 78, 2, 1, 1, 0), + RK3036_PLL_RATE(91200, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE(9, 4, 300, 2, 1, 1, 0), + RK3036_PLL_RATE(88800, 1, 74, 2, 1, 1, 0), + RK3036_PLL_RATE(86400, 1, 72, 2, 1, 1, 0), + RK3036_PLL_RATE(84000, 1, 70, 2, 1, 1, 0), + RK3036_PLL_RATE(81600, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(8, 6, 400, 2, 1, 1, 0), + RK3036_PLL_RATE(7, 6, 350, 2, 1, 1, 0), + RK3036_PLL_RATE(69600, 1, 58, 2, 1, 1, 0), + RK3036_PLL_RATE(62400, 1, 52, 2, 1, 1, 0), + RK3036_PLL_RATE(6, 1, 75, 3, 1, 1, 0), + RK3036_PLL_RATE(59400, 2, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(50400, 1, 63, 3, 1, 1, 0), + RK3036_PLL_RATE(5, 6, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(40800, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(31200, 1, 52, 2, 2, 1, 0), + RK3036_PLL_RATE(21600, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(9600, 1, 64, 4, 4, 1, 0), + { /* sentinel */ }, +}; + +#define RK3308_DIV_ACLKM_MASK 0x7 +#define RK3308_DIV_ACLKM_SHIFT 12 +#define RK3308_DIV_PCLK_DBG_MASK 0xf +#define RK3308_DIV_PCLK_DBG_SHIFT 8 + +#define RK3308_CLKSEL0(_aclk_core, _pclk_dbg) \ +{ \ + .reg = RK3308_CLKSEL_CON(0),\ + .val = HIWORD_UPDATE(_aclk_core, RK3308_DIV_ACLKM_MASK, \ +RK3308_DIV_ACLKM_SHIFT) | \ + HIWORD_UPDATE(_pclk_dbg, RK3308_DIV_PCLK_DBG_MASK, \ +RK3308_DIV_PCLK_DBG_SHIFT),\ +} + +#define RK3308_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \ +{ \ + .prate = _prate,\ + .divs = { \ + RK3308_CLKSEL0(_aclk_core, _pclk_dbg), \ + }, \ +}
[PATCH v1 1/3] dt-bindings: Add bindings for rk3308 clock controller
Add devicetree bindings for Rockchip cru which found on Rockchip SoCs. Signed-off-by: Finley Xiao --- .../devicetree/bindings/clock/rockchip,rk3308.txt | 58 ++ 1 file changed, 58 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3308.txt diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3308.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3308.txt new file mode 100644 index ..5d46c9b7f937 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3308.txt @@ -0,0 +1,58 @@ +* Rockchip RK3308 Clock and Reset Unit + +The RK3308 clock controller generates and supplies clock to various +controllers within the SoC and also implements a reset controller for SoC +peripherals. + +Required Properties: + +- compatible: CRU should be "rockchip,rk3308-cru" +- reg: physical base address of the controller and length of memory mapped + region. +- #clock-cells: should be 1. +- #reset-cells: should be 1. + +Optional Properties: + +- rockchip,grf: phandle to the syscon managing the "general register files" + If missing, pll rates are not changeable, due to the missing pll lock status. + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. All available clocks are defined as +preprocessor macros in the dt-bindings/clock/rk3308-cru.h headers and can be +used in device tree sources. Similar macros exist for the reset sources in +these files. + +External clocks: + +There are several clocks that are generated outside the SoC. It is expected +that they are defined using standard clock bindings with following +clock-output-names: + - "xin24m" - crystal input - required, + - "xin32k" - rtc clock - optional, + - "mclk_i2sx_xch_in" - external I2S or SPDIF clock - optional, + - "mac_clkin" - external MAC clock - optional + +Example: Clock controller node: + + cru: clock-controller@ff50 { + compatible = "rockchip,rk3308-cru"; + reg = <0x0 0xff50 0x0 0x1000>; + rockchip,grf = <&grf>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + +Example: UART controller node that consumes the clock generated by the clock + controller: + + uart0: serial@ff0a { + compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff0a 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; -- 2.11.0
[PATCH v1 0/3] clk: rockchip: support clock controller for rk3308 SoC
Finley Xiao (3): dt-bindings: Add bindings for rk3308 clock controller clk: rockchip: Add dt-binding header for rk3308 clk: rockchip: Add clock controller for the RK3308 .../devicetree/bindings/clock/rockchip,rk3308.txt | 58 ++ drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk-rk3308.c | 955 + drivers/clk/rockchip/clk.h | 13 + include/dt-bindings/clock/rk3308-cru.h | 387 + 5 files changed, 1414 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3308.txt create mode 100644 drivers/clk/rockchip/clk-rk3308.c create mode 100644 include/dt-bindings/clock/rk3308-cru.h -- 2.11.0
[PATCH v1 2/3] clk: rockchip: Add dt-binding header for rk3308
Add the dt-bindings header for the rk3308, that gets shared between the clock controller and the clock references in the dts. Signed-off-by: Finley Xiao --- include/dt-bindings/clock/rk3308-cru.h | 387 + 1 file changed, 387 insertions(+) create mode 100644 include/dt-bindings/clock/rk3308-cru.h diff --git a/include/dt-bindings/clock/rk3308-cru.h b/include/dt-bindings/clock/rk3308-cru.h new file mode 100644 index ..d97840f9ee2e --- /dev/null +++ b/include/dt-bindings/clock/rk3308-cru.h @@ -0,0 +1,387 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 Rockchip Electronics Co. Ltd. + * Author: Finley Xiao + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3308_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3308_H + +/* core clocks */ +#define PLL_APLL 1 +#define PLL_DPLL 2 +#define PLL_VPLL0 3 +#define PLL_VPLL1 4 +#define ARMCLK 5 + +/* sclk (special clocks) */ +#define USB480M14 +#define SCLK_RTC32K15 +#define SCLK_PVTM_CORE 16 +#define SCLK_UART0 17 +#define SCLK_UART1 18 +#define SCLK_UART2 19 +#define SCLK_UART3 20 +#define SCLK_UART4 21 +#define SCLK_I2C0 22 +#define SCLK_I2C1 23 +#define SCLK_I2C2 24 +#define SCLK_I2C3 25 +#define SCLK_PWM0 26 +#define SCLK_SPI0 27 +#define SCLK_SPI1 28 +#define SCLK_SPI2 29 +#define SCLK_TIMER030 +#define SCLK_TIMER131 +#define SCLK_TIMER232 +#define SCLK_TIMER333 +#define SCLK_TIMER434 +#define SCLK_TIMER535 +#define SCLK_TSADC 36 +#define SCLK_SARADC37 +#define SCLK_OTP 38 +#define SCLK_OTP_USR 39 +#define SCLK_CPU_BOOST 40 +#define SCLK_CRYPTO41 +#define SCLK_CRYPTO_APK42 +#define SCLK_NANDC_DIV 43 +#define SCLK_NANDC_DIV50 44 +#define SCLK_NANDC 45 +#define SCLK_SDMMC_DIV 46 +#define SCLK_SDMMC_DIV50 47 +#define SCLK_SDMMC 48 +#define SCLK_SDMMC_DRV 49 +#define SCLK_SDMMC_SAMPLE 50 +#define SCLK_SDIO_DIV 51 +#define SCLK_SDIO_DIV5052 +#define SCLK_SDIO 53 +#define SCLK_SDIO_DRV 54 +#define SCLK_SDIO_SAMPLE 55 +#define SCLK_EMMC_DIV 56 +#define SCLK_EMMC_DIV5057 +#define SCLK_EMMC 58 +#define SCLK_EMMC_DRV 59 +#define SCLK_EMMC_SAMPLE 60 +#define SCLK_SFC 61 +#define SCLK_OTG_ADP 62 +#define SCLK_MAC_SRC 63 +#define SCLK_MAC 64 +#define SCLK_MAC_REF 65 +#define SCLK_MAC_RX_TX 66 +#define SCLK_MAC_RMII 67 +#define SCLK_DDR_MON_TIMER 68 +#define SCLK_DDR_MON 69 +#define SCLK_DDRCLK70 +#define SCLK_PMU 71 +#define SCLK_USBPHY_REF72 +#define SCLK_WIFI 73 +#define SCLK_PVTM_PMU 74 +#define SCLK_PDM 75 +#define SCLK_I2S0_8CH_TX 76 +#define SCLK_I2S0_8CH_TX_OUT 77 +#define SCLK_I2S0_8CH_RX 78 +#define SCLK_I2S0_8CH_RX_OUT 79 +#define SCLK_I2S1_8CH_TX 80 +#define SCLK_I2S1_8CH_TX_OUT 81 +#define SCLK_I2S1_8CH_RX 82 +#define SCLK_I2S1_8CH_RX_OUT 83 +#define SCLK_I2S2_8CH_TX 84 +#define SCLK_I2S2_8CH_TX_OUT 85 +#define SCLK_I2S2_8CH_RX 86 +#define SCLK_I2S2_8CH_RX_OUT 87 +#define SCLK_I2S3_8CH_TX 88 +#define SCLK_I2S3_8CH_TX_OUT 89 +#define SCLK_I2S3_8CH_RX 90 +#define SCLK_I2S3_8CH_RX_OUT 91 +#define SCLK_I2S0_2CH 92 +#define SCLK_I2S0_2CH_OUT 93 +#define SCLK_I2S1_2CH 94 +#define SCLK_I2S1_2CH_OUT 95 +#define SCLK_SPDIF_TX_DIV 96 +#define SCLK_SPDIF_TX_DIV5097 +#define SCLK_SPDIF_TX 98 +#define SCLK_SPDIF_RX_DIV 99 +#define SCLK_SPDIF_RX_DIV50100 +#define SCLK_SPDIF_RX 101 +#define SCLK_I2S0_8CH_TX_MUX 102 +#define SCLK_I2S0_8CH_RX_MUX 103 +#define SCLK_I2S1_8CH_TX_MUX 104 +#define SCLK_I2S1_8CH_RX_MUX 105 +#define SCLK_I2S2_8CH_TX_MUX 106 +#define SCLK_I2S2_8CH_RX_MUX 107 +#define SCLK_I2S3_8CH_TX_MUX 108 +#define SCLK_I2S3_8CH_RX_MUX 109 +#define SCLK_I2S0_8CH_TX_SRC 110 +#define SCLK_I2S0_8CH_RX_SRC 111 +#define SCLK_I2S1_8CH_TX_SRC 112 +#define SCLK_I2S1_8CH_RX_SRC 113 +#define SCLK_I2S2_8CH_TX_SRC 114 +#define SCLK_I2S2_8CH_RX_SRC 115 +#define SCLK_I2S3_8CH_TX_SRC 116 +#define SCLK_I2S3_8CH_RX_SRC 117 +#define SCLK_I2S0_2CH_SRC 118 +#define SCLK_I2S1_2CH_SRC 119 +#define SCLK_PWM1 120 +#define SCLK_PWM2 121 +#define SCLK_OWIRE 122 + +/* dclk */ +#define DCLK_VOP 125 + +/* aclk */ +#define ACLK_BUS_SRC 130 +#define ACLK_BUS
[PATCH 0/2] arm64: dts: rockchip: add cpu operating points and efuse node for RK3328 SoC
Add cpu operating points and an efuse node in the device tree for rk3228 SoC Finley Xiao (2): arm64: dts: rockchip: Add cpu operating points for RK3328 SoC arm64: dts: rockchip: Add efuse device node for RK3328 SoC arch/arm64/boot/dts/rockchip/rk3328.dtsi | 66 1 file changed, 66 insertions(+) -- 2.7.4
[PATCH 2/2] arm64: dts: rockchip: Add efuse device node for RK3328 SoC
This patch adds an efuse node in the device tree for rk3228 SoC. Signed-off-by: Finley Xiao --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 25 + 1 file changed, 25 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 81fd8cb..cc8dd80 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -367,6 +367,31 @@ interrupts = ; }; + efuse: efuse@ff26 { + compatible = "rockchip,rk3328-efuse"; + reg = <0x0 0xff26 0x0 0x50>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&cru SCLK_EFUSE>; + clock-names = "pclk_efuse"; + rockchip,efuse-size = <0x20>; + + /* Data cells */ + efuse_id: id@7 { + reg = <0x07 0x10>; + }; + cpu_leakage: cpu-leakage@17 { + reg = <0x17 0x1>; + }; + logic_leakage: logic-leakage@19 { + reg = <0x19 0x1>; + }; + efuse_cpu_version: cpu-version@1a { + reg = <0x1a 0x1>; + bits = <3 3>; + }; + }; + saradc: adc@ff28 { compatible = "rockchip,rk3328-saradc", "rockchip,rk3399-saradc"; reg = <0x0 0xff28 0x0 0x100>; -- 2.7.4
[PATCH 1/2] arm64: dts: rockchip: Add cpu operating points for RK3328 SoC
This patch adds basic OPP entries for RK3328 SoC. Signed-off-by: Finley Xiao --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 41 1 file changed, 41 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 440e6bc..81fd8cb 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -76,6 +76,7 @@ clocks = <&cru ARMCLK>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu1: cpu@1 { @@ -85,6 +86,7 @@ clocks = <&cru ARMCLK>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu2: cpu@2 { @@ -94,6 +96,7 @@ clocks = <&cru ARMCLK>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu3: cpu@3 { @@ -103,6 +106,7 @@ clocks = <&cru ARMCLK>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; l2: l2-cache0 { @@ -110,6 +114,43 @@ }; }; + cpu0_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-40800 { + opp-hz = /bits/ 64 <40800>; + opp-microvolt = <95>; + clock-latency-ns = <4>; + opp-suspend; + }; + opp-6 { + opp-hz = /bits/ 64 <6>; + opp-microvolt = <95>; + clock-latency-ns = <4>; + }; + opp-81600 { + opp-hz = /bits/ 64 <81600>; + opp-microvolt = <100>; + clock-latency-ns = <4>; + }; + opp-100800 { + opp-hz = /bits/ 64 <100800>; + opp-microvolt = <110>; + clock-latency-ns = <4>; + }; + opp-12 { + opp-hz = /bits/ 64 <12>; + opp-microvolt = <1225000>; + clock-latency-ns = <4>; + }; + opp-129600 { + opp-hz = /bits/ 64 <129600>; + opp-microvolt = <130>; + clock-latency-ns = <4>; + }; + }; + amba { compatible = "simple-bus"; #address-cells = <2>; -- 2.7.4
[PATCH] cpufreq: dt: Add rk3328 compatible to use generic cpufreq driver
This patch adds the rk3328 compatible string for supporting the generic cpufreq driver on RK3328. Signed-off-by: Finley Xiao --- drivers/cpufreq/cpufreq-dt-platdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 096aea7..13c0c47 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -76,6 +76,7 @@ static const struct of_device_id machines[] __initconst = { { .compatible = "rockchip,rk3188", }, { .compatible = "rockchip,rk3228", }, { .compatible = "rockchip,rk3288", }, + { .compatible = "rockchip,rk3328", }, { .compatible = "rockchip,rk3366", }, { .compatible = "rockchip,rk3368", }, { .compatible = "rockchip,rk3399", }, -- 2.7.4
[PATCH 2/2] nvmem: rockchip-efuse: add support for rk3328-efuse
This adds the necessary data for handling eFuse on the rk3328. Signed-off-by: Finley Xiao --- .../devicetree/bindings/nvmem/rockchip-efuse.txt | 1 + drivers/nvmem/rockchip-efuse.c | 66 ++ 2 files changed, 67 insertions(+) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt index d206aa1..7a817c5 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt @@ -6,6 +6,7 @@ Required properties: - "rockchip,rk3188-efuse" - for RK3188 SoCs. - "rockchip,rk322x-efuse" - for RK322x SoCs. - "rockchip,rk3288-efuse" - for RK3288 SoCs. + - "rockchip,rk3328-efuse" - for RK3328 SoCs. - "rockchip,rk3399-efuse" - for RK3399 SoCs. - reg: Should contain the registers location and exact eFuse size - clocks: Should be the clock id of eFuse diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index 8e3e5d0..70c2d64 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -32,6 +32,14 @@ #define RK3288_STROBE BIT(1) #define RK3288_CSB BIT(0) +#define RK3328_SECURE_SIZES96 +#define RK3328_INT_STATUS 0x0018 +#define RK3328_DOUT0x0020 +#define RK3328_AUTO_CTRL 0x0024 +#define RK3328_INT_FINISH BIT(0) +#define RK3328_AUTO_ENBBIT(0) +#define RK3328_AUTO_RD BIT(1) + #define RK3399_A_SHIFT 16 #define RK3399_A_MASK 0x3ff #define RK3399_NBYTES 4 @@ -92,6 +100,60 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset, return 0; } +static int rockchip_rk3328_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) +{ + struct rockchip_efuse_chip *efuse = context; + unsigned int addr_start, addr_end, addr_offset, addr_len; + u32 out_value, status; + u8 *buf; + int ret, i = 0; + + ret = clk_prepare_enable(efuse->clk); + if (ret < 0) { + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n"); + return ret; + } + + /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */ + offset += RK3328_SECURE_SIZES; + addr_start = rounddown(offset, RK3399_NBYTES) / RK3399_NBYTES; + addr_end = roundup(offset + bytes, RK3399_NBYTES) / RK3399_NBYTES; + addr_offset = offset % RK3399_NBYTES; + addr_len = addr_end - addr_start; + + buf = kzalloc(sizeof(*buf) * addr_len * RK3399_NBYTES, GFP_KERNEL); + if (!buf) { + ret = -ENOMEM; + goto nomem; + } + + while (addr_len--) { + writel(RK3328_AUTO_RD | RK3328_AUTO_ENB | + ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT), + efuse->base + RK3328_AUTO_CTRL); + udelay(2); + status = readl(efuse->base + RK3328_INT_STATUS); + if (!(status & RK3328_INT_FINISH)) { + ret = -EIO; + goto err; + } + out_value = readl(efuse->base + RK3328_DOUT); + writel(RK3328_INT_FINISH, efuse->base + RK3328_INT_STATUS); + + memcpy(&buf[i], &out_value, RK3399_NBYTES); + i += RK3399_NBYTES; + } + + memcpy(val, buf + addr_offset, bytes); +err: + kfree(buf); +nomem: + clk_disable_unprepare(efuse->clk); + + return ret; +} + static int rockchip_rk3399_efuse_read(void *context, unsigned int offset, void *val, size_t bytes) { @@ -178,6 +240,10 @@ static const struct of_device_id rockchip_efuse_match[] = { .data = (void *)&rockchip_rk3288_efuse_read, }, { + .compatible = "rockchip,rk3328-efuse", + .data = (void *)&rockchip_rk3328_efuse_read, + }, + { .compatible = "rockchip,rk3399-efuse", .data = (void *)&rockchip_rk3399_efuse_read, }, -- 2.7.4
[PATCH 1/2] nvmem: rockchip-efuse: parse 'rockchip,efuse-size'
The eFuse size is defined in property before, but the length of registers is not equal to the size on some platforms, so we add a new property to redefine it. Signed-off-by: Finley Xiao --- Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt | 4 drivers/nvmem/rockchip-efuse.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt index 194926f..d206aa1 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt @@ -11,6 +11,10 @@ Required properties: - clocks: Should be the clock id of eFuse - clock-names: Should be "pclk_efuse" +Optional properties: +- rockchip,efuse-size: Should be exact eFuse size in byte, the eFuse + size in property will be invalid if define this property. + Deprecated properties: - compatible: "rockchip,rockchip-efuse" Old efuse compatible value compatible to rk3066a, rk3188 and rk3288 diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index a0d4ede..8e3e5d0 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -214,7 +214,9 @@ static int rockchip_efuse_probe(struct platform_device *pdev) return PTR_ERR(efuse->clk); efuse->dev = &pdev->dev; - econfig.size = resource_size(res); + if (of_property_read_u32(dev->of_node, "rockchip,efuse-size", +&econfig.size)) + econfig.size = resource_size(res); econfig.reg_read = match->data; econfig.priv = efuse; econfig.dev = efuse->dev; -- 2.7.4
[PATCH 0/2] nvmem: rockchip-efuse: add support for rk3328-efuse
Add a new property to define eFuse size and add the necessary data for handling eFuse on the rk3328. Finley Xiao (2): nvmem: rockchip-efuse: parse 'rockchip,efuse-size' nvmem: rockchip-efuse: add support for rk3328-efuse .../devicetree/bindings/nvmem/rockchip-efuse.txt | 5 ++ drivers/nvmem/rockchip-efuse.c | 70 +- 2 files changed, 74 insertions(+), 1 deletion(-) -- 2.7.4
[PATCH] nvmem: rockchip-efuse: add support for rk322x-efuse
This adds the necessary data for handling eFuse on the rk322x. Signed-off-by: Finley Xiao --- Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt | 1 + drivers/nvmem/rockchip-efuse.c | 4 2 files changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt index 94aeeea..194926f 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt @@ -4,6 +4,7 @@ Required properties: - compatible: Should be one of the following. - "rockchip,rk3066a-efuse" - for RK3066a SoCs. - "rockchip,rk3188-efuse" - for RK3188 SoCs. + - "rockchip,rk322x-efuse" - for RK322x SoCs. - "rockchip,rk3288-efuse" - for RK3288 SoCs. - "rockchip,rk3399-efuse" - for RK3399 SoCs. - reg: Should contain the registers location and exact eFuse size diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index 423907b..a0d4ede 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -170,6 +170,10 @@ static const struct of_device_id rockchip_efuse_match[] = { .data = (void *)&rockchip_rk3288_efuse_read, }, { + .compatible = "rockchip,rk322x-efuse", + .data = (void *)&rockchip_rk3288_efuse_read, + }, + { .compatible = "rockchip,rk3288-efuse", .data = (void *)&rockchip_rk3288_efuse_read, }, -- 2.7.4
Re: [PATCH v2 4/4] PM / AVS: rockchip-cpu-avs: add driver handling Rockchip cpu avs
在 2016/9/26 16:05, Heiko Stuebner 写道: Am Montag, 26. September 2016, 09:25:11 CEST schrieb Viresh Kumar: On 12-09-16, 14:55, Stephen Boyd wrote: On 08/29, Viresh Kumar wrote: On 18-08-16, 16:52, Finlye Xiao wrote: +static int rockchip_adjust_opp_table(struct device *cpu_dev, +struct cpufreq_frequency_table *table, +int volt) +{ + struct opp_table *opp_table; + struct cpufreq_frequency_table *pos; + struct dev_pm_opp *opp; + + if (!volt) + return 0; + + rcu_read_lock(); + + opp_table = _find_opp_table(cpu_dev); + if (IS_ERR(opp_table)) { + rcu_read_unlock(); + return PTR_ERR(opp_table); + } + + cpufreq_for_each_valid_entry(pos, table) { + opp = dev_pm_opp_find_freq_exact(cpu_dev, pos->frequency * 1000, +true); + if (IS_ERR(opp)) + continue; + + opp->u_volt += volt; + opp->u_volt_min += volt; + opp->u_volt_max += volt; + } + + rcu_read_unlock(); + + return 0; +} I wouldn't prefer altering the opp tables from individual drivers at all. At the least, it should be done via some helpers exposed by the core. But before that I would like to hear from Stephen a bit as I recall he was also working on something similar. I had a patch to modify the voltage at runtime for the "current" OPP. Now that we have regulator and clk control inside OPP that became a little easier to do without having to do some notifier from the OPP layer to the consumers. I haven't had time to revive those patches though. Should we do that? Perhaps yes, we should have a common place for doing all that. Does this need to modify anything besides the OPP the device is currently running at? Finlye, can you please answer this ? If I understand it correctly, depending on the leakage value stored in an efuse, all opp voltages are reduced by a certain value. Right now the driver does it in one go for the full opp table, but of course could also do it for each new opp individually before it gets set. Yes, it is necessary to modify all opp voltages and I agreed with Heiko. -- Finley
[PATCH v5 4/4] nvmem: rockchip-efuse: add rk3399-efuse support
1) the efuse timing of rk3399 is different from earlier SoCs. 2) rk3399-efuse is organized as 32bits by 32 one-time programmable electrical fuses, the efuse of earlier SoCs is organized as 32bits by 8 one-time programmable electrical fuses with random access interface. This patch adds a new read function for rk3399-efuse. Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- drivers/nvmem/rockchip-efuse.c | 133 +++-- 1 file changed, 114 insertions(+), 19 deletions(-) diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index 4d3f391..423907b 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -22,17 +22,29 @@ #include #include #include +#include #include -#define EFUSE_A_SHIFT 6 -#define EFUSE_A_MASK 0x3ff -#define EFUSE_PGENBBIT(3) -#define EFUSE_LOAD BIT(2) -#define EFUSE_STROBE BIT(1) -#define EFUSE_CSB BIT(0) - -#define REG_EFUSE_CTRL 0x -#define REG_EFUSE_DOUT 0x0004 +#define RK3288_A_SHIFT 6 +#define RK3288_A_MASK 0x3ff +#define RK3288_PGENB BIT(3) +#define RK3288_LOADBIT(2) +#define RK3288_STROBE BIT(1) +#define RK3288_CSB BIT(0) + +#define RK3399_A_SHIFT 16 +#define RK3399_A_MASK 0x3ff +#define RK3399_NBYTES 4 +#define RK3399_STROBSFTSEL BIT(9) +#define RK3399_RSB BIT(7) +#define RK3399_PD BIT(5) +#define RK3399_PGENB BIT(3) +#define RK3399_LOADBIT(2) +#define RK3399_STROBE BIT(1) +#define RK3399_CSB BIT(0) + +#define REG_EFUSE_CTRL 0x +#define REG_EFUSE_DOUT 0x0004 struct rockchip_efuse_chip { struct device *dev; @@ -40,8 +52,8 @@ struct rockchip_efuse_chip { struct clk *clk; }; -static int rockchip_efuse_read(void *context, unsigned int offset, - void *val, size_t bytes) +static int rockchip_rk3288_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) { struct rockchip_efuse_chip *efuse = context; u8 *buf = val; @@ -53,27 +65,82 @@ static int rockchip_efuse_read(void *context, unsigned int offset, return ret; } - writel(EFUSE_LOAD | EFUSE_PGENB, efuse->base + REG_EFUSE_CTRL); + writel(RK3288_LOAD | RK3288_PGENB, efuse->base + REG_EFUSE_CTRL); udelay(1); while (bytes--) { writel(readl(efuse->base + REG_EFUSE_CTRL) & -(~(EFUSE_A_MASK << EFUSE_A_SHIFT)), +(~(RK3288_A_MASK << RK3288_A_SHIFT)), efuse->base + REG_EFUSE_CTRL); writel(readl(efuse->base + REG_EFUSE_CTRL) | -((offset++ & EFUSE_A_MASK) << EFUSE_A_SHIFT), +((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT), efuse->base + REG_EFUSE_CTRL); udelay(1); writel(readl(efuse->base + REG_EFUSE_CTRL) | -EFUSE_STROBE, efuse->base + REG_EFUSE_CTRL); +RK3288_STROBE, efuse->base + REG_EFUSE_CTRL); udelay(1); *buf++ = readb(efuse->base + REG_EFUSE_DOUT); writel(readl(efuse->base + REG_EFUSE_CTRL) & -(~EFUSE_STROBE), efuse->base + REG_EFUSE_CTRL); + (~RK3288_STROBE), efuse->base + REG_EFUSE_CTRL); + udelay(1); + } + + /* Switch to standby mode */ + writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL); + + clk_disable_unprepare(efuse->clk); + + return 0; +} + +static int rockchip_rk3399_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) +{ + struct rockchip_efuse_chip *efuse = context; + unsigned int addr_start, addr_end, addr_offset, addr_len; + u32 out_value; + u8 *buf; + int ret, i = 0; + + ret = clk_prepare_enable(efuse->clk); + if (ret < 0) { + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n"); + return ret; + } + + addr_start = rounddown(offset, RK3399_NBYTES) / RK3399_NBYTES; + addr_end = roundup(offset + bytes, RK3399_NBYTES) / RK3399_NBYTES; + addr_offset = offset % RK3399_NBYTES; + addr_len = addr_end - addr_start; + + buf = kzalloc(sizeof(*buf) * addr_len * RK3399_NBYTES, GFP_KERNEL); + if (!buf) { + clk_disable_unprepare(efuse->clk); + return -ENOMEM; + } + + writel(RK3399_LOAD | RK3
[PATCH v5 1/4] nvmem: rockchip-efuse: update compatible strings for Rockchip efuse
Rk3399-efuse is organized as 32bits by 32 one-time programmable electrical fuses. The efuse of earlier SoCs are organized as 32bits by 8 one-time programmable electrical fuses with random access interface. Add different device tree compatible string for different SoCs to be able to differentiate between the two. The old binding is of course preserved, though deprecated. Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt index 8f86ab3..94aeeea 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt @@ -1,11 +1,20 @@ = Rockchip eFuse device tree bindings = Required properties: -- compatible: Should be "rockchip,rockchip-efuse" +- compatible: Should be one of the following. + - "rockchip,rk3066a-efuse" - for RK3066a SoCs. + - "rockchip,rk3188-efuse" - for RK3188 SoCs. + - "rockchip,rk3288-efuse" - for RK3288 SoCs. + - "rockchip,rk3399-efuse" - for RK3399 SoCs. - reg: Should contain the registers location and exact eFuse size - clocks: Should be the clock id of eFuse - clock-names: Should be "pclk_efuse" +Deprecated properties: +- compatible: "rockchip,rockchip-efuse" + Old efuse compatible value compatible to rk3066a, rk3188 and rk3288 + efuses + = Data cells = Are child nodes of eFuse, bindings of which as described in bindings/nvmem/nvmem.txt @@ -13,7 +22,7 @@ bindings/nvmem/nvmem.txt Example: efuse: efuse@ffb4 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3288-efuse"; reg = <0xffb4 0x20>; #address-cells = <1>; #size-cells = <1>; -- 2.7.4
[PATCH v5 2/4] ARM: dts: rockchip: update compatible strings for Rockchip efuse
Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a.dtsi | 2 +- arch/arm/boot/dts/rk3188.dtsi | 2 +- arch/arm/boot/dts/rk3288.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index c0ba86c..5387cc8 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -162,7 +162,7 @@ }; efuse: efuse@2001 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3066a-efuse"; reg = <0x2001 0x4000>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 31f81b2..869e189 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -147,7 +147,7 @@ }; efuse: efuse@2001 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3188-efuse"; reg = <0x2001 0x4000>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index cd33f01..0eadb96 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -1073,7 +1073,7 @@ }; efuse: efuse@ffb4 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3288-efuse"; reg = <0xffb4 0x20>; #address-cells = <1>; #size-cells = <1>; -- 2.7.4
[PATCH v5 3/4] arm64: dts: rockchip: add efuse0 device node for rk3399
Add a efuse0 node in the device tree for the ARM64 rk3399 SoC. Signed-off-by: Finley Xiao --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 29 + 1 file changed, 29 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index a6dd623..05b48e2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -721,6 +721,35 @@ status = "disabled"; }; + efuse0: efuse@ff69 { + compatible = "rockchip,rk3399-efuse"; + reg = <0x0 0xff69 0x0 0x80>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&cru PCLK_EFUSE1024NS>; + clock-names = "pclk_efuse"; + + /* Data cells */ + cpul_leakage: cpul-leakage { + reg = <0x1a 0x1>; + }; + cpub_leakage: cpub-leakage { + reg = <0x17 0x1>; + }; + gpu_leakage: gpu-leakage { + reg = <0x18 0x1>; + }; + center_leakage: center-leakage { + reg = <0x19 0x1>; + }; + logic_leakage: logic-leakage { + reg = <0x1b 0x1>; + }; + wafer_info: wafer-info { + reg = <0x1c 0x1>; + }; + }; + pmucru: pmu-clock-controller@ff75 { compatible = "rockchip,rk3399-pmucru"; reg = <0x0 0xff75 0x0 0x1000>; -- 2.7.4
[PATCH v5 0/4] nvmem: rockchip-efuse: support more rockchip SoCs
As the timing and organization of efuse may be different between rockchip SoCs, so their read function may be different. We add different device tree compatible string for rockchip SoCs to match their own read function. V4->V5: - 3/4 alter the efuse node name - 4/4 align the macro definition disable clk if fail to allocate memory Finley Xiao (4): nvmem: rockchip-efuse: update compatible strings for Rockchip efuse ARM: dts: rockchip: update compatible strings for Rockchip efuse arm64: dts: rockchip: add efuse0 device node for rk3399 nvmem: rockchip-efuse: add rk3399-efuse support .../devicetree/bindings/nvmem/rockchip-efuse.txt | 13 +- arch/arm/boot/dts/rk3066a.dtsi | 2 +- arch/arm/boot/dts/rk3188.dtsi | 2 +- arch/arm/boot/dts/rk3288.dtsi | 2 +- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 29 + drivers/nvmem/rockchip-efuse.c | 133 ++--- 6 files changed, 157 insertions(+), 24 deletions(-) -- 2.7.4
[PATCH v4 0/3] nvmem: rockchip-efuse: support more rockchip SoCs
As the timing and organization of efuse may be different between rockchip SoCs, so their read function may be different. We add different device tree compatible string for rockchip SoCs to match their own read function. V3->V4: - 3/3 change the type of out_value into u32 and buf into u8, their values come from register, use u32 and u8 may be more readable. Finley Xiao (3): nvmem: rockchip-efuse: update compatible strings for Rockchip efuse ARM: dts: rockchip: update compatible strings for Rockchip efuse nvmem: rockchip-efuse: add rk3399-efuse support .../devicetree/bindings/nvmem/rockchip-efuse.txt | 13 +- arch/arm/boot/dts/rk3066a.dtsi | 2 +- arch/arm/boot/dts/rk3188.dtsi | 2 +- arch/arm/boot/dts/rk3288.dtsi | 2 +- drivers/nvmem/rockchip-efuse.c | 131 ++--- 5 files changed, 126 insertions(+), 24 deletions(-) -- 1.9.1
[PATCH v4 3/3] nvmem: rockchip-efuse: add rk3399-efuse support
1) the efuse timing of rk3399 is different from earlier SoCs. 2) rk3399-efuse is organized as 32bits by 32 one-time programmable electrical fuses, the efuse of earlier SoCs is organized as 32bits by 8 one-time programmable electrical fuses with random access interface. This patch adds a new read function for rk3399-efuse. Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- drivers/nvmem/rockchip-efuse.c | 131 +++-- 1 file changed, 112 insertions(+), 19 deletions(-) diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index 4d3f391..1825fd3 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -22,17 +22,29 @@ #include #include #include +#include #include -#define EFUSE_A_SHIFT 6 -#define EFUSE_A_MASK 0x3ff -#define EFUSE_PGENBBIT(3) -#define EFUSE_LOAD BIT(2) -#define EFUSE_STROBE BIT(1) -#define EFUSE_CSB BIT(0) - -#define REG_EFUSE_CTRL 0x -#define REG_EFUSE_DOUT 0x0004 +#define RK3288_A_SHIFT 6 +#define RK3288_A_MASK 0x3ff +#define RK3288_PGENB BIT(3) +#define RK3288_LOADBIT(2) +#define RK3288_STROBE BIT(1) +#define RK3288_CSB BIT(0) + +#define RK3399_A_SHIFT 16 +#define RK3399_A_MASK 0x3ff +#define RK3399_NBYTES 4 +#define RK3399_STROBSFTSEL BIT(9) +#define RK3399_RSB BIT(7) +#define RK3399_PD BIT(5) +#define RK3399_PGENB BIT(3) +#define RK3399_LOADBIT(2) +#define RK3399_STROBE BIT(1) +#define RK3399_CSB BIT(0) + +#define REG_EFUSE_CTRL 0x +#define REG_EFUSE_DOUT 0x0004 struct rockchip_efuse_chip { struct device *dev; @@ -40,8 +52,8 @@ struct rockchip_efuse_chip { struct clk *clk; }; -static int rockchip_efuse_read(void *context, unsigned int offset, - void *val, size_t bytes) +static int rockchip_rk3288_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) { struct rockchip_efuse_chip *efuse = context; u8 *buf = val; @@ -53,27 +65,80 @@ static int rockchip_efuse_read(void *context, unsigned int offset, return ret; } - writel(EFUSE_LOAD | EFUSE_PGENB, efuse->base + REG_EFUSE_CTRL); + writel(RK3288_LOAD | RK3288_PGENB, efuse->base + REG_EFUSE_CTRL); udelay(1); while (bytes--) { writel(readl(efuse->base + REG_EFUSE_CTRL) & -(~(EFUSE_A_MASK << EFUSE_A_SHIFT)), +(~(RK3288_A_MASK << RK3288_A_SHIFT)), efuse->base + REG_EFUSE_CTRL); writel(readl(efuse->base + REG_EFUSE_CTRL) | -((offset++ & EFUSE_A_MASK) << EFUSE_A_SHIFT), +((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT), efuse->base + REG_EFUSE_CTRL); udelay(1); writel(readl(efuse->base + REG_EFUSE_CTRL) | -EFUSE_STROBE, efuse->base + REG_EFUSE_CTRL); +RK3288_STROBE, efuse->base + REG_EFUSE_CTRL); udelay(1); *buf++ = readb(efuse->base + REG_EFUSE_DOUT); writel(readl(efuse->base + REG_EFUSE_CTRL) & -(~EFUSE_STROBE), efuse->base + REG_EFUSE_CTRL); +(~RK3288_STROBE), efuse->base + REG_EFUSE_CTRL); udelay(1); } /* Switch to standby mode */ - writel(EFUSE_PGENB | EFUSE_CSB, efuse->base + REG_EFUSE_CTRL); + writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL); + + clk_disable_unprepare(efuse->clk); + + return 0; +} + +static int rockchip_rk3399_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) +{ + struct rockchip_efuse_chip *efuse = context; + unsigned int addr_start, addr_end, addr_offset, addr_len; + u32 out_value; + u8 *buf; + int ret, i = 0; + + ret = clk_prepare_enable(efuse->clk); + if (ret < 0) { + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n"); + return ret; + } + + addr_start = rounddown(offset, RK3399_NBYTES) / RK3399_NBYTES; + addr_end = roundup(offset + bytes, RK3399_NBYTES) / RK3399_NBYTES; + addr_offset = offset % RK3399_NBYTES; + addr_len = addr_end - addr_start; + + buf = kzalloc(sizeof(*buf) * addr_len * RK3399_NBYTES, GFP_KERNEL); + if (!buf) +
[PATCH v4 2/3] ARM: dts: rockchip: update compatible strings for Rockchip efuse
Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a.dtsi | 2 +- arch/arm/boot/dts/rk3188.dtsi | 2 +- arch/arm/boot/dts/rk3288.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index c0ba86c..5387cc8 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -162,7 +162,7 @@ }; efuse: efuse@2001 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3066a-efuse"; reg = <0x2001 0x4000>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 31f81b2..869e189 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -147,7 +147,7 @@ }; efuse: efuse@2001 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3188-efuse"; reg = <0x2001 0x4000>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index cd33f01..0eadb96 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -1073,7 +1073,7 @@ }; efuse: efuse@ffb4 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3288-efuse"; reg = <0xffb4 0x20>; #address-cells = <1>; #size-cells = <1>; -- 1.9.1
[PATCH v4 1/3] nvmem: rockchip-efuse: update compatible strings for Rockchip efuse
Rk3399-efuse is organized as 32bits by 32 one-time programmable electrical fuses. The efuse of earlier SoCs are organized as 32bits by 8 one-time programmable electrical fuses with random access interface. Add different device tree compatible string for different SoCs to be able to differentiate between the two. The old binding is of course preserved, though deprecated. Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt index 8f86ab3..94aeeea 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt @@ -1,11 +1,20 @@ = Rockchip eFuse device tree bindings = Required properties: -- compatible: Should be "rockchip,rockchip-efuse" +- compatible: Should be one of the following. + - "rockchip,rk3066a-efuse" - for RK3066a SoCs. + - "rockchip,rk3188-efuse" - for RK3188 SoCs. + - "rockchip,rk3288-efuse" - for RK3288 SoCs. + - "rockchip,rk3399-efuse" - for RK3399 SoCs. - reg: Should contain the registers location and exact eFuse size - clocks: Should be the clock id of eFuse - clock-names: Should be "pclk_efuse" +Deprecated properties: +- compatible: "rockchip,rockchip-efuse" + Old efuse compatible value compatible to rk3066a, rk3188 and rk3288 + efuses + = Data cells = Are child nodes of eFuse, bindings of which as described in bindings/nvmem/nvmem.txt @@ -13,7 +22,7 @@ bindings/nvmem/nvmem.txt Example: efuse: efuse@ffb4 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3288-efuse"; reg = <0xffb4 0x20>; #address-cells = <1>; #size-cells = <1>; -- 1.9.1
[PATCH v3 1/3] nvmem: rockchip-efuse: update compatible strings for Rockchip efuse
Rk3399-efuse is organized as 32bits by 32 one-time programmable electrical fuses. The efuse of earlier SoCs are organized as 32bits by 8 one-time programmable electrical fuses with random access interface. Add different device tree compatible string for different SoCs to be able to differentiate between the two. The old binding is of course preserved, though deprecated. Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt index 8f86ab3..94aeeea 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt @@ -1,11 +1,20 @@ = Rockchip eFuse device tree bindings = Required properties: -- compatible: Should be "rockchip,rockchip-efuse" +- compatible: Should be one of the following. + - "rockchip,rk3066a-efuse" - for RK3066a SoCs. + - "rockchip,rk3188-efuse" - for RK3188 SoCs. + - "rockchip,rk3288-efuse" - for RK3288 SoCs. + - "rockchip,rk3399-efuse" - for RK3399 SoCs. - reg: Should contain the registers location and exact eFuse size - clocks: Should be the clock id of eFuse - clock-names: Should be "pclk_efuse" +Deprecated properties: +- compatible: "rockchip,rockchip-efuse" + Old efuse compatible value compatible to rk3066a, rk3188 and rk3288 + efuses + = Data cells = Are child nodes of eFuse, bindings of which as described in bindings/nvmem/nvmem.txt @@ -13,7 +22,7 @@ bindings/nvmem/nvmem.txt Example: efuse: efuse@ffb4 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3288-efuse"; reg = <0xffb4 0x20>; #address-cells = <1>; #size-cells = <1>; -- 1.9.1
[PATCH v3 0/3] nvmem: rockchip-efuse: support more rockchip SoCs
As the timing and organization of efuse may be different between rockchip SoCs, so their read function may be different. We add different device tree compatible string for rockchip SoCs to match their own read function. V2->V3: - delete patch 3/4 in v2, don't add efuse0 device node - 3/3 fix read data error sometimes by disable efuse redundancy Finley Xiao (3): nvmem: rockchip-efuse: update compatible strings for Rockchip efuse ARM: dts: rockchip: update compatible strings for Rockchip efuse nvmem: rockchip-efuse: add rk3399-efuse support .../devicetree/bindings/nvmem/rockchip-efuse.txt | 13 +- arch/arm/boot/dts/rk3066a.dtsi | 2 +- arch/arm/boot/dts/rk3188.dtsi | 2 +- arch/arm/boot/dts/rk3288.dtsi | 2 +- drivers/nvmem/rockchip-efuse.c | 131 ++--- 5 files changed, 126 insertions(+), 24 deletions(-) -- 1.9.1
[PATCH v3 2/3] ARM: dts: rockchip: update compatible strings for Rockchip efuse
Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a.dtsi | 2 +- arch/arm/boot/dts/rk3188.dtsi | 2 +- arch/arm/boot/dts/rk3288.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index c0ba86c..5387cc8 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -162,7 +162,7 @@ }; efuse: efuse@2001 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3066a-efuse"; reg = <0x2001 0x4000>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 31f81b2..869e189 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -147,7 +147,7 @@ }; efuse: efuse@2001 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3188-efuse"; reg = <0x2001 0x4000>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index cd33f01..0eadb96 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -1073,7 +1073,7 @@ }; efuse: efuse@ffb4 { - compatible = "rockchip,rockchip-efuse"; + compatible = "rockchip,rk3288-efuse"; reg = <0xffb4 0x20>; #address-cells = <1>; #size-cells = <1>; -- 1.9.1
[PATCH v3 3/3] nvmem: rockchip-efuse: add rk3399-efuse support
1) the efuse timing of rk3399 is different from earlier SoCs. 2) rk3399-efuse is organized as 32bits by 32 one-time programmable electrical fuses, the efuse of earlier SoCs is organized as 32bits by 8 one-time programmable electrical fuses with random access interface. This patch adds a new read function for rk3399-efuse. Signed-off-by: Finley Xiao Reviewed-by: Heiko Stuebner --- drivers/nvmem/rockchip-efuse.c | 131 +++-- 1 file changed, 112 insertions(+), 19 deletions(-) diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index 4d3f391..2fb6c34 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -22,17 +22,29 @@ #include #include #include +#include #include -#define EFUSE_A_SHIFT 6 -#define EFUSE_A_MASK 0x3ff -#define EFUSE_PGENBBIT(3) -#define EFUSE_LOAD BIT(2) -#define EFUSE_STROBE BIT(1) -#define EFUSE_CSB BIT(0) - -#define REG_EFUSE_CTRL 0x -#define REG_EFUSE_DOUT 0x0004 +#define RK3288_A_SHIFT 6 +#define RK3288_A_MASK 0x3ff +#define RK3288_PGENB BIT(3) +#define RK3288_LOADBIT(2) +#define RK3288_STROBE BIT(1) +#define RK3288_CSB BIT(0) + +#define RK3399_A_SHIFT 16 +#define RK3399_A_MASK 0x3ff +#define RK3399_NBYTES 4 +#define RK3399_STROBSFTSEL BIT(9) +#define RK3399_RSB BIT(7) +#define RK3399_PD BIT(5) +#define RK3399_PGENB BIT(3) +#define RK3399_LOADBIT(2) +#define RK3399_STROBE BIT(1) +#define RK3399_CSB BIT(0) + +#define REG_EFUSE_CTRL 0x +#define REG_EFUSE_DOUT 0x0004 struct rockchip_efuse_chip { struct device *dev; @@ -40,8 +52,8 @@ struct rockchip_efuse_chip { struct clk *clk; }; -static int rockchip_efuse_read(void *context, unsigned int offset, - void *val, size_t bytes) +static int rockchip_rk3288_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) { struct rockchip_efuse_chip *efuse = context; u8 *buf = val; @@ -53,27 +65,80 @@ static int rockchip_efuse_read(void *context, unsigned int offset, return ret; } - writel(EFUSE_LOAD | EFUSE_PGENB, efuse->base + REG_EFUSE_CTRL); + writel(RK3288_LOAD | RK3288_PGENB, efuse->base + REG_EFUSE_CTRL); udelay(1); while (bytes--) { writel(readl(efuse->base + REG_EFUSE_CTRL) & -(~(EFUSE_A_MASK << EFUSE_A_SHIFT)), +(~(RK3288_A_MASK << RK3288_A_SHIFT)), efuse->base + REG_EFUSE_CTRL); writel(readl(efuse->base + REG_EFUSE_CTRL) | -((offset++ & EFUSE_A_MASK) << EFUSE_A_SHIFT), +((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT), efuse->base + REG_EFUSE_CTRL); udelay(1); writel(readl(efuse->base + REG_EFUSE_CTRL) | -EFUSE_STROBE, efuse->base + REG_EFUSE_CTRL); +RK3288_STROBE, efuse->base + REG_EFUSE_CTRL); udelay(1); *buf++ = readb(efuse->base + REG_EFUSE_DOUT); writel(readl(efuse->base + REG_EFUSE_CTRL) & -(~EFUSE_STROBE), efuse->base + REG_EFUSE_CTRL); +(~RK3288_STROBE), efuse->base + REG_EFUSE_CTRL); udelay(1); } /* Switch to standby mode */ - writel(EFUSE_PGENB | EFUSE_CSB, efuse->base + REG_EFUSE_CTRL); + writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL); + + clk_disable_unprepare(efuse->clk); + + return 0; +} + +static int rockchip_rk3399_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) +{ + struct rockchip_efuse_chip *efuse = context; + unsigned int addr_start, addr_end, addr_offset, addr_len; + unsigned int out_value; + unsigned char *buf; + int ret, i = 0; + + ret = clk_prepare_enable(efuse->clk); + if (ret < 0) { + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n"); + return ret; + } + + addr_start = rounddown(offset, RK3399_NBYTES) / RK3399_NBYTES; + addr_end = roundup(offset + bytes, RK3399_NBYTES) / RK3399_NBYTES; + addr_offset = offset % RK3399_NBYTES; + addr_len = addr_end - addr_start; + + buf = kzalloc(sizeof(*buf) * addr_len * RK3399_NBYTES, GFP_KERNEL); +
Re: [PATCH v1 3/3] PM / AVS: rockchip-cpu-avs: add driver handling Rockchip cpu avs
在 2016/8/23 17:03, Heiko Stübner 写道: Hi Finley, Am Dienstag, 23. August 2016, 12:10:27 schrieb Finley Xiao: 在 2016/8/19 21:36, Rob Herring 写道: On Tue, Aug 16, 2016 at 10:38:59AM +0800, Finlye Xiao wrote: From: Finley Xiao This patch supports adjusting opp's voltage according to leakage Signed-off-by: Finley Xiao --- .../devicetree/bindings/power/rockchip-cpu-avs.txt | 37 +++ drivers/power/avs/Kconfig | 8 + drivers/power/avs/Makefile | 1 + drivers/power/avs/rockchip-cpu-avs.c | 314 + 4 files changed, 360 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt create mode 100644 drivers/power/avs/rockchip-cpu-avs.c diff --git a/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt b/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt new file mode 100644 index 000..90f6b08 --- /dev/null +++ b/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt @@ -0,0 +1,37 @@ +Rockchip cpu avs device tree bindings +- + +Under the same frequency, the operating voltage tends to decrease with +increasing leakage. so it is necessary to adjust opp's voltage according +to leakage for power. + + +Required properties: +- compatible: Should be one of the following. + - "rockchip,rk3399-cpu-avs" - for RK3399 SoCs. +- leakage-volt-: Named leakage-volt property. At runtime, the + platform can find a cpu's cluster_id according to it's cpu_id and match + leakage-volt- property. The property is an array of 3-tuples + items, and each item consists of leakage and voltage like + . + min-leakage: minimum leakage in mA. + max-leakage: maximum leakage in mA. + vol: voltage in microvolt. How do you determine these values? When do they vary? How do you determine these values? run antutu-benchmark leakage freqmin_volt 30mA1608MHz 1025mV 40mA1608MHz 1000mV 50mA1608MHz 975mV From the table, we see the min_volt decrease with increasing leakage. So we can set the default opp-microvolt 1025mV for 1608MHz, and add an leakage_volt_cluster0 property as follows. leakage_volt_cluster0 = < /* min(mA) max(mA)volt(uV)*/ 0 400 4150(-25000) 51254 (-5) ; If the leakage is between 41mA and 50mA,the opp-microvolt will subtract 25mV。 If the leakage is between 41mA and 50mA,the opp-microvolt will subtract 50mV。 When do they vary? From the code, cpufreq_online --cpufreq_driver->init(policy); /* add new opp table */ --blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_START, policy); --cpufreq_init_policy cpufreq_set_policy __cpufreq_governor(policy, CPUFREQ_GOV_START); The cpu's opp table is added in the init function(cpufreq_init),and I will register a cpufreq notifier, once the first cpu of cluster is onlined, my notifer will be called, and if the event is CPUFREQ_START,it will modify the opp-microvolt according to leakage_volt_cluster0. I think what Rob was asking with "when do they vary" is, are these leakage values the same for each and every rk3399 soc or are they determined separately for each board-type using the rk3399. Oh, sorry, I misunderstood. They are the same for every rk3399 soc. -- Finley
Re: [PATCH v1 3/3] PM / AVS: rockchip-cpu-avs: add driver handling Rockchip cpu avs
在 2016/8/19 21:36, Rob Herring 写道: On Tue, Aug 16, 2016 at 10:38:59AM +0800, Finlye Xiao wrote: From: Finley Xiao This patch supports adjusting opp's voltage according to leakage Signed-off-by: Finley Xiao --- .../devicetree/bindings/power/rockchip-cpu-avs.txt | 37 +++ drivers/power/avs/Kconfig | 8 + drivers/power/avs/Makefile | 1 + drivers/power/avs/rockchip-cpu-avs.c | 314 + 4 files changed, 360 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt create mode 100644 drivers/power/avs/rockchip-cpu-avs.c diff --git a/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt b/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt new file mode 100644 index 000..90f6b08 --- /dev/null +++ b/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt @@ -0,0 +1,37 @@ +Rockchip cpu avs device tree bindings +- + +Under the same frequency, the operating voltage tends to decrease with +increasing leakage. so it is necessary to adjust opp's voltage according +to leakage for power. + + +Required properties: +- compatible: Should be one of the following. + - "rockchip,rk3399-cpu-avs" - for RK3399 SoCs. +- leakage-volt-: Named leakage-volt property. At runtime, the + platform can find a cpu's cluster_id according to it's cpu_id and match + leakage-volt- property. The property is an array of 3-tuples + items, and each item consists of leakage and voltage like + . + min-leakage: minimum leakage in mA. + max-leakage: maximum leakage in mA. + vol: voltage in microvolt. How do you determine these values? When do they vary? How do you determine these values? run antutu-benchmark leakage freqmin_volt 30mA1608MHz 1025mV 40mA1608MHz 1000mV 50mA1608MHz 975mV From the table, we see the min_volt decrease with increasing leakage. So we can set the default opp-microvolt 1025mV for 1608MHz, and add an leakage_volt_cluster0 property as follows. leakage_volt_cluster0 = < /* min(mA) max(mA)volt(uV)*/ 0 400 4150(-25000) 51254 (-5) ; If the leakage is between 41mA and 50mA,the opp-microvolt will subtract 25mV。 If the leakage is between 41mA and 50mA,the opp-microvolt will subtract 50mV。 When do they vary? From the code, cpufreq_online --cpufreq_driver->init(policy); /* add new opp table */ --blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_START, policy); --cpufreq_init_policy cpufreq_set_policy __cpufreq_governor(policy, CPUFREQ_GOV_START); The cpu's opp table is added in the init function(cpufreq_init),and I will register a cpufreq notifier, once the first cpu of cluster is onlined, my notifer will be called, and if the event is CPUFREQ_START,it will modify the opp-microvolt according to leakage_volt_cluster0. + +Example: + + cpu_avs: cpu-avs { + compatible = "rockchip,rk3399-cpu-avs"; This isn't really a hardware block. For the same reasons we don't have cpufreq nodes. So I don't think this belongs in DT. if I delete the compatible property like the thermal-zones node, is it allowed? cpu_avs: cpu-avs { leakage_volt_cluster0 = < /* min(mA) max(mA)volt(uV)*/ 0 400 4150(-25000) 51254 (-5) >; leakage_volt_cluster1 = < /* min(mA) max(mA)volt(uV)*/ 0 400 4150(-25000) 51254 (-5) >; } Rob -- Finley
Re: [PATCH v1 2/3] of: Add support for reading a s32 from a multi-value property.
在 2016/8/20 4:47, David Woodhouse 写道: On Fri, 2016-08-19 at 22:41 +0200, Heiko Stuebner wrote: So no, don't *add* any more of these functions. Only add the generic version. And if your driver isn't using the generic property functions... fix it. As far as I can see, all the device_property_* functions are grounded on their of_property_*, acpi_property_* etc counterparts and functions reading specific elements (the _index variants) are currently not available at all. drivers/base/property.c: #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ : of_property_count_elems_of_size((node), (propname), sizeof(type)) So even if you're using the device_property_* functions you'd still need a match in the underlying functions or am I missing something? Yes, but the underlying function should never be used directly by drivers. And should probably be prefixed with __ or marked deprecated (with an override in its one genuine call site). So can I add a device_property_read_s32_array function in property.h? --- a/include/linux/property.h +++ b/include/linux/property.h @@ -108,6 +108,13 @@ static inline int device_property_read_u32(struct device *dev, return device_property_read_u32_array(dev, propname, val, 1); } +static inline int device_property_read_s32_array(struct device *dev, const char *propname, + s32 *val, size_t nval) +{ + return device_property_read_u32_array(struct device *dev, const char *propname, + (u32 *)val, size_t nval); +} -- Finley
Re: [PATCH v1 3/3] PM / AVS: rockchip-cpu-avs: add driver handling Rockchip cpu avs
在 2016/8/17 1:24, Heiko Stübner 写道: Hi Finley, Am Dienstag, 16. August 2016, 10:38:59 schrieb Finlye Xiao: From: Finley Xiao This patch supports adjusting opp's voltage according to leakage Signed-off-by: Finley Xiao we of course talked about this before and it generally looks good, I just found a bunch of smaller issues below. --- .../devicetree/bindings/power/rockchip-cpu-avs.txt | 37 +++ drivers/power/avs/Kconfig | 8 + drivers/power/avs/Makefile | 1 + drivers/power/avs/rockchip-cpu-avs.c | 314 + 4 files changed, 360 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt create mode 100644 drivers/power/avs/rockchip-cpu-avs.c diff --git a/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt b/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt new file mode 100644 index 000..90f6b08 --- /dev/null +++ b/Documentation/devicetree/bindings/power/rockchip-cpu-avs.txt the binding should generally be a separate patch, so that Rob and other devicetree-maintainers can spot them better, so name it something like dt-bindings: add binding document for Rockchip cpu avs or similar. @@ -0,0 +1,37 @@ +Rockchip cpu avs device tree bindings +- + +Under the same frequency, the operating voltage tends to decrease with +increasing leakage. so it is necessary to adjust opp's voltage according +to leakage for power. + + +Required properties: +- compatible: Should be one of the following. + - "rockchip,rk3399-cpu-avs" - for RK3399 SoCs. +- leakage-volt-: Named leakage-volt property. At runtime, the + platform can find a cpu's cluster_id according to it's cpu_id and match + leakage-volt- property. The property is an array of 3-tuples + items, and each item consists of leakage and voltage like + . vol -> volt ? + min-leakage: minimum leakage in mA. + max-leakage: maximum leakage in mA. + vol: voltage in microvolt. vol -> volt? maybe also make that volt: voltage offset in mV to apply to the opp table entries + +Example: + + cpu_avs: cpu-avs { + compatible = "rockchip,rk3399-cpu-avs"; + leakage-volt-cluster0 = < + /* mAmA uV*/ + 0 1000 + 101 200(-25000) + 201 300(-5) + >; + leakage-volt-cluster1 = < + /* mAmA uV*/ + 0 1000 + 101 200(-25000) + 201 300(-5) + >; + }; diff --git a/drivers/power/avs/Kconfig b/drivers/power/avs/Kconfig index a67eeac..c8f2d09 100644 --- a/drivers/power/avs/Kconfig +++ b/drivers/power/avs/Kconfig @@ -18,3 +18,11 @@ config ROCKCHIP_IODOMAIN Say y here to enable support io domains on Rockchip SoCs. It is necessary for the io domain setting of the SoC to match the voltage supplied by the regulators. + +config ROCKCHIP_CPU_AVS +bool "Rockchip CPU AVS support" +depends on POWER_AVS && ARCH_ROCKCHIP && OF as the kbuild-robot found out, you'll need as well a depends on CPU_FREQ also, I don't know if this also applies to the rk3288 and before (arm32), but if so and with your generic depends on ARCH_ROCKCHIP, you'd also need a depends on ARM_CPU_TOPOLOGY if ARM as the topology-stuff is not always active on arm32. +help + Say y here to enable support CPU AVS on Rockchip SoCs. + The cpu's operating voltage is adapted depending on leakage + or pvtm. diff --git a/drivers/power/avs/Makefile b/drivers/power/avs/Makefile index ba4c7bc..11ce242 100644 --- a/drivers/power/avs/Makefile +++ b/drivers/power/avs/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_POWER_AVS_OMAP) += smartreflex.o obj-$(CONFIG_ROCKCHIP_IODOMAIN) += rockchip-io-domain.o +obj-$(CONFIG_ROCKCHIP_CPU_AVS) += rockchip-cpu-avs.o diff --git a/drivers/power/avs/rockchip-cpu-avs.c b/drivers/power/avs/rockchip-cpu-avs.c new file mode 100644 index 000..8266c02 --- /dev/null +++ b/drivers/power/avs/rockchip-cpu-avs.c @@ -0,0 +1,314 @@ +/* + * Rockchip CPU AVS support. + * + * Copyright (c) 2016 ROCKCHIP, Co. Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt copy'n'pasted from somewhere? Should probably not be here +#include +#include +#include +#include +#include +#include +#include +#include +#incl
Re: [PATCH v2] cpufreq: rockchip: add driver
Hi Viresh, can we add a of_match_table with a common compatible name as follows ? --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -470,10 +470,16 @@ static int dt_cpufreq_remove(struct platform_device *pdev) cpufreq_unregister_driver(&dt_cpufreq_driver); return 0; } +static const struct of_device_id dt_cpufreq_of_match[] = { + { .compatible = "***,***", }, + { } +}; +MODULE_DEVICE_TABLE(of, dt_cpufreq_of_match); static struct platform_driver dt_cpufreq_platdrv = { .driver = { .name = "cpufreq-dt", + .of_match_table = dt_cpufreq_of_match, }, --- a/arch/arm64/boot/dts/rockchip/rk3366.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3366.dtsi + cpufreq { + compatible = "***,***"; + } Does it create a DT node for a dummy device too ? 在 2016/3/24 14:43, Viresh Kumar 写道: On 24-03-16, 11:01, Feng Xiao wrote: hi all, I found that it could match the cpufreq-dt driver succesfully only with the following changes. --- a/arch/arm64/boot/dts/rockchip/rk3366.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3366.dtsi @@ -139,6 +139,10 @@ }; }; + cpufreq-dt { //the node name must be cpufreq-dt + compatible = "rockchip,cpufreq"; // the compatible name is insignificant + }; + Its not allowed to create a DT node for a dummy device and so we never followed this way. I have just sent a patchset and cc'd you: "[PATCH 0/3] cpufreq: dt: Create platform device from generic code" and so this patch shall get replaced now. -- Finley