lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 09 Jan 2019 11:28:31 -0800
From:   Stephen Boyd <sboyd@...nel.org>
To:     David Dai <daidavid1@...eaurora.org>,
        linux-arm-msm@...r.kernel.org, linux-clk@...r.kernel.org,
        linux-kernel@...r.kernel.org
Cc:     David Dai <daidavid1@...eaurora.org>, georgi.djakov@...aro.org,
        bjorn.andersson@...aro.org, evgreen@...gle.com,
        tdas@...eaurora.org, elder@...aro.org
Subject: Re: [PATCH v1] clk: qcom: clk-rpmh: Add IPA clock support

Quoting David Dai (2018-12-13 18:35:04)
> The current clk-rpmh driver only supports on and off RPMh clock resources,
> let's extend the current driver by add support for clocks that are managed
> by a different type of RPMh resource known as Bus Clock Manager(BCM).
> The BCM is a configurable shared resource aggregator that scales performance
> based on a preset of frequency points. The Qualcomm IP Accelerator (IPA) clock
> is an example of a resource that is managed by the BCM and this a requirement
> from the IPA driver in order to scale its core clock.

Please use this commit text instead:

    
The clk-rpmh driver only supports on and off RPMh clock resources. Let's
extend the driver by add support for clocks that are managed by a
different type of RPMh resource known as Bus Clock Manager(BCM). The BCM
is a configurable shared resource aggregator that scales performance
based on a set of frequency points. The Qualcomm IP Accelerator (IPA)
clock is an example of a resource that is managed by the BCM and this a
requirement from the IPA driver in order to scale its core clock.

> 
> Signed-off-by: David Dai <daidavid1@...eaurora.org>
> ---
>  drivers/clk/qcom/clk-rpmh.c           | 141 ++++++++++++++++++++++++++++++++++
>  include/dt-bindings/clock/qcom,rpmh.h |   1 +
>  2 files changed, 142 insertions(+)
> 
> diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c
> index 9f4fc77..ee78c4b 100644
> --- a/drivers/clk/qcom/clk-rpmh.c
> +++ b/drivers/clk/qcom/clk-rpmh.c
> @@ -18,6 +18,31 @@
>  #define CLK_RPMH_ARC_EN_OFFSET         0
>  #define CLK_RPMH_VRM_EN_OFFSET         4
>  
> +#define BCM_TCS_CMD_COMMIT_MASK                0x40000000
> +#define BCM_TCS_CMD_VALID_SHIFT                29
> +#define BCM_TCS_CMD_VOTE_MASK          0x3fff
> +#define BCM_TCS_CMD_VOTE_SHIFT         0
> +
> +#define BCM_TCS_CMD(valid, vote)                               \
> +       (BCM_TCS_CMD_COMMIT_MASK |                              \
> +       ((valid) << BCM_TCS_CMD_VALID_SHIFT) |                  \
> +       ((cpu_to_le32(vote) &                                   \

Why?

> +       BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_SHIFT))
> +
> +/**
> + * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM)
> + * @unit: divisor used to convert Hz value to an RPMh msg
> + * @width: multiplier used to convert Hz value to an RPMh msg
> + * @vcd: virtual clock domain that this bcm belongs to
> + * @reserved: reserved to pad the struct
> + */
> +struct bcm_db {
> +       __le32 unit;
> +       __le16 width;
> +       u8 vcd;
> +       u8 reserved;
> +};
> +
>  /**
>   * struct clk_rpmh - individual rpmh clock data structure
>   * @hw:                        handle between common and hardware-specific interfaces
> @@ -29,6 +54,7 @@
>   * @aggr_state:                rpmh clock aggregated state
>   * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh
>   * @valid_state_mask:  mask to determine the state of the rpmh clock
> + * @aux_data:          data specific to the bcm rpmh resource

But there isn't aux_data. Is this supposed to be unit? And what is unit
going to be? 1000?

>   * @dev:               device to which it is attached
>   * @peer:              pointer to the clock rpmh sibling
>   */
> @@ -42,6 +68,7 @@ struct clk_rpmh {
>         u32 aggr_state;
>         u32 last_sent_aggr_state;
>         u32 valid_state_mask;
> +       u32 unit;
>         struct device *dev;
>         struct clk_rpmh *peer;
>  };
> @@ -210,6 +248,91 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw,
>         .recalc_rate    = clk_rpmh_recalc_rate,
>  };
>  
> +static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable)
> +{
> +       struct tcs_cmd cmd = { 0 };
> +       u32 cmd_state;
> +       int ret;
> +
> +       mutex_lock(&rpmh_clk_lock);
> +
> +       cmd_state = enable ? (c->aggr_state ? c->aggr_state : 1) : 0;

Make this into an if statement instead of double ternary?

	cmd_state = 0;
	if (enable) {
		cmd_state = 1;
		if (c->aggr_state)
			cmd_state = c->aggr_state;

	}

> +
> +       if (c->last_sent_aggr_state == cmd_state)
> +               return 0;

We just returned with a mutex held. Oops!

> +
> +       cmd.addr = c->res_addr;
> +       cmd.data = BCM_TCS_CMD(enable, cmd_state);
> +
> +       ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, &cmd, 1);
> +       if (ret) {
> +               dev_err(c->dev, "set active state of %s failed: (%d)\n",
> +                       c->res_name, ret);
> +               return ret;

Again!

> +       }
> +
> +       c->last_sent_aggr_state = cmd_state;
> +
> +       mutex_unlock(&rpmh_clk_lock);
> +
> +       return 0;
> +}
> +
> +static int clk_rpmh_bcm_prepare(struct clk_hw *hw)
> +{
> +       struct clk_rpmh *c = to_clk_rpmh(hw);
> +       int ret;
> +
> +       ret = clk_rpmh_bcm_send_cmd(c, true);
> +
> +       return ret;

Just write return clk_rpmh_bcm_send_cmd(...)

> +};
> +
> +static void clk_rpmh_bcm_unprepare(struct clk_hw *hw)
> +{
> +       struct clk_rpmh *c = to_clk_rpmh(hw);
> +
> +       clk_rpmh_bcm_send_cmd(c, false);
> +};
> +
> +static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate,
> +                                unsigned long parent_rate)
> +{
> +       struct clk_rpmh *c = to_clk_rpmh(hw);
> +
> +       c->aggr_state = rate / c->unit;
> +       /*
> +        * Since any non-zero value sent to hw would result in enabling the
> +        * clock, only send the value if the clock has already been prepared.
> +        */
> +       if (clk_hw_is_prepared(hw))

This is sad, but OK.

> +               clk_rpmh_bcm_send_cmd(c, true);
> +
> +       return 0;
> +};
> +
[...]
> @@ -217,6 +340,7 @@ static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw,
>  DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1);
>  DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1);
>  DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1);
> +DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0");

It's really IP0?! What was wrong with IPA?

>  
>  static struct clk_hw *sdm845_rpmh_clocks[] = {
>         [RPMH_CXO_CLK]          = &sdm845_bi_tcxo.hw,
> @@ -275,6 +402,20 @@ static int clk_rpmh_probe(struct platform_device *pdev)
>                                 rpmh_clk->res_name);
>                         return -ENODEV;
>                 }
> +
> +               data = cmd_db_read_aux_data(rpmh_clk->res_name, &aux_data_len);
> +               if (IS_ERR(data)) {
> +                       ret = PTR_ERR(data);
> +                       dev_err(&pdev->dev,
> +                               "error reading RPMh aux data for %s (%d)\n",
> +                               rpmh_clk->res_name, ret);
> +                               return ret;

Weird indent here.

Powered by blists - more mailing lists