Re: [PATCH v2 3/5] devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A.
From: Matthias Kaehlcke
Date: Tue Mar 19 2019 - 20:33:57 EST
Hi GaÃl,
On Tue, Mar 19, 2019 at 02:13:21PM -0400, GaÃl PORTAY wrote:
> From: Enric Balletbo i Serra <enric.balletbo@xxxxxxxxxxxxx>
>
> Trusted Firmware-A (TF-A) for rk3399 implements a SiP call to get the
> on-die termination (ODT) and auto power down parameters from kernel,
> this patch adds the functionality to do this. Also, if DDR clock
> frequency is lower than the on-die termination (ODT) disable frequency
> this driver should disable the DDR ODT.
>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@xxxxxxxxxxxxx>
> Reviewed-by: Chanwoo Choi <cw00.choi@xxxxxxxxxxx>
> ---
>
> Changes in v2: None
>
> Changes in v1:
> - [RFC 3/10] Add an explanation for platform SIP calls.
> - [RFC 3/10] Change if statement for a switch.
> - [RFC 3/10] Rename ddr_flag to odt_enable to be more clear.
>
> drivers/devfreq/rk3399_dmc.c | 74 ++++++++++++++++++++++++++++-
> include/soc/rockchip/rockchip_sip.h | 1 +
> 2 files changed, 74 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
> ...
> static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
> @@ -80,6 +86,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
> struct dev_pm_opp *opp;
> unsigned long old_clk_rate = dmcfreq->rate;
> unsigned long target_volt, target_rate;
> + struct arm_smccc_res res;
> + bool odt_enable = false;
> int err;
>
> opp = devfreq_recommended_opp(dev, freq, flags);
> @@ -95,6 +103,19 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
>
> mutex_lock(&dmcfreq->lock);
>
> + if (target_rate >= dmcfreq->odt_dis_freq)
> + odt_enable = true;
> +
> + /*
> + * This makes a SMC call to the TF-A to set the DDR PD (power-down)
> + * timings and to enable or disable the ODT (on-die termination)
> + * resistors.
> + */
> + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
> + dmcfreq->odt_pd_arg1,
> + ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
> + odt_enable, 0, 0, 0, &res);
Is it necessary/desirable to make this call for every frequency
change? IIUC it should be only needed when odt_enable changes and the
driver could track the state. If the DDR frequency doesn't change too
often and the overhead of the call is small it shouldn't be really
important though.
> @@ -294,11 +315,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
> {
> struct arm_smccc_res res;
> struct device *dev = &pdev->dev;
> - struct device_node *np = pdev->dev.of_node;
> + struct device_node *np = pdev->dev.of_node, *node;
> struct rk3399_dmcfreq *data;
> int ret, index, size;
> uint32_t *timing;
> struct dev_pm_opp *opp;
> + u32 ddr_type;
> + u32 val;
>
> data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL);
> if (!data)
> @@ -334,6 +357,34 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
> return ret;
> }
>
> + /* Try to find the optional reference to the pmu syscon */
> + node = of_parse_phandle(np, "rockchip,pmu", 0);
> + if (node) {
The 'optional' part doesn't seem to be accurate: according to the
binding (https://lore.kernel.org/patchwork/patch/1052322/) the
property is required and the code below assumes that data->regmap_pmu
is set.
> + data->regmap_pmu = syscon_node_to_regmap(node);
> + if (IS_ERR(data->regmap_pmu))
> + return PTR_ERR(data->regmap_pmu);
> + }
> +
> + /* Get DDR type */
nit: the comment doesn't add much value, thanks to good variable
naming this is evident from the code.
> + regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
> + ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
> + RK3399_PMUGRF_DDRTYPE_MASK;
> +
> + /* Get the odt_dis_freq parameter in function of the DDR type */
nit: ditto
(if you prefer to keep these comments I'm not opposed to keeping them,
but I don't think they are needed)
Cheers
Matthias