diff mbox series

[v5,3/5] nvmem: imx-ocotp: Change TIMING calculation to u-boot algorithm

Message ID 20190424202607.23522-4-pure.logic@nexus-software.ie (mailing list archive)
State New, archived
Headers show
Series Add i.MX8MM support | expand

Commit Message

Bryan O'Donoghue April 24, 2019, 8:26 p.m. UTC
The RELAX field of the OCOTP block is turning out as a zero on i.MX8MM.
This messes up the subsequent re-load of the fuse shadow registers.

After some discussion with people @ NXP its clear we have missed a trick
here in Linux.

The OCOTP fuse programming time has a physical minimum 'burn time' that is
not related to the ipg_clk.

We need to define the RELAX, STROBE_READ and STROBE_PROG fields in terms of
desired timings to allow for the burn-in to safely complete. Right now only
the RELAX field is calculated in terms of an absolute time and we are
ending up with a value of zero.

This patch inherits the u-boot timings for the OCOTP_TIMING calculation on
the i.MX6 and i.MX8. Those timings are known to work and critically specify
values such as STROBE_PROG as a minimum timing.

Fixes: 0642bac7da42 ("nvmem: imx-ocotp: add write support")

Signed-off-by: Bryan O'Donoghue <pure.logic@nexus-software.ie>
Suggested-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 drivers/nvmem/imx-ocotp.c | 36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

Comments

Leonard Crestez April 25, 2019, 12:41 p.m. UTC | #1
On 24.04.2019 23:26, Bryan O'Donoghue wrote:
> The RELAX field of the OCOTP block is turning out as a zero on i.MX8MM.
> This messes up the subsequent re-load of the fuse shadow registers.
> 
> After some discussion with people @ NXP its clear we have missed a trick
> here in Linux.
> 
> The OCOTP fuse programming time has a physical minimum 'burn time' that is
> not related to the ipg_clk.
> 
> We need to define the RELAX, STROBE_READ and STROBE_PROG fields in terms of
> desired timings to allow for the burn-in to safely complete. Right now only
> the RELAX field is calculated in terms of an absolute time and we are
> ending up with a value of zero.
> 
> This patch inherits the u-boot timings for the OCOTP_TIMING calculation on
> the i.MX6 and i.MX8. Those timings are known to work and critically specify
> values such as STROBE_PROG as a minimum timing.
> 
> Fixes: 0642bac7da42 ("nvmem: imx-ocotp: add write support")
> 
> Signed-off-by: Bryan O'Donoghue <pure.logic@nexus-software.ie>

> -#define DEF_RELAX			20	/* > 16.5ns */
> +#define BV_TIMING_STROBE_PROG_US	10	/* Min time to blow a fuse */
> +#define BV_TIMING_STROBE_READ_NS	37	/* Min time before read */
> +#define BV_TIMING_RELAX_NS		17

I don't know what the BV_ prefix from uboot means exactly. It's combined 
with some bit field macros so maybe "Bit Value"? This prefix seems 
meaningless in kernel.

> @@ -182,12 +184,38 @@ static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv)
>   	 * fields with timing values to match the current frequency of the
>   	 * ipg_clk. OTP writes will work at maximum bus frequencies as long
>   	 * as the HW_OCOTP_TIMING parameters are set correctly.
> +	 *
> +	 * Note: there are minimum timings required to ensure an OTP fuse burns
> +	 * correctly that are independent of the ipg_clk. Those values are not
> +	 * formally documented anywhere however, working from the minimum
> +	 * timings given in u-boot we can say:
> +	 *
> +	 * - Minimum STROBE_PROG time is 10 microseconds. Intuitively 10
> +	 *   microseconds feels about right as representative of a minimum time
> +	 *   to physically burn out a fuse.
> +	 *
> +	 * - Minimum STROBE_READ i.e. the time to wait post OTP fuse burn before
> +	 *   performing another read is 37 nanoseconds
> +	 *
> +	 * - Minimum RELAX timing is 17 nanoseconds. This final RELAX minimum
> +	 *   timing is not entirely clear the documentation says "This
> +	 *   count value specifies the time to add to all default timing
> +	 *   parameters other than the Tpgm and Trd. It is given in number
> +	 *   of ipg_clk periods." where Tpgm and Trd refer to STROBE_PROG
> +	 *   and STROBE_READ respectively. What the other timing parameters
> +	 *   are though, is not specified. Experience shows a zero RELAX
> +	 *   value will mess up a re-load of the shadow registers post OTP
> +	 *   burn.
>   	 */
>   	clk_rate = clk_get_rate(priv->clk);
>   
> -	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
> -	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
> -	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
> +	relax = DIV_ROUND_UP(clk_rate * BV_TIMING_RELAX_NS, 1000000000) - 1;
> +	strobe_read = DIV_ROUND_UP(clk_rate * BV_TIMING_STROBE_READ_NS,
> +				   1000000000);
> +	strobe_read += 2 * (relax + 1) - 1;
> +	strobe_prog = DIV_ROUND_CLOSEST(clk_rate * BV_TIMING_STROBE_PROG_US,
> +					1000000);
> +	strobe_prog += 2 * (relax + 1) - 1;

