1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 * See "LICENSE_GPLv2.txt" for details. 9 * 10 * @TAG(DATA61_GPL) 11 */ 12 13/* Author Alex Kroh */ 14#include "ocotp_ctrl.h" 15#include <assert.h> 16#include <stdio.h> 17#include <utils/util.h> 18#include "unimplemented.h" 19 20/* 21 * NOTE: ocotp clock is sources by ipg_clk but must be gated 22 * CCM_CGR2[CG6] 23 */ 24 25#ifdef CONFIG_PLAT_IMX6 26#define IMX6_OCOTP_PADDR 0x021BC000 27#define IMX6_OCOTP_SIZE 0x00004000 28#endif 29#ifdef CONFIG_PLAT_IMX8MQ_EVK 30#define IMX6_OCOTP_PADDR 0x30350000 31#define IMX6_OCOTP_SIZE 0x00010000 32#endif 33 34#define TIMING_WAIT(x) ((x) << 22) 35#define TIMING_SREAD(x) ((x) << 16) 36#define TIMING_RELAX(x) ((x) << 12) 37#define TIMING_SPROG(x) ((x) << 0) 38#define TIMING_WAIT_MAX 0x03f 39#define TIMING_SREAD_MAX 0x03f 40#define TIMING_RELAX_MAX 0x00f 41#define TIMING_SPROG_MAX 0xfff 42 43#define CTRL_UNLOCK_KEY (0x3E77 << 16) 44#define CTRL_RELOAD_SHADOWS BIT(10) 45#define CTRL_ERROR BIT(9) 46#define CTRL_BUSY BIT(8) 47#define CTRL_ADDR(x) ((x) << 0) 48 49#define LOCK_FUSE BIT(0) 50#define LOCK_SHADOW BIT(1) 51#define LOCK_ANALOG(x) ((x) << 18) 52#define LOCK_GP2(x) ((x) << 12) 53#define LOCK_CP1(x) ((x) << 10) 54#define LOCK_MAC(x) ((x) << 8) 55#define LOCK_MEMTRIM(x) ((x) << 4) 56#define LOCK_BOOTCFG(x) ((x) << 2) 57#define LOCK_TESTER(x) ((x) << 0) 58 59#define FADDR_LOCK 0x00 60#define FADDR_MAC0 0x22 61#define FADDR_MAC1 0x23 62 63struct ocotp_regs { 64 uint32_t ctrl; /* 000 */ 65 uint32_t ctrl_set; /* 004 */ 66 uint32_t ctrl_clr; /* 008 */ 67 uint32_t ctrl_tog; /* 00C */ 68 uint32_t timing; /* 010 */ 69 uint32_t res1[3]; /* 014 */ 70 uint32_t data; /* 020 */ 71 uint32_t res2[3]; /* 024 */ 72 uint32_t read_ctrl; /* 030 */ 73 uint32_t res3[3]; /* 034 */ 74 uint32_t read_fuse_data; /* 040 */ 75 uint32_t res4[3]; /* 044 */ 76 uint32_t sw_sticky; /* 050 */ 77 uint32_t res5[3]; /* 054 */ 78 uint32_t scs; /* 060 */ 79 uint32_t scs_set; /* 064 */ 80 uint32_t scs_clr; /* 068 */ 81 uint32_t scs_tog; /* 06C */ 82 uint32_t res6[8]; /* 070 */ 83 uint32_t ver; /* 090 */ 84 uint32_t res7[219]; /* 094 */ 85 /* Bank 0 */ 86 uint32_t lock; /* 400 */ 87 uint32_t res8[3]; 88 uint32_t cfg0; /* 410 */ 89 uint32_t res9[3]; 90 uint32_t cfg1; /* 420 */ 91 uint32_t res10[3]; 92 uint32_t cfg2; /* 430 */ 93 uint32_t res11[3]; 94 uint32_t cfg3; /* 440 */ 95 uint32_t res12[3]; 96 uint32_t cfg4; /* 450 */ 97 uint32_t res13[3]; 98 uint32_t cfg5; /* 460 */ 99 uint32_t res14[3]; 100 uint32_t cfg6; /* 470 */ 101 uint32_t res15[3]; 102 /* Bank 1 */ 103 uint32_t mem0; /* 480 */ 104 uint32_t res16[3]; 105 uint32_t mem1; /* 490 */ 106 uint32_t res17[3]; 107 uint32_t mem2; /* 4A0 */ 108 uint32_t res18[3]; 109 uint32_t mem3; /* 4B0 */ 110 uint32_t res19[3]; 111 uint32_t mem4; /* 4C0 */ 112 uint32_t res20[3]; 113 uint32_t ana0; /* 4D0 */ 114 uint32_t res21[3]; 115 uint32_t ana1; /* 4E0 */ 116 uint32_t res22[3]; 117 uint32_t ana2; /* 4F0 */ 118 uint32_t res23[3]; 119 uint32_t res24[32]; /* 500 */ 120 /* Bank 3 shadow */ 121 uint32_t srk0; /* 580 */ 122 uint32_t res25[3]; 123 uint32_t srk1; /* 590 */ 124 uint32_t res26[3]; 125 uint32_t srk2; /* 5A0 */ 126 uint32_t res27[3]; 127 uint32_t srk3; /* 5B0 */ 128 uint32_t res28[3]; 129 uint32_t srk4; /* 5C0 */ 130 uint32_t res29[3]; 131 uint32_t srk5; /* 5D0 */ 132 uint32_t res30[3]; 133 uint32_t srk6; /* 5E0 */ 134 uint32_t res31[3]; 135 uint32_t srk7; /* 5F0 */ 136 uint32_t res32[3]; 137 /* Bank 4 */ 138 uint32_t resp0; /* 600 */ 139 uint32_t res33[3]; 140 uint32_t hsjc_resp1; /* 610 */ 141 uint32_t res34[3]; 142 uint32_t mac0; /* 620 */ 143 uint32_t res35[3]; 144 uint32_t mac1; /* 630 */ 145 uint32_t res36[3]; 146 uint32_t res37[8]; 147 uint32_t gp0; /* 660 */ 148 uint32_t res38[3]; 149 uint32_t gp1; /* 670 */ 150 uint32_t res39[3]; 151 uint32_t res40[20]; 152 /* Bank 5 */ 153 uint32_t misc_conf; /* 6D0 */ 154 uint32_t res41[3]; 155 uint32_t field_return; /* 6E0 */ 156 uint32_t res42[3]; 157 uint32_t srk_revoke; /* 6F0 */ 158 uint32_t res43[3]; 159}; 160 161struct ocotp { 162 int dummy; 163}; 164 165typedef volatile struct ocotp_regs ocotp_regs_t; 166 167static inline ocotp_regs_t *ocotp_get_regs(struct ocotp *ocotp) 168{ 169 return (ocotp_regs_t *)ocotp; 170} 171 172struct ocotp * 173ocotp_init(ps_io_mapper_t *io_mapper) 174{ 175 return (struct ocotp *)RESOURCE(io_mapper, IMX6_OCOTP); 176} 177 178void ocotp_free(struct ocotp *ocotp, ps_io_mapper_t *io_mapper) 179{ 180 UNRESOURCE(io_mapper, IMX6_OCOTP, ocotp); 181} 182 183int ocotp_get_mac(struct ocotp *ocotp, unsigned char *mac) 184{ 185 ocotp_regs_t *regs; 186 uint32_t mac0; 187 uint32_t mac1; 188 assert(ocotp); 189 190 regs = ocotp_get_regs(ocotp); 191 mac0 = regs->mac0; 192 mac1 = regs->mac1; 193 if (mac0 | mac1) { 194 mac[0] = (mac1 >> 8) & 0xff; 195 mac[1] = (mac1 >> 0) & 0xff; 196 197 mac[2] = (mac0 >> 24) & 0xff; 198 mac[3] = (mac0 >> 16) & 0xff; 199 mac[4] = (mac0 >> 8) & 0xff; 200 mac[5] = (mac0 >> 0) & 0xff; 201 return 0; 202 } else { 203 return -1; 204 } 205} 206