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