Other than constant naming series whole looks good to me:
Reviewed-by: Leonard Crestez <leonard.crestez@nxp.com>

--
Regards,
Leonard
diff mbox series

Patch

diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
index 85a7d0da3abb..826812d3332f 100644
--- a/drivers/nvmem/imx-ocotp.c
+++ b/drivers/nvmem/imx-ocotp.c
@@ -50,7 +50,9 @@ 
 #define IMX_OCOTP_BM_CTRL_ERROR		0x00000200
 #define IMX_OCOTP_BM_CTRL_REL_SHADOWS	0x00000400
 
-#define DEF_RELAX			20	/* > 16.5ns */
+#define BV_TIMING_STROBE_PROG_US	10	/* Min time to blow a fuse */
+#define BV_TIMING_STROBE_READ_NS	37	/* Min time before read */
+#define BV_TIMING_RELAX_NS		17
 #define DEF_FSOURCE			1001	/* > 1000 ns */
 #define DEF_STROBE_PROG			10000	/* IPG clocks */
 #define IMX_OCOTP_WR_UNLOCK		0x3E770000
@@ -182,12 +184,38 @@  static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv)
 	 * fields with timing values to match the current frequency of the
 	 * ipg_clk. OTP writes will work at maximum bus frequencies as long
 	 * as the HW_OCOTP_TIMING parameters are set correctly.
+	 *
+	 * Note: there are minimum timings required to ensure an OTP fuse burns
+	 * correctly that are independent of the ipg_clk. Those values are not
+	 * formally documented anywhere however, working from the minimum
+	 * timings given in u-boot we can say:
+	 *
+	 * - Minimum STROBE_PROG time is 10 microseconds. Intuitively 10
+	 *   microseconds feels about right as representative of a minimum time
+	 *   to physically burn out a fuse.
+	 *
+	 * - Minimum STROBE_READ i.e. the time to wait post OTP fuse burn before
+	 *   performing another read is 37 nanoseconds
+	 *
+	 * - Minimum RELAX timing is 17 nanoseconds. This final RELAX minimum
+	 *   timing is not entirely clear the documentation says "This
+	 *   count value specifies the time to add to all default timing
+	 *   parameters other than the Tpgm and Trd. It is given in number
+	 *   of ipg_clk periods." where Tpgm and Trd refer to STROBE_PROG
+	 *   and STROBE_READ respectively. What the other timing parameters
+	 *   are though, is not specified. Experience shows a zero RELAX
+	 *   value will mess up a re-load of the shadow registers post OTP
+	 *   burn.
 	 */
 	clk_rate = clk_get_rate(priv->clk);
 
-	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
-	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
-	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
+	relax = DIV_ROUND_UP(clk_rate * BV_TIMING_RELAX_NS, 1000000000) - 1;
+	strobe_read = DIV_ROUND_UP(clk_rate * BV_TIMING_STROBE_READ_NS,
+				   1000000000);
+	strobe_read += 2 * (relax + 1) - 1;
+	strobe_prog = DIV_ROUND_CLOSEST(clk_rate * BV_TIMING_STROBE_PROG_US,
+					1000000);
+	strobe_prog += 2 * (relax + 1) - 1;
 
 	timing = readl(priv->base + IMX_OCOTP_ADDR_TIMING) & 0x0FC00000;
 	timing |= strobe_prog & 0x00000FFF;