On Mon, 2017-10-09 at 15:11 +0100, Bryan O'Donoghue wrote:
> This patch adds logic to correctly setup the write timing parameters
> when blowing an OTP fuse for the i.MX7S/D.
> 
> Fixes: 0642bac7da42 ("nvmem: imx-ocotp: add write support")
> 
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> ---
>  drivers/nvmem/imx-ocotp.c | 63 
> ++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 52 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
> index 2645ee3..f80aee9 100644
> --- a/drivers/nvmem/imx-ocotp.c
> +++ b/drivers/nvmem/imx-ocotp.c
> @@ -51,16 +51,12 @@
>  #define IMX_OCOTP_BM_CTRL_REL_SHADOWS        0x00000400
>  
>  #define DEF_RELAX                    20 /* > 16.5ns */
> +#define DEF_FSOURCE                  1001

Maybe add a comment /* > 1000ns */ ?

Also, I get why there is no DEF_STROBE_PROG, but this is a bit
inconsistent. You could switch to 64-bit calculations and add a

#define DEF_STROBE_PROG                 10000

here.

>  #define IMX_OCOTP_WR_UNLOCK          0x3E770000
>  #define IMX_OCOTP_READ_LOCKED_VAL    0xBADABADA
>  
>  static DEFINE_MUTEX(ocotp_mutex);
>  
> -struct ocotp_params {
> -     unsigned int nregs;
> -     unsigned int bank_address_words;
> -};
> -
>  struct ocotp_priv {
>       struct device *dev;
>       struct clk *clk;
> @@ -69,6 +65,12 @@ struct ocotp_priv {
>       struct nvmem_config *config;
>  };
>  
> +struct ocotp_params {
> +     unsigned int nregs;
> +     unsigned int bank_address_words;
> +     void (*set_timing)(struct ocotp_priv *priv);
> +};
> +
>  static int imx_ocotp_wait_for_busy(void __iomem *base, u32 flags)
>  {
>       int count;
> @@ -193,6 +195,25 @@ static void imx_ocotp_set_imx6_timing(struct ocotp_priv 
> *priv)
>       writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
>  }
>  
> +static void imx_ocotp_set_imx7_timing(struct ocotp_priv *priv)
> +{
> +     unsigned long clk_rate = 0;
> +     unsigned long fsource, strobe_prog;
> +     u32 timing = 0;
> +
> +     /* i.MX 7Solo Applications Processor Reference Manual, Rev. 0.1
> +      * 6.4.3.3
> +      */
> +     clk_rate = clk_get_rate(priv->clk);
> +     fsource = DIV_ROUND_UP(((clk_rate / 1000) * DEF_FSOURCE), 1000000) + 1;
> +     strobe_prog = ((clk_rate * 10) / 1000000) + 1;

Would

        fsource = DIV_ROUND_UP_ULL((u64)clk_rate * DEF_FSOURCE,
                                   NSEC_PER_SEC) + 1;
        strobe_prog = DIV_ROUND_CLOSEST_ULL((u64)clk_rate * DEF_STROBE_PROG,
                                            NSEC_PER_SEC) + 1;

work instead?

> +
> +     timing = strobe_prog & 0x00000FFF;
> +     timing |= (fsource       << 12) & 0x000FF000;

Unnecessary whitespace.

> +
> +     writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
> +}
> +
>  static int imx_ocotp_write(void *context, unsigned int offset, void *val,
>                          size_t bytes)
>  {
> @@ -219,7 +240,7 @@ static int imx_ocotp_write(void *context, unsigned int 
> offset, void *val,
>       }
>  
>       /* Setup the write timing values */
> -     imx_ocotp_set_imx6_timing(priv);
> +     priv->params->set_timing(priv);
>  
>       /* 47.3.1.3.2
>        * Check that HW_OCOTP_CTRL[BUSY] and HW_OCOTP_CTRL[ERROR] are clear.
> @@ -372,11 +393,31 @@ static struct nvmem_config imx_ocotp_nvmem_config = {
>  };
>  
>  static const struct ocotp_params params[] = {
> -     { .nregs = 128, .bank_address_words = 0 },
> -     { .nregs = 64,  .bank_address_words = 0 },
> -     { .nregs = 128, .bank_address_words = 0 },
> -     { .nregs = 128, .bank_address_words = 0 },
> -     { .nregs = 64,  .bank_address_words = 4 },
> +     {
> +             .nregs = 128,
> +             .bank_address_words = 0,
> +             .set_timing = imx_ocotp_set_imx6_timing,
> +     },
> +     {
> +             .nregs = 64,
> +             .bank_address_words = 0,
> +             .set_timing = imx_ocotp_set_imx6_timing,
> +     },
> +     {
> +             .nregs = 128,
> +             .bank_address_words = 0,
> +             .set_timing = imx_ocotp_set_imx6_timing,
> +     },
> +     {
> +             .nregs = 128,
> +             .bank_address_words = 0,
> +             .set_timing = imx_ocotp_set_imx6_timing,
> +     },
> +     {
> +             .nregs = 64,
> +             .bank_address_words = 4,
> +             .set_timing = imx_ocotp_set_imx7_timing,
> +     },

See previous patches.

>  };
>  
>  static const struct of_device_id imx_ocotp_dt_ids[] = {

regards
Philipp

Reply via email to