On 14/08/2012 14:52, Benoît Thébaudeau wrote: > Add a fsl_iim driver common to i.MX and MPC. > > Signed-off-by: Benoît Thébaudeau <benoit.thebaud...@advansee.com> > Cc: Wolfgang Denk <w...@denx.de> > Cc: Stefano Babic <sba...@denx.de> > --- > .../drivers/misc/Makefile | 1 + > /dev/null => u-boot-4d3c95f/drivers/misc/fsl_iim.c | 318 > ++++++++++++++++++++ > 2 files changed, 319 insertions(+) > create mode 100644 u-boot-4d3c95f/drivers/misc/fsl_iim.c > > diff --git u-boot-4d3c95f.orig/drivers/misc/Makefile > u-boot-4d3c95f/drivers/misc/Makefile > index 271463c..31b8db8 100644 > --- u-boot-4d3c95f.orig/drivers/misc/Makefile > +++ u-boot-4d3c95f/drivers/misc/Makefile > @@ -27,6 +27,7 @@ LIB := $(obj)libmisc.o > > COBJS-$(CONFIG_ALI152X) += ali512x.o > COBJS-$(CONFIG_DS4510) += ds4510.o > +COBJS-$(CONFIG_FSL_IIM) += fsl_iim.o > COBJS-$(CONFIG_FSL_LAW) += fsl_law.o > COBJS-$(CONFIG_GPIO_LED) += gpio_led.o > COBJS-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o > diff --git u-boot-4d3c95f/drivers/misc/fsl_iim.c > u-boot-4d3c95f/drivers/misc/fsl_iim.c > new file mode 100644 > index 0000000..1a3d5fc > --- /dev/null > +++ u-boot-4d3c95f/drivers/misc/fsl_iim.c > @@ -0,0 +1,318 @@ > +/* > + * (C) Copyright 2009-2012 ADVANSEE > + * Benoît Thébaudeau <benoit.thebaud...@advansee.com> > + * > + * Based on the mpc512x iim code: > + * Copyright 2008 Silicon Turnkey Express, Inc. > + * Martha Marx <mm...@silicontkx.com> > + * > + * See file CREDITS for list of people who contributed to this > + * project. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307 USA > + */ > + > +#include <config.h> > +#include <common.h> > +#include <hwconfig.h> > +#include <fuse.h> > +#include <asm/errno.h> > +#include <asm/byteorder.h> > +#include <asm/io.h> > + > +/* FSL IIM-specific constants */ > +#define STAT_BUSY 0x80 > +#define STAT_PRGD 0x02 > +#define STAT_SNSD 0x01 > + > +#define STATM_PRGD_M 0x02 > +#define STATM_SNSD_M 0x01 > + > +#define ERR_PRGE 0x80 > +#define ERR_WPE 0x40 > +#define ERR_OPE 0x20 > +#define ERR_RPE 0x10 > +#define ERR_WLRE 0x08 > +#define ERR_SNSE 0x04 > +#define ERR_PARITYE 0x02 > + > +#define EMASK_PRGE_M 0x80 > +#define EMASK_WPE_M 0x40 > +#define EMASK_OPE_M 0x20 > +#define EMASK_RPE_M 0x10 > +#define EMASK_WLRE_M 0x08 > +#define EMASK_SNSE_M 0x04 > +#define EMASK_PARITYE_M 0x02 > + > +#define FCTL_DPC 0x80 > +#define FCTL_PRG_LENGTH_MASK 0x70 > +#define FCTL_ESNS_N 0x08 > +#define FCTL_ESNS_0 0x04 > +#define FCTL_ESNS_1 0x02 > +#define FCTL_PRG 0x01 > + > +#define UA_A_BANK_MASK 0x38 > +#define UA_A_ROWH_MASK 0x07 > + > +#define LA_A_ROWL_MASK 0xf8 > +#define LA_A_BIT_MASK 0x07 > + > +#define PREV_PROD_REV_MASK 0xf8 > +#define PREV_PROD_VT_MASK 0x07 > + > +/* Select the correct accessors depending on endianness */ > +#if __BYTE_ORDER == __LITTLE_ENDIAN > +#define iim_read32 in_le32 > +#define iim_write32 out_le32 > +#define iim_clrsetbits32 clrsetbits_le32 > +#define iim_clrbits32 clrbits_le32 > +#define iim_setbits32 setbits_le32 > +#elif __BYTE_ORDER == __BIG_ENDIAN > +#define iim_read32 in_be32 > +#define iim_write32 out_be32 > +#define iim_clrsetbits32 clrsetbits_be32 > +#define iim_clrbits32 clrbits_be32 > +#define iim_setbits32 setbits_be32 > +#else > +#error "Endianess is not defined: please fix to continue" > +#endif > + > +/* IIM control registers */ > +struct fsl_iim { > + u32 stat; > + u32 statm; > + u32 err; > + u32 emask; > + u32 fctl; > + u32 ua; > + u32 la; > + u32 sdat; > + u32 prev; > + u32 srev; > + u32 prg_p; > + u32 scs[0x1f5]; > + struct { > + u32 row[0x100]; > + } bank[8]; > +}; > + > +int fuse_read_bit(u32 bank, u32 row, u32 bit, u32 *val) > +{ > + int ret; > + > + if (bit >= 8) { > + puts("fsl_iim fuse read: Invalid argument\n"); > + return -EINVAL; > + } > + > + ret = fuse_read_row(bank, row, val); > + if (ret) > + return ret; > + > + *val = !!(*val & 1 << bit); > + return 0; > +} > + > +int fuse_read_row(u32 bank, u32 row, u32 *val) > +{ > + volatile struct fsl_iim *regs = > + (struct fsl_iim *)CONFIG_SYS_FSL_IIM_ADDR; > + u32 err; > + > + if (bank >= ARRAY_SIZE(regs->bank) || > + row >= ARRAY_SIZE(regs->bank[0].row) || > + val == NULL) { > + puts("fsl_iim fuse read: Invalid argument\n"); > + return -EINVAL; > + } > + > + iim_write32(®s->err, iim_read32(®s->err)); > + *val = iim_read32(®s->bank[bank].row[row]); > + err = iim_read32(®s->err); > + iim_write32(®s->err, iim_read32(®s->err)); > + > + if (err & ERR_RPE) { > + puts("fsl_iim fuse read: Read protect error\n"); > + return -EIO; > + } > + > + return 0; > +} > + > +int fuse_sense_bit(u32 bank, u32 row, u32 bit, u32 *val) > +{ > + int ret; > + > + if (bit >= 8) { > + puts("fsl_iim fuse sense: Invalid argument\n"); > + return -EINVAL; > + } > + > + ret = fuse_sense_row(bank, row, val); > + if (ret) > + return ret; > + > + *val = !!(*val & 1 << bit); > + return 0; > +} > + > +int fuse_sense_row(u32 bank, u32 row, u32 *val) > +{ > + volatile struct fsl_iim *regs = > + (struct fsl_iim *)CONFIG_SYS_FSL_IIM_ADDR; > + u32 stat, err; > + > + if (bank >= ARRAY_SIZE(regs->bank) || > + row >= ARRAY_SIZE(regs->bank[0].row) || > + val == NULL) { > + puts("fsl_iim fuse sense: Invalid argument\n"); > + return -EINVAL; > + } > + > + iim_write32(®s->stat, iim_read32(®s->stat)); > + iim_write32(®s->err, iim_read32(®s->err)); > + iim_write32(®s->ua, bank << 3 | row >> 5); > + iim_write32(®s->la, row << 3 & 0xff); > + iim_write32(®s->fctl, iim_read32(®s->fctl) | FCTL_ESNS_N); > + while (iim_read32(®s->stat) & STAT_BUSY) > + udelay(20); > + stat = iim_read32(®s->stat); > + err = iim_read32(®s->err); > + iim_write32(®s->stat, iim_read32(®s->stat)); > + iim_write32(®s->err, iim_read32(®s->err)); > + > + if (err & ERR_SNSE) { > + puts("fsl_iim fuse sense: Explicit sense cycle error\n"); > + return -EIO; > + } > + > + if (!(stat & STAT_SNSD)) { > + puts("fsl_iim fuse sense: Explicit sense cycle " > + "did not complete\n"); > + return -EIO; > + } > + > + *val = iim_read32(®s->sdat); > + return 0; > +} > + > +int fuse_prog_bit(u32 bank, u32 row, u32 bit) > +{ > + volatile struct fsl_iim *regs = > + (struct fsl_iim *)CONFIG_SYS_FSL_IIM_ADDR;
The address depends on the SOC, and is not a board configuration option. Should we not use IIM_BASE_ADDR ? Best regards, Stefano -- ===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de ===================================================================== _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot