~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/arch/arm/cpu/arm926ejs/orion5x/cpu.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net>
 
3
 *
 
4
 * Based on original Kirkwood support which is
 
5
 * (C) Copyright 2009
 
6
 * Marvell Semiconductor <www.marvell.com>
 
7
 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
 
8
 *
 
9
 * SPDX-License-Identifier:     GPL-2.0+
 
10
 */
 
11
 
 
12
#include <common.h>
 
13
#include <netdev.h>
 
14
#include <asm/cache.h>
 
15
#include <asm/io.h>
 
16
#include <u-boot/md5.h>
 
17
#include <asm/arch/cpu.h>
 
18
#include <hush.h>
 
19
 
 
20
#define BUFLEN  16
 
21
 
 
22
void reset_cpu(unsigned long ignored)
 
23
{
 
24
        struct orion5x_cpu_registers *cpureg =
 
25
            (struct orion5x_cpu_registers *)ORION5X_CPU_REG_BASE;
 
26
 
 
27
        writel(readl(&cpureg->rstoutn_mask) | (1 << 2),
 
28
                &cpureg->rstoutn_mask);
 
29
        writel(readl(&cpureg->sys_soft_rst) | 1,
 
30
                &cpureg->sys_soft_rst);
 
31
        while (1)
 
32
                ;
 
33
}
 
34
 
 
35
/*
 
36
 * Compute Window Size field value from size expressed in bytes
 
37
 * Used with the Base register to set the address window size and location.
 
38
 * Must be programmed from LSB to MSB as sequence of ones followed by
 
39
 * sequence of zeros. The number of ones specifies the size of the window in
 
40
 * 64 KiB granularity (e.g., a value of 0x00FF specifies 256 = 16 MiB).
 
41
 * NOTES:
 
42
 * 1) A sizeval equal to 0x0 specifies 4 GiB.
 
43
 * 2) A return value of 0x0 specifies 64 KiB.
 
44
 */
 
45
unsigned int orion5x_winctrl_calcsize(unsigned int sizeval)
 
46
{
 
47
        /*
 
48
         * Calculate the number of 64 KiB blocks needed minus one (rounding up).
 
49
         * For sizeval > 0 this is equivalent to:
 
50
         * sizeval = (u32) ceil((double) sizeval / 65536.0) - 1
 
51
         */
 
52
        sizeval = (sizeval - 1) >> 16;
 
53
 
 
54
        /*
 
55
         * Propagate 'one' bits to the right by 'oring' them.
 
56
         * We need only treat bits 15-0.
 
57
         */
 
58
        sizeval |= sizeval >> 1;  /* 'Or' bit 15 onto bit 14 */
 
59
        sizeval |= sizeval >> 2;  /* 'Or' bits 15-14 onto bits 13-12 */
 
60
        sizeval |= sizeval >> 4;  /* 'Or' bits 15-12 onto bits 11-8 */
 
61
        sizeval |= sizeval >> 8;  /* 'Or' bits 15-8 onto bits 7-0*/
 
62
 
 
63
        return sizeval;
 
64
}
 
65
 
 
66
/*
 
67
 * orion5x_config_adr_windows - Configure address Windows
 
68
 *
 
69
 * There are 8 address windows supported by Orion5x Soc to addess different
 
70
 * devices. Each window can be configured for size, BAR and remap addr
 
71
 * Below configuration is standard for most of the cases
 
72
 *
 
73
 * If remap function not used, remap_lo must be set as base
 
74
 *
 
75
 * NOTES:
 
76
 *
 
77
 * 1) in order to avoid windows with inconsistent control and base values
 
78
 *    (which could prevent access to BOOTCS and hence execution from FLASH)
 
79
 *    always disable window before writing the base value then reenable it
 
80
 *    by writing the control value.
 
81
 *
 
82
 * 2) in order to avoid losing access to BOOTCS when disabling window 7,
 
83
 *    first configure window 6 for BOOTCS, then configure window 7 for BOOTCS,
 
84
 *    then configure windows 6 for its own target.
 
85
 *
 
86
 * Reference Documentation:
 
87
 * Mbus-L to Mbus Bridge Registers Configuration.
 
88
 * (Sec 25.1 and 25.3 of Datasheet)
 
89
 */
 
90
int orion5x_config_adr_windows(void)
 
91
{
 
92
        struct orion5x_win_registers *winregs =
 
93
                (struct orion5x_win_registers *)ORION5X_CPU_WIN_BASE;
 
94
 
 
95
/* Disable window 0, configure it for its intended target, enable it. */
 
96
        writel(0, &winregs[0].ctrl);
 
97
        writel(ORION5X_ADR_PCIE_MEM, &winregs[0].base);
 
98
        writel(ORION5X_ADR_PCIE_MEM_REMAP_LO, &winregs[0].remap_lo);
 
99
        writel(ORION5X_ADR_PCIE_MEM_REMAP_HI, &winregs[0].remap_hi);
 
100
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCIE_MEM,
 
101
                ORION5X_TARGET_PCIE, ORION5X_ATTR_PCIE_MEM,
 
102
                ORION5X_WIN_ENABLE), &winregs[0].ctrl);
 
