Hi Stefano, > > 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 ?
CONFIG_SYS_FSL_IIM_ADDR is supposed to be a board configuration option, just like CONFIG_SYS_I2C_BASE. This makes things easier since on MPC this address comes from a struct (&((immap_t *) CONFIG_SYS_IMMR)->iim). Or we could define a FSL_IIM_BASE_ADDR in all supported register definition files, but that would mean including conditionally these files in fsl_iim.c. Best regards, Benoît _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot