[PATCH v3 5/7] nvmem: imx-ocotp: Add i.MX7D timing write clock setup support

Philipp Zabel p.zabel at pengutronix.de
Wed Oct 11 09:03:25 PDT 2017


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 <pure.logic at nexus-software.ie>
> ---
>  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



More information about the linux-arm-kernel mailing list