103
/* Disable window 1, configure it for its intended target, enable it. */
 
104
        writel(0, &winregs[1].ctrl);
 
105
        writel(ORION5X_ADR_PCIE_IO, &winregs[1].base);
 
106
        writel(ORION5X_ADR_PCIE_IO_REMAP_LO, &winregs[1].remap_lo);
 
107
        writel(ORION5X_ADR_PCIE_IO_REMAP_HI, &winregs[1].remap_hi);
 
108
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCIE_IO,
 
109
                ORION5X_TARGET_PCIE, ORION5X_ATTR_PCIE_IO,
 
110
                ORION5X_WIN_ENABLE), &winregs[1].ctrl);
 
111
/* Disable window 2, configure it for its intended target, enable it. */
 
112
        writel(0, &winregs[2].ctrl);
 
113
        writel(ORION5X_ADR_PCI_MEM, &winregs[2].base);
 
114
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCI_MEM,
 
115
                ORION5X_TARGET_PCI, ORION5X_ATTR_PCI_MEM,
 
116
                ORION5X_WIN_ENABLE), &winregs[2].ctrl);
 
117
/* Disable window 3, configure it for its intended target, enable it. */
 
118
        writel(0, &winregs[3].ctrl);
 
119
        writel(ORION5X_ADR_PCI_IO, &winregs[3].base);
 
120
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCI_IO,
 
121
                ORION5X_TARGET_PCI, ORION5X_ATTR_PCI_IO,
 
122
                ORION5X_WIN_ENABLE), &winregs[3].ctrl);
 
123
/* Disable window 4, configure it for its intended target, enable it. */
 
124
        writel(0, &winregs[4].ctrl);
 
125
        writel(ORION5X_ADR_DEV_CS0, &winregs[4].base);
 
126
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS0,
 
127
                ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS0,
 
128
                ORION5X_WIN_ENABLE), &winregs[4].ctrl);
 
129
/* Disable window 5, configure it for its intended target, enable it. */
 
130
        writel(0, &winregs[5].ctrl);
 
131
        writel(ORION5X_ADR_DEV_CS1, &winregs[5].base);
 
132
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS1,
 
133
                ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS1,
 
134
                ORION5X_WIN_ENABLE), &winregs[5].ctrl);
 
135
/* Disable window 6, configure it for FLASH, enable it. */
 
136
        writel(0, &winregs[6].ctrl);
 
137
        writel(ORION5X_ADR_BOOTROM, &winregs[6].base);
 
138
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_BOOTROM,
 
139
                ORION5X_TARGET_DEVICE, ORION5X_ATTR_BOOTROM,
 
140
                ORION5X_WIN_ENABLE), &winregs[6].ctrl);
 
141
/* Disable window 7, configure it for FLASH, enable it. */
 
142
        writel(0, &winregs[7].ctrl);
 
143
        writel(ORION5X_ADR_BOOTROM, &winregs[7].base);
 
144
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_BOOTROM,
 
145
                ORION5X_TARGET_DEVICE, ORION5X_ATTR_BOOTROM,
 
146
                ORION5X_WIN_ENABLE), &winregs[7].ctrl);
 
147
/* Disable window 6, configure it for its intended target, enable it. */
 
148
        writel(0, &winregs[6].ctrl);
 
149
        writel(ORION5X_ADR_DEV_CS2, &winregs[6].base);
 
150
        writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS2,
 
151
                ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS2,
 
152
                ORION5X_WIN_ENABLE), &winregs[6].ctrl);
 
153
 
 
154
        return 0;
 
155
}
 
156
 
 
157
/*
 
158
 * Orion5x identification is done through PCIE space.
 
159
 */
 
160
 
 
161
u32 orion5x_device_id(void)
 
162
{
 
163
        return readl(PCIE_DEV_ID_OFF) >> 16;
 
164
}
 
165
 
 
166
u32 orion5x_device_rev(void)
 
167
{
 
168
        return readl(PCIE_DEV_REV_OFF) & 0xff;
 
169
}
 
170
 
 
171
#if defined(CONFIG_DISPLAY_CPUINFO)
 
172
 
 
173
/* Display device and revision IDs.
 
174
 * This function must cover all known device/revision
 
175
 * combinations, not only the one for which u-boot is
 
176
 * compiled; this way, one can identify actual HW in
 
177
 * case of a mismatch.
 
178
 */
 
179
int print_cpuinfo(void)
 
