uboot/drivers/misc/mxs_ocotp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Freescale i.MX28 OCOTP Driver
   4 *
   5 * Copyright (C) 2014 Marek Vasut <marex@denx.de>
   6 *
   7 * Note: The i.MX23/i.MX28 OCOTP block is a predecessor to the OCOTP block
   8 *       used in i.MX6 . While these blocks are very similar at the first
   9 *       glance, by digging deeper, one will notice differences (like the
  10 *       tight dependence on MXS power block, some completely new registers
  11 *       etc.) which would make common driver an ifdef nightmare :-(
  12 */
  13
  14#include <common.h>
  15#include <fuse.h>
  16#include <linux/delay.h>
  17#include <linux/errno.h>
  18#include <asm/io.h>
  19#include <asm/arch/clock.h>
  20#include <asm/arch/imx-regs.h>
  21#include <asm/arch/sys_proto.h>
  22
  23#define MXS_OCOTP_TIMEOUT       100000
  24
  25static struct mxs_ocotp_regs *ocotp_regs =
  26        (struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
  27static struct mxs_power_regs *power_regs =
  28        (struct mxs_power_regs *)MXS_POWER_BASE;
  29static struct mxs_clkctrl_regs *clkctrl_regs =
  30        (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
  31
  32static int mxs_ocotp_wait_busy_clear(void)
  33{
  34        uint32_t reg;
  35        int timeout = MXS_OCOTP_TIMEOUT;
  36
  37        while (--timeout) {
  38                reg = readl(&ocotp_regs->hw_ocotp_ctrl);
  39                if (!(reg & OCOTP_CTRL_BUSY))
  40                        break;
  41                udelay(10);
  42        }
  43
  44        if (!timeout)
  45                return -EINVAL;
  46
  47        /* Wait a little as per FSL datasheet's 'write postamble' section. */
  48        udelay(10);
  49
  50        return 0;
  51}
  52
  53static void mxs_ocotp_clear_error(void)
  54{
  55        writel(OCOTP_CTRL_ERROR, &ocotp_regs->hw_ocotp_ctrl_clr);
  56}
  57
  58static int mxs_ocotp_read_bank_open(bool open)
  59{
  60        int ret = 0;
  61
  62        if (open) {
  63                writel(OCOTP_CTRL_RD_BANK_OPEN,
  64                       &ocotp_regs->hw_ocotp_ctrl_set);
  65
  66                /*
  67                 * Wait before polling the BUSY bit, since the BUSY bit might
  68                 * be asserted only after a few HCLK cycles and if we were to
  69                 * poll immediatelly, we could miss the busy bit.
  70                 */
  71                udelay(10);
  72                ret = mxs_ocotp_wait_busy_clear();
  73        } else {
  74                writel(OCOTP_CTRL_RD_BANK_OPEN,
  75                       &ocotp_regs->hw_ocotp_ctrl_clr);
  76        }
  77
  78        return ret;
  79}
  80
  81static void mxs_ocotp_scale_vddio(bool enter, uint32_t *val)
  82{
  83        uint32_t scale_val;
  84
  85        if (enter) {
  86                /*
  87                 * Enter the fuse programming VDDIO voltage setup. We start
  88                 * scaling the voltage from it's current value down to 2.8V
  89                 * which is the one and only correct voltage for programming
  90                 * the OCOTP fuses (according to datasheet).
  91                 */
  92                scale_val = readl(&power_regs->hw_power_vddioctrl);
  93                scale_val &= POWER_VDDIOCTRL_TRG_MASK;
  94
  95                /* Return the original voltage. */
  96                *val = scale_val;
  97
  98                /*
  99                 * Start scaling VDDIO down to 0x2, which is 2.8V . Actually,
 100                 * the value 0x0 should be 2.8V, but that's not the case on
 101                 * most designs due to load etc., so we play safe. Undervolt
 102                 * can actually cause incorrect programming of the fuses and
 103                 * or reboots of the board.
 104                 */
 105                while (scale_val > 2) {
 106                        clrsetbits_le32(&power_regs->hw_power_vddioctrl,
 107                                        POWER_VDDIOCTRL_TRG_MASK, --scale_val);
 108                        udelay(500);
 109                }
 110        } else {
 111                /* Start scaling VDDIO up to original value . */
 112                for (scale_val = 2; scale_val <= *val; scale_val++) {
 113                        clrsetbits_le32(&power_regs->hw_power_vddioctrl,
 114                                        POWER_VDDIOCTRL_TRG_MASK, scale_val);
 115                        udelay(500);
 116                }
 117        }
 118
 119        mdelay(10);
 120}
 121
 122static int mxs_ocotp_wait_hclk_ready(void)
 123{
 124        uint32_t reg, timeout = MXS_OCOTP_TIMEOUT;
 125
 126        while (--timeout) {
 127                reg = readl(&clkctrl_regs->hw_clkctrl_hbus);
 128                if (!(reg & CLKCTRL_HBUS_ASM_BUSY))
 129                        break;
 130        }
 131
 132        if (!timeout)
 133                return -EINVAL;
 134
 135        return 0;
 136}
 137
 138static int mxs_ocotp_scale_hclk(bool enter, uint32_t *val)
 139{
 140        uint32_t scale_val;
 141        int ret;
 142
 143        ret = mxs_ocotp_wait_hclk_ready();
 144        if (ret)
 145                return ret;
 146
 147        /* Set CPU bypass */
 148        writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
 149               &clkctrl_regs->hw_clkctrl_clkseq_set);
 150
 151        if (enter) {
 152                /* Return the original HCLK clock speed. */
 153                *val = readl(&clkctrl_regs->hw_clkctrl_hbus);
 154                *val &= CLKCTRL_HBUS_DIV_MASK;
 155                *val >>= CLKCTRL_HBUS_DIV_OFFSET;
 156
 157                /* Scale the HCLK to 454/19 = 23.9 MHz . */
 158                scale_val = (~19) << CLKCTRL_HBUS_DIV_OFFSET;
 159                scale_val &= CLKCTRL_HBUS_DIV_MASK;
 160        } else {
 161                /* Scale the HCLK back to original frequency. */
 162                scale_val = (~(*val)) << CLKCTRL_HBUS_DIV_OFFSET;
 163                scale_val &= CLKCTRL_HBUS_DIV_MASK;
 164        }
 165
 166        writel(CLKCTRL_HBUS_DIV_MASK,
 167               &clkctrl_regs->hw_clkctrl_hbus_set);
 168        writel(scale_val,
 169               &clkctrl_regs->hw_clkctrl_hbus_clr);
 170
 171        mdelay(10);
 172
 173        ret = mxs_ocotp_wait_hclk_ready();
 174        if (ret)
 175                return ret;
 176
 177        /* Disable CPU bypass */
 178        writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
 179               &clkctrl_regs->hw_clkctrl_clkseq_clr);
 180
 181        mdelay(10);
 182
 183        return 0;
 184}
 185
 186static int mxs_ocotp_write_fuse(uint32_t addr, uint32_t mask)
 187{
 188        uint32_t hclk_val, vddio_val;
 189        int ret;
 190
 191        mxs_ocotp_clear_error();
 192
 193        /* Make sure the banks are closed for reading. */
 194        ret = mxs_ocotp_read_bank_open(0);
 195        if (ret) {
 196                puts("Failed closing banks for reading!\n");
 197                return ret;
 198        }
 199
 200        ret = mxs_ocotp_scale_hclk(1, &hclk_val);
 201        if (ret) {
 202                puts("Failed scaling down the HCLK!\n");
 203                return ret;
 204        }
 205        mxs_ocotp_scale_vddio(1, &vddio_val);
 206
 207        ret = mxs_ocotp_wait_busy_clear();
 208        if (ret) {
 209                puts("Failed waiting for ready state!\n");
 210                goto fail;
 211        }
 212
 213        /* Program the fuse address */
 214        writel(addr | OCOTP_CTRL_WR_UNLOCK_KEY, &ocotp_regs->hw_ocotp_ctrl);
 215
 216        /* Program the data. */
 217        writel(mask, &ocotp_regs->hw_ocotp_data);
 218
 219        udelay(10);
 220
 221        ret = mxs_ocotp_wait_busy_clear();
 222        if (ret) {
 223                puts("Failed waiting for ready state!\n");
 224                goto fail;
 225        }
 226
 227        /* Check for errors */
 228        if (readl(&ocotp_regs->hw_ocotp_ctrl) & OCOTP_CTRL_ERROR) {
 229                puts("Failed writing fuses!\n");
 230                ret = -EPERM;
 231                goto fail;
 232        }
 233
 234fail:
 235        mxs_ocotp_scale_vddio(0, &vddio_val);
 236        if (mxs_ocotp_scale_hclk(0, &hclk_val))
 237                puts("Failed scaling up the HCLK!\n");
 238
 239        return ret;
 240}
 241
 242static int mxs_ocotp_read_fuse(uint32_t reg, uint32_t *val)
 243{
 244        int ret;
 245
 246        /* Register offset from CUST0 */
 247        reg = ((uint32_t)&ocotp_regs->hw_ocotp_cust0) + (reg << 4);
 248
 249        ret = mxs_ocotp_wait_busy_clear();
 250        if (ret) {
 251                puts("Failed waiting for ready state!\n");
 252                return ret;
 253        }
 254
 255        mxs_ocotp_clear_error();
 256
 257        ret = mxs_ocotp_read_bank_open(1);
 258        if (ret) {
 259                puts("Failed opening banks for reading!\n");
 260                return ret;
 261        }
 262
 263        *val = readl(reg);
 264
 265        ret = mxs_ocotp_read_bank_open(0);
 266        if (ret) {
 267                puts("Failed closing banks for reading!\n");
 268                return ret;
 269        }
 270
 271        return ret;
 272}
 273
 274static int mxs_ocotp_valid(u32 bank, u32 word)
 275{
 276        if (bank > 4)
 277                return -EINVAL;
 278        if (word > 7)
 279                return -EINVAL;
 280        return 0;
 281}
 282
 283/*
 284 * The 'fuse' command API
 285 */
 286int fuse_read(u32 bank, u32 word, u32 *val)
 287{
 288        int ret;
 289
 290        ret = mxs_ocotp_valid(bank, word);
 291        if (ret)
 292                return ret;
 293
 294        return mxs_ocotp_read_fuse((bank << 3) | word, val);
 295}
 296
 297int fuse_prog(u32 bank, u32 word, u32 val)
 298{
 299        int ret;
 300
 301        ret = mxs_ocotp_valid(bank, word);
 302        if (ret)
 303                return ret;
 304
 305        return mxs_ocotp_write_fuse((bank << 3) | word, val);
 306}
 307
 308int fuse_sense(u32 bank, u32 word, u32 *val)
 309{
 310        /* We do not support sensing :-( */
 311        return -EINVAL;
 312}
 313
 314int fuse_override(u32 bank, u32 word, u32 val)
 315{
 316        /* We do not support overriding :-( */
 317        return -EINVAL;
 318}
 319