Message ID | 1439310001-5643-4-git-send-email-aalonso@freescale.com |
---|---|
State | Awaiting Upstream |
Delegated to: | Stefano Babic |
Headers | show |
On 11/08/2015 18:19, Adrian Alonso wrote: > * Ocotp of i.MX7D has different operation rule. > This patch is to add support for i.MX7D ocotp. > > Signed-off-by: Adrian Alonso <aalonso@freescale.com> > Signed-off-by: Peng Fan <Peng.Fan@freescale.com> > Signed-off-by: Ye.Li <B37916@freescale.com> > --- > Changes for V2: Resend > Changes for V3: Resend > Changes for V4: Resend > Changes for V5: Resend > > drivers/misc/mxc_ocotp.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 73 insertions(+), 1 deletion(-) > > diff --git a/drivers/misc/mxc_ocotp.c b/drivers/misc/mxc_ocotp.c > index d92044e..d9b02c7 100644 > --- a/drivers/misc/mxc_ocotp.c > +++ b/drivers/misc/mxc_ocotp.c > @@ -25,8 +25,21 @@ > #define BM_CTRL_ERROR 0x00000200 > #define BM_CTRL_BUSY 0x00000100 > #define BO_CTRL_ADDR 0 > +#ifdef CONFIG_MX7 > +#define BM_CTRL_ADDR 0x0000000f > +#define BM_CTRL_RELOAD 0x00000400 > +#else > #define BM_CTRL_ADDR 0x0000007f > - > +#endif > + > +#ifdef CONFIG_MX7 > +#define BO_TIMING_FSOURCE 12 > +#define BM_TIMING_FSOURCE 0x0007f000 > +#define BV_TIMING_FSOURCE_NS 1001 > +#define BO_TIMING_PROG 0 > +#define BM_TIMING_PROG 0x00000fff > +#define BV_TIMING_PROG_US 10 > +#else > #define BO_TIMING_STROBE_READ 16 > #define BM_TIMING_STROBE_READ 0x003f0000 > #define BV_TIMING_STROBE_READ_NS 37 > @@ -36,6 +49,7 @@ > #define BO_TIMING_STROBE_PROG 0 > #define BM_TIMING_STROBE_PROG 0x00000fff > #define BV_TIMING_STROBE_PROG_US 10 > +#endif > > #define BM_READ_CTRL_READ_FUSE 0x00000001 > > @@ -109,6 +123,25 @@ int fuse_read(u32 bank, u32 word, u32 *val) > return finish_access(regs, __func__); > } > > +#ifdef CONFIG_MX7 > +static void set_timing(struct ocotp_regs *regs) > +{ > + u32 ipg_clk; > + u32 fsource, prog; > + u32 timing; > + > + ipg_clk = mxc_get_clock(MXC_IPG_CLK); > + > + fsource = DIV_ROUND_UP((ipg_clk / 1000) * BV_TIMING_FSOURCE_NS, > + + 1000000) + 1; > + prog = DIV_ROUND_CLOSEST(ipg_clk * BV_TIMING_PROG_US, 1000000) + 1; > + > + timing = BF(fsource, TIMING_FSOURCE) | BF(prog, TIMING_PROG); > + > + clrsetbits_le32(®s->timing, BM_TIMING_FSOURCE | BM_TIMING_PROG, > + timing); > +} > +#else > static void set_timing(struct ocotp_regs *regs) > { > u32 ipg_clk; > @@ -130,12 +163,17 @@ static void set_timing(struct ocotp_regs *regs) > clrsetbits_le32(®s->timing, BM_TIMING_STROBE_READ | BM_TIMING_RELAX | > BM_TIMING_STROBE_PROG, timing); > } > +#endif > > static void setup_direct_access(struct ocotp_regs *regs, u32 bank, u32 word, > int write) > { > u32 wr_unlock = write ? BV_CTRL_WR_UNLOCK_KEY : 0; > +#ifdef CONFIG_MX7 > + u32 addr = bank; > +#else > u32 addr = bank << 3 | word; > +#endif > > set_timing(regs); > clrsetbits_le32(®s->ctrl, BM_CTRL_WR_UNLOCK | BM_CTRL_ADDR, > @@ -155,7 +193,11 @@ int fuse_sense(u32 bank, u32 word, u32 *val) > setup_direct_access(regs, bank, word, false); > writel(BM_READ_CTRL_READ_FUSE, ®s->read_ctrl); > wait_busy(regs, 1); > +#ifdef CONFIG_MX7 > + *val = readl((®s->read_fuse_data0) + (word << 2)); > +#else > *val = readl(®s->read_fuse_data); > +#endif > > return finish_access(regs, __func__); > } > @@ -176,8 +218,38 @@ int fuse_prog(u32 bank, u32 word, u32 val) > return ret; > > setup_direct_access(regs, bank, word, true); > +#ifdef CONFIG_MX7 > + switch (word) { > + case 0: > + writel(0, ®s->data1); > + writel(0, ®s->data2); > + writel(0, ®s->data3); > + writel(val, ®s->data0); > + break; > + case 1: > + writel(val, ®s->data1); > + writel(0, ®s->data2); > + writel(0, ®s->data3); > + writel(0, ®s->data0); > + break; > + case 2: > + writel(0, ®s->data1); > + writel(val, ®s->data2); > + writel(0, ®s->data3); > + writel(0, ®s->data0); > + break; > + case 3: > + writel(0, ®s->data1); > + writel(0, ®s->data2); > + writel(val, ®s->data3); > + writel(0, ®s->data0); > + break; > + } > + wait_busy(regs, BV_TIMING_PROG_US); > +#else > writel(val, ®s->data); > wait_busy(regs, BV_TIMING_STROBE_PROG_US); > +#endif > udelay(WRITE_POSTAMBLE_US); > > return finish_access(regs, __func__); > Applied to u-boot-imx, thanks ! Best regards, Stefano Babic
diff --git a/drivers/misc/mxc_ocotp.c b/drivers/misc/mxc_ocotp.c index d92044e..d9b02c7 100644 --- a/drivers/misc/mxc_ocotp.c +++ b/drivers/misc/mxc_ocotp.c @@ -25,8 +25,21 @@ #define BM_CTRL_ERROR 0x00000200 #define BM_CTRL_BUSY 0x00000100 #define BO_CTRL_ADDR 0 +#ifdef CONFIG_MX7 +#define BM_CTRL_ADDR 0x0000000f +#define BM_CTRL_RELOAD 0x00000400 +#else #define BM_CTRL_ADDR 0x0000007f - +#endif + +#ifdef CONFIG_MX7 +#define BO_TIMING_FSOURCE 12 +#define BM_TIMING_FSOURCE 0x0007f000 +#define BV_TIMING_FSOURCE_NS 1001 +#define BO_TIMING_PROG 0 +#define BM_TIMING_PROG 0x00000fff +#define BV_TIMING_PROG_US 10 +#else #define BO_TIMING_STROBE_READ 16 #define BM_TIMING_STROBE_READ 0x003f0000 #define BV_TIMING_STROBE_READ_NS 37 @@ -36,6 +49,7 @@ #define BO_TIMING_STROBE_PROG 0 #define BM_TIMING_STROBE_PROG 0x00000fff #define BV_TIMING_STROBE_PROG_US 10 +#endif #define BM_READ_CTRL_READ_FUSE 0x00000001 @@ -109,6 +123,25 @@ int fuse_read(u32 bank, u32 word, u32 *val) return finish_access(regs, __func__); } +#ifdef CONFIG_MX7 +static void set_timing(struct ocotp_regs *regs) +{ + u32 ipg_clk; + u32 fsource, prog; + u32 timing; + + ipg_clk = mxc_get_clock(MXC_IPG_CLK); + + fsource = DIV_ROUND_UP((ipg_clk / 1000) * BV_TIMING_FSOURCE_NS, + + 1000000) + 1; + prog = DIV_ROUND_CLOSEST(ipg_clk * BV_TIMING_PROG_US, 1000000) + 1; + + timing = BF(fsource, TIMING_FSOURCE) | BF(prog, TIMING_PROG); + + clrsetbits_le32(®s->timing, BM_TIMING_FSOURCE | BM_TIMING_PROG, + timing); +} +#else static void set_timing(struct ocotp_regs *regs) { u32 ipg_clk; @@ -130,12 +163,17 @@ static void set_timing(struct ocotp_regs *regs) clrsetbits_le32(®s->timing, BM_TIMING_STROBE_READ | BM_TIMING_RELAX | BM_TIMING_STROBE_PROG, timing); } +#endif static void setup_direct_access(struct ocotp_regs *regs, u32 bank, u32 word, int write) { u32 wr_unlock = write ? BV_CTRL_WR_UNLOCK_KEY : 0; +#ifdef CONFIG_MX7 + u32 addr = bank; +#else u32 addr = bank << 3 | word; +#endif set_timing(regs); clrsetbits_le32(®s->ctrl, BM_CTRL_WR_UNLOCK | BM_CTRL_ADDR, @@ -155,7 +193,11 @@ int fuse_sense(u32 bank, u32 word, u32 *val) setup_direct_access(regs, bank, word, false); writel(BM_READ_CTRL_READ_FUSE, ®s->read_ctrl); wait_busy(regs, 1); +#ifdef CONFIG_MX7 + *val = readl((®s->read_fuse_data0) + (word << 2)); +#else *val = readl(®s->read_fuse_data); +#endif return finish_access(regs, __func__); } @@ -176,8 +218,38 @@ int fuse_prog(u32 bank, u32 word, u32 val) return ret; setup_direct_access(regs, bank, word, true); +#ifdef CONFIG_MX7 + switch (word) { + case 0: + writel(0, ®s->data1); + writel(0, ®s->data2); + writel(0, ®s->data3); + writel(val, ®s->data0); + break; + case 1: + writel(val, ®s->data1); + writel(0, ®s->data2); + writel(0, ®s->data3); + writel(0, ®s->data0); + break; + case 2: + writel(0, ®s->data1); + writel(val, ®s->data2); + writel(0, ®s->data3); + writel(0, ®s->data0); + break; + case 3: + writel(0, ®s->data1); + writel(0, ®s->data2); + writel(val, ®s->data3); + writel(0, ®s->data0); + break; + } + wait_busy(regs, BV_TIMING_PROG_US); +#else writel(val, ®s->data); wait_busy(regs, BV_TIMING_STROBE_PROG_US); +#endif udelay(WRITE_POSTAMBLE_US); return finish_access(regs, __func__);