* [PATCH v2 0/2] Enable usage of Marvell FW SIP services
@ 2021-01-14 10:26 kostap
2021-01-14 10:26 ` [PATCH v2 1/2] thermal: armada: ap806: use firmware SiP services for thermal operations kostap
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: kostap @ 2021-01-14 10:26 UTC (permalink / raw)
To: linux-clk
Cc: linux-pm, mturquette, sboyd, miquel.raynal, rui.zhang,
daniel.lezcano, amitk, mw, jaz, nadavh, bpeled, stefanc,
Konstantin Porotchkin
From: Konstantin Porotchkin <kostap@marvell.com>
These patches enable usage of Arm Trusted Firmware SIP services on
Marvell Armada plaforms for accessing system registers that are not
normally accessible from kernel or user space (EL1/EL0), like DFX
registers group.
v2:
* use separate legacy/smc regmap functions registered at ap-cpu
clock driver probe according to FW response
Grzegorz Jaszczyk (2):
thermal: armada: ap806: use firmware SiP services for thermal
operations
clk: mvebu: use firmware SiP service for accessing dfx register set
drivers/clk/mvebu/ap-cpu-clk.c | 168 ++++++++++++++++++--
drivers/thermal/armada_thermal.c | 125 ++++++++++++++-
include/soc/marvell/armada8k/fw.h | 22 +++
3 files changed, 296 insertions(+), 19 deletions(-)
create mode 100644 include/soc/marvell/armada8k/fw.h
--
2.17.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/2] thermal: armada: ap806: use firmware SiP services for thermal operations
2021-01-14 10:26 [PATCH v2 0/2] Enable usage of Marvell FW SIP services kostap
@ 2021-01-14 10:26 ` kostap
2021-01-14 13:17 ` kernel test robot
2021-01-14 10:26 ` [PATCH v2 2/2] clk: mvebu: use firmware SiP service for accessing dfx register set kostap
2021-02-11 2:36 ` [PATCH v2 0/2] Enable usage of Marvell FW SIP services Stephen Boyd
2 siblings, 1 reply; 8+ messages in thread
From: kostap @ 2021-01-14 10:26 UTC (permalink / raw)
To: linux-clk
Cc: linux-pm, mturquette, sboyd, miquel.raynal, rui.zhang,
daniel.lezcano, amitk, mw, jaz, nadavh, bpeled, stefanc,
Konstantin Porotchkin
From: Grzegorz Jaszczyk <jaz@semihalf.com>
This patch introduces support for ap806 thermal driver in case when SoC
DFX region is marked as secure by the firmware. In such case accessing
thermal registers, which are part of dfx register set, will not be
possible from non-secure world. Due to above the ARM Trusted Firmware
exposes thermal driver as a SiP service. This allows Linux thermal
driver to initialise and perform various operations on thermal sensor
with use of SMC calls.
If during ap806 thermal initialisation the SMC is unhandled (old fw
case), fallback to regmap handling.
Signed-off-by: Grzegorz Jaszczyk <jaz@semihalf.com>
Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
---
drivers/thermal/armada_thermal.c | 125 +++++++++++++++++++-
include/soc/marvell/armada8k/fw.h | 19 +++
2 files changed, 141 insertions(+), 3 deletions(-)
create mode 100644 include/soc/marvell/armada8k/fw.h
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index c2ebfb5be4b3..ec077e834c85 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2013 Marvell
*/
+#include <linux/arm-smccc.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -18,6 +19,8 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/interrupt.h>
+#include <linux/time.h>
+#include "soc/marvell/armada8k/fw.h"
#include "thermal_core.h"
@@ -62,6 +65,8 @@
#define STATUS_POLL_TIMEOUT_US 100000
#define OVERHEAT_INT_POLL_DELAY_MS 1000
+#define THERMAL_SUPPORTED_IN_FIRMWARE(priv) (priv->data->is_smc_supported)
+
struct armada_thermal_data;
/* Marvell EBU Thermal Sensor Dev Structure */
@@ -111,6 +116,12 @@ struct armada_thermal_data {
/* One sensor is in the thermal IC, the others are in the CPUs if any */
unsigned int cpu_nr;
+
+ /*
+ * Thermal sensor operations exposed as firmware SIP services and
+ * accessed via SMC
+ */
+ bool is_smc_supported;
};
struct armada_drvdata {
@@ -135,6 +146,18 @@ struct armada_thermal_sensor {
int id;
};
+static int thermal_smc(u32 addr, u32 *reg, u32 val1, u32 val2)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(MV_SIP_DFX, addr, val1, val2, 0, 0, 0, 0, &res);
+
+ if (res.a0 == 0 && reg != NULL)
+ *reg = res.a1;
+
+ return res.a0;
+}
+
static void armadaxp_init(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
@@ -206,6 +229,27 @@ static void armada375_init(struct platform_device *pdev,
static int armada_wait_sensor_validity(struct armada_thermal_priv *priv)
{
u32 reg;
+ int ret;
+ ktime_t timeout;
+
+ if (THERMAL_SUPPORTED_IN_FIRMWARE(priv)) {
+ timeout = ktime_add_us(ktime_get(), STATUS_POLL_TIMEOUT_US);
+ do {
+ ret = thermal_smc(MV_SIP_DFX_THERMAL_IS_VALID,
+ ®, 0, 0);
+ if (ret || reg)
+ break;
+
+ usleep_range((STATUS_POLL_PERIOD_US >> 2) + 1,
+ STATUS_POLL_PERIOD_US);
+
+ } while (ktime_before(ktime_get(), timeout));
+
+ if (ret == SMCCC_RET_SUCCESS)
+ return reg ? 0 : -ETIMEDOUT;
+
+ return ret;
+ }
return regmap_read_poll_timeout(priv->syscon,
priv->data->syscon_status_off, reg,
@@ -238,6 +282,22 @@ static void armada_ap806_init(struct platform_device *pdev,
{
struct armada_thermal_data *data = priv->data;
u32 reg;
+ int ret;
+
+ /*
+ * The ap806 thermal sensor registers are part of DFX which is secured
+ * by latest firmware, therefore accessing relevant registers from
+ * not-secure world will not be possible. In that case Arm Trusted
+ * Firmware exposes thermal operations as firmware run-time service. If
+ * SMC initialization succeeds, perform other thermal operations using
+ * SMC, otherwise (old fw case) fallback to regmap handling.
+ */
+ ret = thermal_smc(MV_SIP_DFX_THERMAL_INIT, 0x0, 0, 0);
+ if (ret == SMCCC_RET_SUCCESS) {
+ dev_info(&pdev->dev, "firmware support\n");
+ THERMAL_SUPPORTED_IN_FIRMWARE(priv) = true;
+ return;
+ }
regmap_read(priv->syscon, data->syscon_control0_off, ®);
reg &= ~CONTROL0_TSEN_RESET;
@@ -274,11 +334,17 @@ static void armada_cp110_init(struct platform_device *pdev,
static bool armada_is_valid(struct armada_thermal_priv *priv)
{
+ int ret;
u32 reg;
if (!priv->data->is_valid_bit)
return true;
+ if (THERMAL_SUPPORTED_IN_FIRMWARE(priv)) {
+ ret = thermal_smc(MV_SIP_DFX_THERMAL_IS_VALID, ®, 0, 0);
+ return ret ? false : reg;
+ }
+
regmap_read(priv->syscon, priv->data->syscon_status_off, ®);
return reg & priv->data->is_valid_bit;
@@ -324,6 +390,7 @@ static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
{
struct armada_thermal_data *data = priv->data;
u32 ctrl0;
+ int ret;
if (channel < 0 || channel > priv->data->cpu_nr)
return -EINVAL;
@@ -331,6 +398,16 @@ static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
if (priv->current_channel == channel)
return 0;
+ if (THERMAL_SUPPORTED_IN_FIRMWARE(priv)) {
+ ret = thermal_smc(MV_SIP_DFX_THERMAL_SEL_CHANNEL,
+ NULL, channel, 0);
+ if (ret)
+ return ret;
+
+ priv->current_channel = channel;
+ goto is_valid;
+ }
+
/* Stop the measurements */
regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);
ctrl0 &= ~CONTROL0_TSEN_START;
@@ -357,6 +434,7 @@ static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
ctrl0 |= CONTROL0_TSEN_START;
regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
+is_valid:
/*
* The IP has a latency of ~15ms, so after updating the selected source,
* we must absolutely wait for the sensor validity bit to ensure we read
@@ -376,6 +454,9 @@ static int armada_read_sensor(struct armada_thermal_priv *priv, int *temp)
u32 reg, div;
s64 sample, b, m;
+ if (THERMAL_SUPPORTED_IN_FIRMWARE(priv))
+ return thermal_smc(MV_SIP_DFX_THERMAL_READ, temp, 0, 0);
+
regmap_read(priv->syscon, priv->data->syscon_status_off, ®);
reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
if (priv->data->signed_sample)
@@ -559,7 +640,13 @@ static irqreturn_t armada_overheat_isr_thread(int irq, void *blob)
goto enable_irq;
} while (temperature >= low_threshold);
- regmap_read(priv->syscon, priv->data->dfx_irq_cause_off, &dummy);
+ if (THERMAL_SUPPORTED_IN_FIRMWARE(priv)) {
+ if (thermal_smc(MV_SIP_DFX_THERMAL_IRQ, 0, 0, 0))
+ return IRQ_NONE;
+ } else {
+ regmap_read(priv->syscon, priv->data->dfx_irq_cause_off,
+ &dummy);
+ }
/* Notify the thermal core that the temperature is acceptable again */
thermal_zone_device_update(priv->overheat_sensor,
@@ -772,6 +859,27 @@ static void armada_set_sane_name(struct platform_device *pdev,
} while (insane_char);
}
+/*
+ * Let the firmware configure the thermal overheat threshold, hysteresis and
+ * enable overheat interrupt
+ */
+static int armada_fw_overheat_settings(struct armada_thermal_priv *priv,
+ int thresh_mc, int hyst_mc)
+{
+ int ret;
+
+ ret = thermal_smc(MV_SIP_DFX_THERMAL_THRESH, NULL, thresh_mc, hyst_mc);
+ if (ret)
+ return ret;
+
+ if (thresh_mc >= 0)
+ priv->current_threshold = thresh_mc;
+ if (hyst_mc >= 0)
+ priv->current_hysteresis = hyst_mc;
+
+ return 0;
+}
+
/*
* The IP can manage to trigger interrupts on overheat situation from all the
* sensors. However, the interrupt source changes along with the last selected
@@ -803,11 +911,22 @@ static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
if (ret)
return ret;
+ priv->overheat_sensor = tz;
+ priv->interrupt_source = sensor_id;
+
+ if (THERMAL_SUPPORTED_IN_FIRMWARE(priv)) {
+ /*
+ * When thermal supported in firmware the configuring overheat
+ * threshold and enabling overheat interrupt is done in one
+ * step.
+ */
+ return armada_fw_overheat_settings(priv, trips[i].temperature,
+ trips[i].hysteresis);
+ }
+
armada_set_overheat_thresholds(priv,
trips[i].temperature,
trips[i].hysteresis);
- priv->overheat_sensor = tz;
- priv->interrupt_source = sensor_id;
armada_enable_overheat_interrupt(priv);
diff --git a/include/soc/marvell/armada8k/fw.h b/include/soc/marvell/armada8k/fw.h
new file mode 100644
index 000000000000..2a80f26cbf6f
--- /dev/null
+++ b/include/soc/marvell/armada8k/fw.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2019 Marvell International Ltd.
+ */
+
+#ifndef _SOC_MARVELL_ARMADA8K_FW_H
+#define _SOC_MARVELL_ARMADA8K_FW_H
+
+/* FW related definitions */
+#define MV_SIP_DFX 0x82000014
+
+#define MV_SIP_DFX_THERMAL_INIT 1
+#define MV_SIP_DFX_THERMAL_READ 2
+#define MV_SIP_DFX_THERMAL_IS_VALID 3
+#define MV_SIP_DFX_THERMAL_IRQ 4
+#define MV_SIP_DFX_THERMAL_THRESH 5
+#define MV_SIP_DFX_THERMAL_SEL_CHANNEL 6
+
+#endif /* _SOC_MARVELL_ARMADA8K_FW_H */
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] clk: mvebu: use firmware SiP service for accessing dfx register set
2021-01-14 10:26 [PATCH v2 0/2] Enable usage of Marvell FW SIP services kostap
2021-01-14 10:26 ` [PATCH v2 1/2] thermal: armada: ap806: use firmware SiP services for thermal operations kostap
@ 2021-01-14 10:26 ` kostap
2021-01-14 14:27 ` kernel test robot
2021-01-14 19:00 ` kernel test robot
2021-02-11 2:36 ` [PATCH v2 0/2] Enable usage of Marvell FW SIP services Stephen Boyd
2 siblings, 2 replies; 8+ messages in thread
From: kostap @ 2021-01-14 10:26 UTC (permalink / raw)
To: linux-clk
Cc: linux-pm, mturquette, sboyd, miquel.raynal, rui.zhang,
daniel.lezcano, amitk, mw, jaz, nadavh, bpeled, stefanc,
Konstantin Porotchkin
From: Grzegorz Jaszczyk <jaz@semihalf.com>
This patch introduces support for cpu clk driver in case when SoC
DFX region is marked as secure by the firmware. In such case accessing
cpu clk registers, which are part of dfx register set, will not be
possible from non-secure world.
The ARM Trusted Firmware exposes SiP service which allows to read/write
some dfx registers (white-listed in firmware). This allows Linux cpu clk
driver to set_rate and recalc_rate with use of SMC calls.
If during cpu clk operation the SMC is unhandled (old fw case), fallback
to regmap handling.
Signed-off-by: Grzegorz Jaszczyk <jaz@semihalf.com>
Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
---
drivers/clk/mvebu/ap-cpu-clk.c | 168 ++++++++++++++++++--
include/soc/marvell/armada8k/fw.h | 3 +
2 files changed, 155 insertions(+), 16 deletions(-)
diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c
index b4259b60dcfd..b63bd5da4752 100644
--- a/drivers/clk/mvebu/ap-cpu-clk.c
+++ b/drivers/clk/mvebu/ap-cpu-clk.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) "ap-cpu-clk: " fmt
+#include <linux/arm-smccc.h>
#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/mfd/syscon.h>
@@ -19,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include "armada_ap_cp_helper.h"
+#include "soc/marvell/armada8k/fw.h"
#define AP806_CPU_CLUSTER0 0
#define AP806_CPU_CLUSTER1 1
@@ -139,8 +141,118 @@ struct ap_cpu_clk {
struct clk_hw hw;
struct regmap *pll_cr_base;
const struct cpu_dfs_regs *pll_regs;
+ phys_addr_t phys;
+ int (*regmap_read)(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int *val);
+ int (*regmap_write)(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int val);
+ int (*regmap_update_bits)(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int mask, unsigned int val);
+ int (*regmap_read_poll_timeout)(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int stable_bit);
+
};
+static int dfx_sread_smc(unsigned long addr, unsigned int *reg)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(MV_SIP_DFX, MV_SIP_DFX_SREAD, addr, 0, 0, 0, 0, 0, &res);
+
+ if (res.a0 == 0 && reg != NULL)
+ *reg = res.a1;
+
+ return res.a0;
+}
+
+static int dfx_swrite_smc(unsigned long addr, unsigned long val)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(MV_SIP_DFX, MV_SIP_DFX_SWRITE, addr, val,
+ 0, 0, 0, 0, &res);
+
+ return res.a0;
+}
+
+static int smc_regmap_read(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int *val)
+{
+ return dfx_sread_smc(clk->phys + reg, val);
+}
+
+static int legacy_regmap_read(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int *val)
+{
+ return regmap_read(clk->pll_cr_base, reg, val);
+}
+
+static int smc_regmap_write(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int val)
+{
+ return dfx_swrite_smc(clk->phys + reg, val);
+}
+
+static int legacy_regmap_write(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int val)
+{
+ return regmap_write(clk->pll_cr_base, reg, val);
+}
+
+static int smc_regmap_update_bits(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int mask, unsigned int val)
+{
+ int ret;
+ unsigned int tmp;
+
+ ret = dfx_sread_smc(clk->phys + reg, &tmp);
+ if (ret != SMCCC_RET_SUCCESS)
+ return ret;
+
+ tmp &= ~mask;
+ tmp |= val & mask;
+
+ return dfx_swrite_smc(clk->phys + reg, tmp);
+}
+
+static int legacy_regmap_update_bits(struct ap_cpu_clk *clk, unsigned int reg,
+ unsigned int mask, unsigned int val)
+{
+ return regmap_update_bits(clk->pll_cr_base, reg, mask, val);
+}
+
+static int smc_regmap_read_poll_timeout(struct ap_cpu_clk *clk,
+ unsigned int reg,
+ unsigned int stable_bit)
+{
+ int ret;
+ u32 val;
+ ktime_t timeout;
+
+ timeout = ktime_add_us(ktime_get(), STATUS_POLL_TIMEOUT_US);
+ do {
+ ret = dfx_sread_smc(clk->phys + reg, &val);
+ if (ret || (val & stable_bit))
+ break;
+
+ usleep_range((STATUS_POLL_PERIOD_US >> 2) + 1,
+ STATUS_POLL_PERIOD_US);
+
+ } while (ktime_before(ktime_get(), timeout));
+
+ if (ret == SMCCC_RET_SUCCESS)
+ return (val & stable_bit) ? 0 : -ETIMEDOUT;
+}
+
+static int legacy_regmap_read_poll_timeout(struct ap_cpu_clk *clk,
+ unsigned int reg,
+ unsigned int stable_bit)
+{
+ return regmap_read_poll_timeout(clk->pll_cr_base,
+ reg, val,
+ val & stable_bit, STATUS_POLL_PERIOD_US,
+ STATUS_POLL_TIMEOUT_US);
+}
static unsigned long ap_cpu_clk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
@@ -150,7 +262,7 @@ static unsigned long ap_cpu_clk_recalc_rate(struct clk_hw *hw,
cpu_clkdiv_reg = clk->pll_regs->divider_reg +
(clk->cluster * clk->pll_regs->cluster_offset);
- regmap_read(clk->pll_cr_base, cpu_clkdiv_reg, &cpu_clkdiv_ratio);
+ clk->regmap_read(clk, cpu_clkdiv_reg, &cpu_clkdiv_ratio);
cpu_clkdiv_ratio &= clk->pll_regs->divider_mask;
cpu_clkdiv_ratio >>= clk->pll_regs->divider_offset;
@@ -171,7 +283,7 @@ static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
cpu_ratio_reg = clk->pll_regs->ratio_reg +
(clk->cluster * clk->pll_regs->cluster_offset);
- regmap_read(clk->pll_cr_base, cpu_clkdiv_reg, ®);
+ clk->regmap_read(clk, cpu_clkdiv_reg, ®);
reg &= ~(clk->pll_regs->divider_mask);
reg |= (divider << clk->pll_regs->divider_offset);
@@ -184,29 +296,26 @@ static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
reg |= ((divider * clk->pll_regs->divider_ratio) <<
AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET);
}
- regmap_write(clk->pll_cr_base, cpu_clkdiv_reg, reg);
+ clk->regmap_write(clk, cpu_clkdiv_reg, reg);
+ clk->regmap_update_bits(clk, cpu_force_reg, clk->pll_regs->force_mask,
+ clk->pll_regs->force_mask);
- regmap_update_bits(clk->pll_cr_base, cpu_force_reg,
- clk->pll_regs->force_mask,
- clk->pll_regs->force_mask);
-
- regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg,
- BIT(clk->pll_regs->ratio_offset),
- BIT(clk->pll_regs->ratio_offset));
+ clk->regmap_update_bits(clk, cpu_ratio_reg,
+ BIT(clk->pll_regs->ratio_offset),
+ BIT(clk->pll_regs->ratio_offset));
stable_bit = BIT(clk->pll_regs->ratio_state_offset +
clk->cluster *
clk->pll_regs->ratio_state_cluster_offset);
- ret = regmap_read_poll_timeout(clk->pll_cr_base,
- clk->pll_regs->ratio_state_reg, reg,
- reg & stable_bit, STATUS_POLL_PERIOD_US,
- STATUS_POLL_TIMEOUT_US);
+ ret = clk->regmap_read_poll_timeout(clk,
+ clk->pll_regs->ratio_state_reg,
+ stable_bit);
if (ret)
return ret;
- regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg,
- BIT(clk->pll_regs->ratio_offset), 0);
+ clk->regmap_update_bits(clk, cpu_ratio_reg,
+ BIT(clk->pll_regs->ratio_offset), 0);
return 0;
}
@@ -235,6 +344,11 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
struct clk_hw_onecell_data *ap_cpu_data;
struct ap_cpu_clk *ap_cpu_clk;
struct regmap *regmap;
+ struct resource res;
+
+ ret = of_address_to_resource(np->parent, 0, &res);
+ if (ret)
+ return ret;
regmap = syscon_node_to_regmap(np->parent);
if (IS_ERR(regmap)) {
@@ -286,6 +400,7 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
const char *parent_name;
struct clk *parent;
int cpu, err;
+ unsigned int tmp;
err = of_property_read_u32(dn, "reg", &cpu);
if (WARN_ON(err))
@@ -313,6 +428,27 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
ap_cpu_clk[cluster_index].dev = dev;
ap_cpu_clk[cluster_index].pll_regs = of_device_get_match_data(&pdev->dev);
+ /* Get the physical address to hand to the firmware. */
+ ap_cpu_clk[cluster_index].phys = res.start;
+
+ /* Try to read a register using SMC and setup DFX access APIs accordingly */
+ ret = smc_regmap_read(&ap_cpu_clk[cluster_index],
+ ap_cpu_clk[cluster_index].pll_regs->divider_reg,
+ &tmp);
+ if (ret == SMCCC_RET_SUCCESS) {
+ ap_cpu_clk[cluster_index].regmap_read = smc_regmap_read;
+ ap_cpu_clk[cluster_index].regmap_wriite = smc_regmap_write;
+ ap_cpu_clk[cluster_index].regmap_update_bits = smc_regmap_update_bits;
+ ap_cpu_clk[cluster_index].regmap_read_poll_timeout =
+ smc_regmap_read_poll_timeout;
+ } else {
+ ap_cpu_clk[cluster_index].regmap_read = legacy_regmap_read;
+ ap_cpu_clk[cluster_index].regmap_wriite = legacy_regmap_write;
+ ap_cpu_clk[cluster_index].regmap_update_bits = legacy_regmap_update_bits;
+ ap_cpu_clk[cluster_index].regmap_read_poll_timeout =
+ legacy_regmap_read_poll_timeout;
+ }
+
init.name = ap_cpu_clk[cluster_index].clk_name;
init.ops = &ap_cpu_clk_ops;
init.num_parents = 1;
diff --git a/include/soc/marvell/armada8k/fw.h b/include/soc/marvell/armada8k/fw.h
index 2a80f26cbf6f..e646212a3796 100644
--- a/include/soc/marvell/armada8k/fw.h
+++ b/include/soc/marvell/armada8k/fw.h
@@ -16,4 +16,7 @@
#define MV_SIP_DFX_THERMAL_THRESH 5
#define MV_SIP_DFX_THERMAL_SEL_CHANNEL 6
+#define MV_SIP_DFX_SREAD 20
+#define MV_SIP_DFX_SWRITE 21
+
#endif /* _SOC_MARVELL_ARMADA8K_FW_H */
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] thermal: armada: ap806: use firmware SiP services for thermal operations
2021-01-14 10:26 ` [PATCH v2 1/2] thermal: armada: ap806: use firmware SiP services for thermal operations kostap
@ 2021-01-14 13:17 ` kernel test robot
0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-01-14 13:17 UTC (permalink / raw)
To: kostap, linux-clk
Cc: kbuild-all, linux-pm, mturquette, sboyd, miquel.raynal,
rui.zhang, daniel.lezcano, amitk, mw, jaz
[-- Attachment #1: Type: text/plain, Size: 1880 bytes --]
Hi,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on clk/clk-next]
[also build test ERROR on linus/master thermal/next soc-thermal/next v5.11-rc3 next-20210114]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/kostap-marvell-com/Enable-usage-of-Marvell-FW-SIP-services/20210114-183207
base: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
config: openrisc-randconfig-r024-20210114 (attached as .config)
compiler: or1k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/0817606b4d4dda1aeb2b1acccdc15b15a6751746
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review kostap-marvell-com/Enable-usage-of-Marvell-FW-SIP-services/20210114-183207
git checkout 0817606b4d4dda1aeb2b1acccdc15b15a6751746
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=openrisc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
or1k-linux-ld: drivers/thermal/armada_thermal.o: in function `thermal_smc':
>> armada_thermal.c:(.text+0x23c): undefined reference to `__arm_smccc_smc'
armada_thermal.c:(.text+0x23c): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `__arm_smccc_smc'
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 35686 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] thermal: armada: ap806: use firmware SiP services for thermal operations
@ 2021-01-14 13:17 ` kernel test robot
0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-01-14 13:17 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 1918 bytes --]
Hi,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on clk/clk-next]
[also build test ERROR on linus/master thermal/next soc-thermal/next v5.11-rc3 next-20210114]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/kostap-marvell-com/Enable-usage-of-Marvell-FW-SIP-services/20210114-183207
base: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
config: openrisc-randconfig-r024-20210114 (attached as .config)
compiler: or1k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/0817606b4d4dda1aeb2b1acccdc15b15a6751746
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review kostap-marvell-com/Enable-usage-of-Marvell-FW-SIP-services/20210114-183207
git checkout 0817606b4d4dda1aeb2b1acccdc15b15a6751746
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=openrisc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
or1k-linux-ld: drivers/thermal/armada_thermal.o: in function `thermal_smc':
>> armada_thermal.c:(.text+0x23c): undefined reference to `__arm_smccc_smc'
armada_thermal.c:(.text+0x23c): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `__arm_smccc_smc'
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 35686 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] clk: mvebu: use firmware SiP service for accessing dfx register set
2021-01-14 10:26 ` [PATCH v2 2/2] clk: mvebu: use firmware SiP service for accessing dfx register set kostap
@ 2021-01-14 14:27 ` kernel test robot
2021-01-14 19:00 ` kernel test robot
1 sibling, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-01-14 14:27 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 7054 bytes --]
Hi,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on clk/clk-next]
[also build test WARNING on linus/master v5.11-rc3 next-20210114]
[cannot apply to thermal/next soc-thermal/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/kostap-marvell-com/Enable-usage-of-Marvell-FW-SIP-services/20210114-183207
base: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/8dc917b26b54d723831b58c1f166a15a1b7d28e2
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review kostap-marvell-com/Enable-usage-of-Marvell-FW-SIP-services/20210114-183207
git checkout 8dc917b26b54d723831b58c1f166a15a1b7d28e2
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
In file included from include/linux/regmap.h:20,
from drivers/clk/mvebu/ap-cpu-clk.c:21:
drivers/clk/mvebu/ap-cpu-clk.c: In function 'legacy_regmap_read_poll_timeout':
drivers/clk/mvebu/ap-cpu-clk.c:252:11: error: 'val' undeclared (first use in this function)
252 | reg, val,
| ^~~
include/linux/iopoll.h:46:14: note: in definition of macro 'read_poll_timeout'
46 | (val) = op(args); \
| ^~~~
drivers/clk/mvebu/ap-cpu-clk.c:251:9: note: in expansion of macro 'regmap_read_poll_timeout'
251 | return regmap_read_poll_timeout(clk->pll_cr_base,
| ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/clk/mvebu/ap-cpu-clk.c:252:11: note: each undeclared identifier is reported only once for each function it appears in
252 | reg, val,
| ^~~
include/linux/iopoll.h:46:14: note: in definition of macro 'read_poll_timeout'
46 | (val) = op(args); \
| ^~~~
drivers/clk/mvebu/ap-cpu-clk.c:251:9: note: in expansion of macro 'regmap_read_poll_timeout'
251 | return regmap_read_poll_timeout(clk->pll_cr_base,
| ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/clk/mvebu/ap-cpu-clk.c: In function 'ap_cpu_clk_set_rate':
drivers/clk/mvebu/ap-cpu-clk.c:313:20: error: macro "regmap_read_poll_timeout" requires 6 arguments, but only 3 given
313 | stable_bit);
| ^
In file included from drivers/clk/mvebu/ap-cpu-clk.c:21:
include/linux/regmap.h:103: note: macro "regmap_read_poll_timeout" defined here
103 | #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \
|
>> drivers/clk/mvebu/ap-cpu-clk.c:311:6: warning: assignment to 'int' from 'int (*)(struct ap_cpu_clk *, unsigned int, unsigned int)' makes integer from pointer without a cast [-Wint-conversion]
311 | ret = clk->regmap_read_poll_timeout(clk,
| ^
>> drivers/clk/mvebu/ap-cpu-clk.c:277:61: warning: variable 'stable_bit' set but not used [-Wunused-but-set-variable]
277 | unsigned int cpu_clkdiv_reg, cpu_force_reg, cpu_ratio_reg, stable_bit;
| ^~~~~~~~~~
drivers/clk/mvebu/ap-cpu-clk.c: In function 'ap_cpu_clock_probe':
drivers/clk/mvebu/ap-cpu-clk.c:440:30: error: 'struct ap_cpu_clk' has no member named 'regmap_wriite'; did you mean 'regmap_write'?
440 | ap_cpu_clk[cluster_index].regmap_wriite = smc_regmap_write;
| ^~~~~~~~~~~~~
| regmap_write
drivers/clk/mvebu/ap-cpu-clk.c:446:30: error: 'struct ap_cpu_clk' has no member named 'regmap_wriite'; did you mean 'regmap_write'?
446 | ap_cpu_clk[cluster_index].regmap_wriite = legacy_regmap_write;
| ^~~~~~~~~~~~~
| regmap_write
drivers/clk/mvebu/ap-cpu-clk.c: In function 'smc_regmap_read_poll_timeout':
drivers/clk/mvebu/ap-cpu-clk.c:245:1: error: control reaches end of non-void function [-Werror=return-type]
245 | }
| ^
cc1: some warnings being treated as errors
vim +311 drivers/clk/mvebu/ap-cpu-clk.c
271
272 static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
273 unsigned long parent_rate)
274 {
275 struct ap_cpu_clk *clk = to_ap_cpu_clk(hw);
276 int ret, reg, divider = parent_rate / rate;
> 277 unsigned int cpu_clkdiv_reg, cpu_force_reg, cpu_ratio_reg, stable_bit;
278
279 cpu_clkdiv_reg = clk->pll_regs->divider_reg +
280 (clk->cluster * clk->pll_regs->cluster_offset);
281 cpu_force_reg = clk->pll_regs->force_reg +
282 (clk->cluster * clk->pll_regs->cluster_offset);
283 cpu_ratio_reg = clk->pll_regs->ratio_reg +
284 (clk->cluster * clk->pll_regs->cluster_offset);
285
286 clk->regmap_read(clk, cpu_clkdiv_reg, ®);
287 reg &= ~(clk->pll_regs->divider_mask);
288 reg |= (divider << clk->pll_regs->divider_offset);
289
290 /*
291 * AP807 CPU divider has two channels with ratio 1:3 and divider_ratio
292 * is 1. Otherwise, in the case of the AP806, divider_ratio is 0.
293 */
294 if (clk->pll_regs->divider_ratio) {
295 reg &= ~(AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_MASK);
296 reg |= ((divider * clk->pll_regs->divider_ratio) <<
297 AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET);
298 }
299 clk->regmap_write(clk, cpu_clkdiv_reg, reg);
300
301 clk->regmap_update_bits(clk, cpu_force_reg, clk->pll_regs->force_mask,
302 clk->pll_regs->force_mask);
303
304 clk->regmap_update_bits(clk, cpu_ratio_reg,
305 BIT(clk->pll_regs->ratio_offset),
306 BIT(clk->pll_regs->ratio_offset));
307
308 stable_bit = BIT(clk->pll_regs->ratio_state_offset +
309 clk->cluster *
310 clk->pll_regs->ratio_state_cluster_offset);
> 311 ret = clk->regmap_read_poll_timeout(clk,
312 clk->pll_regs->ratio_state_reg,
313 stable_bit);
314 if (ret)
315 return ret;
316
317 clk->regmap_update_bits(clk, cpu_ratio_reg,
318 BIT(clk->pll_regs->ratio_offset), 0);
319
320 return 0;
321 }
322
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 76465 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] clk: mvebu: use firmware SiP service for accessing dfx register set
2021-01-14 10:26 ` [PATCH v2 2/2] clk: mvebu: use firmware SiP service for accessing dfx register set kostap
2021-01-14 14:27 ` kernel test robot
@ 2021-01-14 19:00 ` kernel test robot
1 sibling, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-01-14 19:00 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 13633 bytes --]
Hi,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on clk/clk-next]
[also build test ERROR on linus/master v5.11-rc3 next-20210114]
[cannot apply to thermal/next soc-thermal/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/kostap-marvell-com/Enable-usage-of-Marvell-FW-SIP-services/20210114-183207
base: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/8dc917b26b54d723831b58c1f166a15a1b7d28e2
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review kostap-marvell-com/Enable-usage-of-Marvell-FW-SIP-services/20210114-183207
git checkout 8dc917b26b54d723831b58c1f166a15a1b7d28e2
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
In file included from include/linux/regmap.h:20,
from drivers/clk/mvebu/ap-cpu-clk.c:21:
drivers/clk/mvebu/ap-cpu-clk.c: In function 'legacy_regmap_read_poll_timeout':
>> drivers/clk/mvebu/ap-cpu-clk.c:252:11: error: 'val' undeclared (first use in this function)
252 | reg, val,
| ^~~
include/linux/iopoll.h:46:14: note: in definition of macro 'read_poll_timeout'
46 | (val) = op(args); \
| ^~~~
drivers/clk/mvebu/ap-cpu-clk.c:251:9: note: in expansion of macro 'regmap_read_poll_timeout'
251 | return regmap_read_poll_timeout(clk->pll_cr_base,
| ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/clk/mvebu/ap-cpu-clk.c:252:11: note: each undeclared identifier is reported only once for each function it appears in
252 | reg, val,
| ^~~
include/linux/iopoll.h:46:14: note: in definition of macro 'read_poll_timeout'
46 | (val) = op(args); \
| ^~~~
drivers/clk/mvebu/ap-cpu-clk.c:251:9: note: in expansion of macro 'regmap_read_poll_timeout'
251 | return regmap_read_poll_timeout(clk->pll_cr_base,
| ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/clk/mvebu/ap-cpu-clk.c: In function 'ap_cpu_clk_set_rate':
>> drivers/clk/mvebu/ap-cpu-clk.c:313:20: error: macro "regmap_read_poll_timeout" requires 6 arguments, but only 3 given
313 | stable_bit);
| ^
In file included from drivers/clk/mvebu/ap-cpu-clk.c:21:
include/linux/regmap.h:103: note: macro "regmap_read_poll_timeout" defined here
103 | #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \
|
drivers/clk/mvebu/ap-cpu-clk.c:311:6: warning: assignment to 'int' from 'int (*)(struct ap_cpu_clk *, unsigned int, unsigned int)' makes integer from pointer without a cast [-Wint-conversion]
311 | ret = clk->regmap_read_poll_timeout(clk,
| ^
drivers/clk/mvebu/ap-cpu-clk.c:277:61: warning: variable 'stable_bit' set but not used [-Wunused-but-set-variable]
277 | unsigned int cpu_clkdiv_reg, cpu_force_reg, cpu_ratio_reg, stable_bit;
| ^~~~~~~~~~
drivers/clk/mvebu/ap-cpu-clk.c: In function 'ap_cpu_clock_probe':
>> drivers/clk/mvebu/ap-cpu-clk.c:440:30: error: 'struct ap_cpu_clk' has no member named 'regmap_wriite'; did you mean 'regmap_write'?
440 | ap_cpu_clk[cluster_index].regmap_wriite = smc_regmap_write;
| ^~~~~~~~~~~~~
| regmap_write
drivers/clk/mvebu/ap-cpu-clk.c:446:30: error: 'struct ap_cpu_clk' has no member named 'regmap_wriite'; did you mean 'regmap_write'?
446 | ap_cpu_clk[cluster_index].regmap_wriite = legacy_regmap_write;
| ^~~~~~~~~~~~~
| regmap_write
drivers/clk/mvebu/ap-cpu-clk.c: In function 'smc_regmap_read_poll_timeout':
drivers/clk/mvebu/ap-cpu-clk.c:245:1: error: control reaches end of non-void function [-Werror=return-type]
245 | }
| ^
cc1: some warnings being treated as errors
vim +/val +252 drivers/clk/mvebu/ap-cpu-clk.c
246
247 static int legacy_regmap_read_poll_timeout(struct ap_cpu_clk *clk,
248 unsigned int reg,
249 unsigned int stable_bit)
250 {
> 251 return regmap_read_poll_timeout(clk->pll_cr_base,
> 252 reg, val,
253 val & stable_bit, STATUS_POLL_PERIOD_US,
254 STATUS_POLL_TIMEOUT_US);
255 }
256 static unsigned long ap_cpu_clk_recalc_rate(struct clk_hw *hw,
257 unsigned long parent_rate)
258 {
259 struct ap_cpu_clk *clk = to_ap_cpu_clk(hw);
260 unsigned int cpu_clkdiv_reg;
261 int cpu_clkdiv_ratio;
262
263 cpu_clkdiv_reg = clk->pll_regs->divider_reg +
264 (clk->cluster * clk->pll_regs->cluster_offset);
265 clk->regmap_read(clk, cpu_clkdiv_reg, &cpu_clkdiv_ratio);
266 cpu_clkdiv_ratio &= clk->pll_regs->divider_mask;
267 cpu_clkdiv_ratio >>= clk->pll_regs->divider_offset;
268
269 return parent_rate / cpu_clkdiv_ratio;
270 }
271
272 static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
273 unsigned long parent_rate)
274 {
275 struct ap_cpu_clk *clk = to_ap_cpu_clk(hw);
276 int ret, reg, divider = parent_rate / rate;
277 unsigned int cpu_clkdiv_reg, cpu_force_reg, cpu_ratio_reg, stable_bit;
278
279 cpu_clkdiv_reg = clk->pll_regs->divider_reg +
280 (clk->cluster * clk->pll_regs->cluster_offset);
281 cpu_force_reg = clk->pll_regs->force_reg +
282 (clk->cluster * clk->pll_regs->cluster_offset);
283 cpu_ratio_reg = clk->pll_regs->ratio_reg +
284 (clk->cluster * clk->pll_regs->cluster_offset);
285
286 clk->regmap_read(clk, cpu_clkdiv_reg, ®);
287 reg &= ~(clk->pll_regs->divider_mask);
288 reg |= (divider << clk->pll_regs->divider_offset);
289
290 /*
291 * AP807 CPU divider has two channels with ratio 1:3 and divider_ratio
292 * is 1. Otherwise, in the case of the AP806, divider_ratio is 0.
293 */
294 if (clk->pll_regs->divider_ratio) {
295 reg &= ~(AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_MASK);
296 reg |= ((divider * clk->pll_regs->divider_ratio) <<
297 AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET);
298 }
299 clk->regmap_write(clk, cpu_clkdiv_reg, reg);
300
301 clk->regmap_update_bits(clk, cpu_force_reg, clk->pll_regs->force_mask,
302 clk->pll_regs->force_mask);
303
304 clk->regmap_update_bits(clk, cpu_ratio_reg,
305 BIT(clk->pll_regs->ratio_offset),
306 BIT(clk->pll_regs->ratio_offset));
307
308 stable_bit = BIT(clk->pll_regs->ratio_state_offset +
309 clk->cluster *
310 clk->pll_regs->ratio_state_cluster_offset);
> 311 ret = clk->regmap_read_poll_timeout(clk,
312 clk->pll_regs->ratio_state_reg,
> 313 stable_bit);
314 if (ret)
315 return ret;
316
317 clk->regmap_update_bits(clk, cpu_ratio_reg,
318 BIT(clk->pll_regs->ratio_offset), 0);
319
320 return 0;
321 }
322
323 static long ap_cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate,
324 unsigned long *parent_rate)
325 {
326 int divider = *parent_rate / rate;
327
328 divider = min(divider, APN806_MAX_DIVIDER);
329
330 return *parent_rate / divider;
331 }
332
333 static const struct clk_ops ap_cpu_clk_ops = {
334 .recalc_rate = ap_cpu_clk_recalc_rate,
335 .round_rate = ap_cpu_clk_round_rate,
336 .set_rate = ap_cpu_clk_set_rate,
337 };
338
339 static int ap_cpu_clock_probe(struct platform_device *pdev)
340 {
341 int ret, nclusters = 0, cluster_index = 0;
342 struct device *dev = &pdev->dev;
343 struct device_node *dn, *np = dev->of_node;
344 struct clk_hw_onecell_data *ap_cpu_data;
345 struct ap_cpu_clk *ap_cpu_clk;
346 struct regmap *regmap;
347 struct resource res;
348
349 ret = of_address_to_resource(np->parent, 0, &res);
350 if (ret)
351 return ret;
352
353 regmap = syscon_node_to_regmap(np->parent);
354 if (IS_ERR(regmap)) {
355 pr_err("cannot get pll_cr_base regmap\n");
356 return PTR_ERR(regmap);
357 }
358
359 /*
360 * AP806 has 4 cpus and DFS for AP806 is controlled per
361 * cluster (2 CPUs per cluster), cpu0 and cpu1 are fixed to
362 * cluster0 while cpu2 and cpu3 are fixed to cluster1 whether
363 * they are enabled or not. Since cpu0 is the boot cpu, then
364 * cluster0 must exist. If cpu2 or cpu3 is enabled, cluster1
365 * will exist and the cluster number is 2; otherwise the
366 * cluster number is 1.
367 */
368 nclusters = 1;
369 for_each_of_cpu_node(dn) {
370 int cpu, err;
371
372 err = of_property_read_u32(dn, "reg", &cpu);
373 if (WARN_ON(err))
374 return err;
375
376 /* If cpu2 or cpu3 is enabled */
377 if (cpu & APN806_CLUSTER_NUM_MASK) {
378 nclusters = 2;
379 break;
380 }
381 }
382 /*
383 * DFS for AP806 is controlled per cluster (2 CPUs per cluster),
384 * so allocate structs per cluster
385 */
386 ap_cpu_clk = devm_kcalloc(dev, nclusters, sizeof(*ap_cpu_clk),
387 GFP_KERNEL);
388 if (!ap_cpu_clk)
389 return -ENOMEM;
390
391 ap_cpu_data = devm_kzalloc(dev, struct_size(ap_cpu_data, hws,
392 nclusters),
393 GFP_KERNEL);
394 if (!ap_cpu_data)
395 return -ENOMEM;
396
397 for_each_of_cpu_node(dn) {
398 char *clk_name = "cpu-cluster-0";
399 struct clk_init_data init;
400 const char *parent_name;
401 struct clk *parent;
402 int cpu, err;
403 unsigned int tmp;
404
405 err = of_property_read_u32(dn, "reg", &cpu);
406 if (WARN_ON(err))
407 return err;
408
409 cluster_index = cpu & APN806_CLUSTER_NUM_MASK;
410 cluster_index >>= APN806_CLUSTER_NUM_OFFSET;
411
412 /* Initialize once for one cluster */
413 if (ap_cpu_data->hws[cluster_index])
414 continue;
415
416 parent = of_clk_get(np, cluster_index);
417 if (IS_ERR(parent)) {
418 dev_err(dev, "Could not get the clock parent\n");
419 return -EINVAL;
420 }
421 parent_name = __clk_get_name(parent);
422 clk_name[12] += cluster_index;
423 ap_cpu_clk[cluster_index].clk_name =
424 ap_cp_unique_name(dev, np->parent, clk_name);
425 ap_cpu_clk[cluster_index].cluster = cluster_index;
426 ap_cpu_clk[cluster_index].pll_cr_base = regmap;
427 ap_cpu_clk[cluster_index].hw.init = &init;
428 ap_cpu_clk[cluster_index].dev = dev;
429 ap_cpu_clk[cluster_index].pll_regs = of_device_get_match_data(&pdev->dev);
430
431 /* Get the physical address to hand to the firmware. */
432 ap_cpu_clk[cluster_index].phys = res.start;
433
434 /* Try to read a register using SMC and setup DFX access APIs accordingly */
435 ret = smc_regmap_read(&ap_cpu_clk[cluster_index],
436 ap_cpu_clk[cluster_index].pll_regs->divider_reg,
437 &tmp);
438 if (ret == SMCCC_RET_SUCCESS) {
439 ap_cpu_clk[cluster_index].regmap_read = smc_regmap_read;
> 440 ap_cpu_clk[cluster_index].regmap_wriite = smc_regmap_write;
441 ap_cpu_clk[cluster_index].regmap_update_bits = smc_regmap_update_bits;
442 ap_cpu_clk[cluster_index].regmap_read_poll_timeout =
443 smc_regmap_read_poll_timeout;
444 } else {
445 ap_cpu_clk[cluster_index].regmap_read = legacy_regmap_read;
446 ap_cpu_clk[cluster_index].regmap_wriite = legacy_regmap_write;
447 ap_cpu_clk[cluster_index].regmap_update_bits = legacy_regmap_update_bits;
448 ap_cpu_clk[cluster_index].regmap_read_poll_timeout =
449 legacy_regmap_read_poll_timeout;
450 }
451
452 init.name = ap_cpu_clk[cluster_index].clk_name;
453 init.ops = &ap_cpu_clk_ops;
454 init.num_parents = 1;
455 init.parent_names = &parent_name;
456
457 ret = devm_clk_hw_register(dev, &ap_cpu_clk[cluster_index].hw);
458 if (ret)
459 return ret;
460 ap_cpu_data->hws[cluster_index] = &ap_cpu_clk[cluster_index].hw;
461 }
462
463 ap_cpu_data->num = cluster_index + 1;
464
465 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, ap_cpu_data);
466 if (ret)
467 dev_err(dev, "failed to register OF clock provider\n");
468
469 return ret;
470 }
471
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 76465 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/2] Enable usage of Marvell FW SIP services
2021-01-14 10:26 [PATCH v2 0/2] Enable usage of Marvell FW SIP services kostap
2021-01-14 10:26 ` [PATCH v2 1/2] thermal: armada: ap806: use firmware SiP services for thermal operations kostap
2021-01-14 10:26 ` [PATCH v2 2/2] clk: mvebu: use firmware SiP service for accessing dfx register set kostap
@ 2021-02-11 2:36 ` Stephen Boyd
2 siblings, 0 replies; 8+ messages in thread
From: Stephen Boyd @ 2021-02-11 2:36 UTC (permalink / raw)
To: kostap, linux-clk
Cc: linux-pm, mturquette, miquel.raynal, rui.zhang, daniel.lezcano,
amitk, mw, jaz, nadavh, bpeled, stefanc, Konstantin Porotchkin
Quoting kostap@marvell.com (2021-01-14 02:26:41)
> From: Konstantin Porotchkin <kostap@marvell.com>
>
> These patches enable usage of Arm Trusted Firmware SIP services on
> Marvell Armada plaforms for accessing system registers that are not
> normally accessible from kernel or user space (EL1/EL0), like DFX
> registers group.
>
> v2:
> * use separate legacy/smc regmap functions registered at ap-cpu
> clock driver probe according to FW response
Please fix kbuild robot errors. Probably some Kconfig dependency is
needed?
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-02-11 2:37 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-14 10:26 [PATCH v2 0/2] Enable usage of Marvell FW SIP services kostap
2021-01-14 10:26 ` [PATCH v2 1/2] thermal: armada: ap806: use firmware SiP services for thermal operations kostap
2021-01-14 13:17 ` kernel test robot
2021-01-14 13:17 ` kernel test robot
2021-01-14 10:26 ` [PATCH v2 2/2] clk: mvebu: use firmware SiP service for accessing dfx register set kostap
2021-01-14 14:27 ` kernel test robot
2021-01-14 19:00 ` kernel test robot
2021-02-11 2:36 ` [PATCH v2 0/2] Enable usage of Marvell FW SIP services Stephen Boyd
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.