180
{
 
181
        char dev_str[7]; /* room enough for 0x0000 plus null byte */
 
182
        char rev_str[5]; /* room enough for 0x00 plus null byte */
 
183
        char *dev_name = NULL;
 
184
        char *rev_name = NULL;
 
185
 
 
186
        u32 dev = orion5x_device_id();
 
187
        u32 rev = orion5x_device_rev();
 
188
 
 
189
        if (dev == MV88F5181_DEV_ID) {
 
190
                dev_name = "MV88F5181";
 
191
                if (rev == MV88F5181_REV_B1)
 
192
                        rev_name = "B1";
 
193
                else if (rev == MV88F5181L_REV_A1) {
 
194
                        dev_name = "MV88F5181L";
 
195
                        rev_name = "A1";
 
196
                } else if (rev == MV88F5181L_REV_A0) {
 
197
                        dev_name = "MV88F5181L";
 
198
                        rev_name = "A0";
 
199
                }
 
200
        } else if (dev == MV88F5182_DEV_ID) {
 
201
                dev_name = "MV88F5182";
 
202
                if (rev == MV88F5182_REV_A2)
 
203
                        rev_name = "A2";
 
204
        } else if (dev == MV88F5281_DEV_ID) {
 
205
                dev_name = "MV88F5281";
 
206
                if (rev == MV88F5281_REV_D2)
 
207
                        rev_name = "D2";
 
208
                else if (rev == MV88F5281_REV_D1)
 
209
                        rev_name = "D1";
 
210
                else if (rev == MV88F5281_REV_D0)
 
211
                        rev_name = "D0";
 
212
        } else if (dev == MV88F6183_DEV_ID) {
 
213
                dev_name = "MV88F6183";
 
214
                if (rev == MV88F6183_REV_B0)
 
215
                        rev_name = "B0";
 
216
        }
 
217
        if (dev_name == NULL) {
 
218
                sprintf(dev_str, "0x%04x", dev);
 
219
                dev_name = dev_str;
 
220
        }
 
221
        if (rev_name == NULL) {
 
222
                sprintf(rev_str, "0x%02x", rev);
 
223
                rev_name = rev_str;
 
224
        }
 
225
 
 
226
        printf("SoC:   Orion5x %s-%s\n", dev_name, rev_name);
 
227
 
 
228
        return 0;
 
229
}
 
230
#endif /* CONFIG_DISPLAY_CPUINFO */
 
231
 
 
232
#ifdef CONFIG_ARCH_CPU_INIT
 
233
int arch_cpu_init(void)
 
234
{
 
235
        /* Enable and invalidate L2 cache in write through mode */
 
236
        invalidate_l2_cache();
 
237
 
 
238
        orion5x_config_adr_windows();
 
239
 
 
240
        return 0;
 
241
}
 
242
#endif /* CONFIG_ARCH_CPU_INIT */
 
243
 
 
244
/*
 
245
 * SOC specific misc init
 
246
 */
 
247
#if defined(CONFIG_ARCH_MISC_INIT)
 
248
int arch_misc_init(void)
 
249
{
 
250
        u32 temp;
 
251
 
 
252
        /*CPU streaming & write allocate */
 
253
        temp = readfr_extra_feature_reg();
 
254
        temp &= ~(1 << 28);     /* disable wr alloc */
 
255
        writefr_extra_feature_reg(temp);
 
256
 
 
257
        temp = readfr_extra_feature_reg();
 
258
        temp &= ~(1 << 29);     /* streaming disabled */
 
259
        writefr_extra_feature_reg(temp);
 
260
 
 
261
        /* L2Cache settings */
 
262
        temp = readfr_extra_feature_reg();
 
263
        /* Disable L2C pre fetch - Set bit 24 */
 
264
        temp |= (1 << 24);
 
265
        /* enable L2C - Set bit 22 */
 
266
        temp |= (1 << 22);
 
267
        writefr_extra_feature_reg(temp);
 
268
 
 
269
        icache_enable();
 
270
        /* Change reset vector to address 0x0 */
 
271
        temp = get_cr();
 
272
        set_cr(temp & ~CR_V);
 
273
 
 
274
        /* Set CPIOs and MPPs - values provided by board
 
275
           include file */
 
276
        writel(ORION5X_MPP0_7, ORION5X_MPP_BASE+0x00);
 
277
        writel(ORION5X_MPP8_15, ORION5X_MPP_BASE+0x04);
 
278
        writel(ORION5X_MPP16_23, ORION5X_MPP_BASE+0x50);
 
279
        writel(ORION5X_GPIO_OUT_VALUE, ORION5X_GPIO_BASE+0x00);
 
280
        writel(ORION5X_GPIO_OUT_ENABLE, ORION5X_GPIO_BASE+0x04);
 
281
        writel(ORION5X_GPIO_IN_POLARITY, ORION5X_GPIO_BASE+0x0c);
 
282
 
 
283
        /* initialize timer */
 
284
        timer_init_r();
 
285
        return 0;
 
286
}
 
287
#endif /* CONFIG_ARCH_MISC_INIT */
 
288
 
 
289
#ifdef CONFIG_MVGBE
 
290
int cpu_eth_init(bd_t *bis)
 
291
{
 
292
        mvgbe_initialize(bis);
 
293
        return 0;
 
294
}
 
295
#endif