]>
Commit | Line | Data |
---|---|---|
f51cdaf1 | 1 | /* |
f133796d | 2 | * Copyright 2010-2011 Freescale Semiconductor, Inc. |
f51cdaf1 | 3 | * |
5b8031cc | 4 | * SPDX-License-Identifier: GPL-2.0 |
f51cdaf1 BB |
5 | */ |
6 | ||
7 | #include <common.h> | |
8 | #include <asm/fsl_lbc.h> | |
9 | ||
38dba0c2 BB |
10 | #ifdef CONFIG_MPC85xx |
11 | /* Boards should provide their own version of this if they use lbc sdram */ | |
2ed2e912 | 12 | static void __lbc_sdram_init(void) |
38dba0c2 BB |
13 | { |
14 | /* Do nothing */ | |
15 | } | |
70961ba4 | 16 | void lbc_sdram_init(void) __attribute__((weak, alias("__lbc_sdram_init"))); |
38dba0c2 BB |
17 | #endif |
18 | ||
19 | ||
f51cdaf1 BB |
20 | void print_lbc_regs(void) |
21 | { | |
22 | int i; | |
23 | ||
24 | printf("\nLocal Bus Controller Registers\n"); | |
25 | for (i = 0; i < 8; i++) { | |
26 | printf("BR%d\t0x%08X\tOR%d\t0x%08X\n", | |
27 | i, get_lbc_br(i), i, get_lbc_or(i)); | |
28 | } | |
3dc23c7c PG |
29 | printf("LBCR\t0x%08X\tLCRR\t0x%08X\n", |
30 | get_lbc_lbcr(), get_lbc_lcrr()); | |
f51cdaf1 BB |
31 | } |
32 | ||
33 | void init_early_memctl_regs(void) | |
34 | { | |
35 | uint init_br1 = 1; | |
36 | ||
f133796d KG |
37 | #ifdef CONFIG_SYS_FSL_ERRATUM_ELBC_A001 |
38 | /* Set the local bus monitor timeout value to the maximum */ | |
39 | clrsetbits_be32(&(LBC_BASE_ADDR)->lbcr, LBCR_BMT|LBCR_BMTPS, 0xf); | |
40 | #endif | |
41 | ||
f51cdaf1 BB |
42 | #ifdef CONFIG_MPC85xx |
43 | /* if cs1 is already set via debugger, leave cs0/cs1 alone */ | |
44 | if (get_lbc_br(1) & BR_V) | |
45 | init_br1 = 0; | |
46 | #endif | |
47 | ||
48 | /* | |
49 | * Map banks 0 (and maybe 1) to the FLASH banks 0 (and 1) at | |
50 | * preliminary addresses - these have to be modified later | |
51 | * when FLASH size has been determined | |
52 | */ | |
53 | #if defined(CONFIG_SYS_OR0_REMAP) | |
54 | set_lbc_or(0, CONFIG_SYS_OR0_REMAP); | |
55 | #endif | |
56 | #if defined(CONFIG_SYS_OR1_REMAP) | |
57 | set_lbc_or(1, CONFIG_SYS_OR1_REMAP); | |
58 | #endif | |
59 | /* now restrict to preliminary range */ | |
60 | if (init_br1) { | |
9829feff | 61 | #if defined(CONFIG_SYS_BR0_PRELIM) && defined(CONFIG_SYS_OR0_PRELIM) |
f51cdaf1 BB |
62 | set_lbc_br(0, CONFIG_SYS_BR0_PRELIM); |
63 | set_lbc_or(0, CONFIG_SYS_OR0_PRELIM); | |
9829feff | 64 | #endif |
f51cdaf1 BB |
65 | |
66 | #if defined(CONFIG_SYS_BR1_PRELIM) && defined(CONFIG_SYS_OR1_PRELIM) | |
67 | set_lbc_or(1, CONFIG_SYS_OR1_PRELIM); | |
68 | set_lbc_br(1, CONFIG_SYS_BR1_PRELIM); | |
69 | #endif | |
70 | } | |
71 | ||
72 | #if defined(CONFIG_SYS_BR2_PRELIM) && defined(CONFIG_SYS_OR2_PRELIM) | |
73 | set_lbc_or(2, CONFIG_SYS_OR2_PRELIM); | |
74 | set_lbc_br(2, CONFIG_SYS_BR2_PRELIM); | |
75 | #endif | |
76 | ||
77 | #if defined(CONFIG_SYS_BR3_PRELIM) && defined(CONFIG_SYS_OR3_PRELIM) | |
78 | set_lbc_or(3, CONFIG_SYS_OR3_PRELIM); | |
79 | set_lbc_br(3, CONFIG_SYS_BR3_PRELIM); | |
80 | #endif | |
81 | ||
82 | #if defined(CONFIG_SYS_BR4_PRELIM) && defined(CONFIG_SYS_OR4_PRELIM) | |
83 | set_lbc_or(4, CONFIG_SYS_OR4_PRELIM); | |
84 | set_lbc_br(4, CONFIG_SYS_BR4_PRELIM); | |
85 | #endif | |
86 | ||
87 | #if defined(CONFIG_SYS_BR5_PRELIM) && defined(CONFIG_SYS_OR5_PRELIM) | |
88 | set_lbc_or(5, CONFIG_SYS_OR5_PRELIM); | |
89 | set_lbc_br(5, CONFIG_SYS_BR5_PRELIM); | |
90 | #endif | |
91 | ||
92 | #if defined(CONFIG_SYS_BR6_PRELIM) && defined(CONFIG_SYS_OR6_PRELIM) | |
93 | set_lbc_or(6, CONFIG_SYS_OR6_PRELIM); | |
94 | set_lbc_br(6, CONFIG_SYS_BR6_PRELIM); | |
95 | #endif | |
96 | ||
97 | #if defined(CONFIG_SYS_BR7_PRELIM) && defined(CONFIG_SYS_OR7_PRELIM) | |
98 | set_lbc_or(7, CONFIG_SYS_OR7_PRELIM); | |
99 | set_lbc_br(7, CONFIG_SYS_BR7_PRELIM); | |
100 | #endif | |
101 | } | |
f2d9a5da BB |
102 | |
103 | /* | |
104 | * Configures a UPM. The function requires the respective MxMR to be set | |
105 | * before calling this function. "size" is the number or entries, not a sizeof. | |
106 | */ | |
107 | void upmconfig(uint upm, uint *table, uint size) | |
108 | { | |
109 | fsl_lbc_t *lbc = LBC_BASE_ADDR; | |
e55d637a | 110 | int i, mad, old_mad = 0; |
f2d9a5da BB |
111 | u32 mask = (~MxMR_OP_MSK & ~MxMR_MAD_MSK); |
112 | u32 msel = BR_UPMx_TO_MSEL(upm); | |
113 | u32 *mxmr = &lbc->mamr + upm; | |
114 | volatile u8 *dummy = NULL; | |
115 | ||
116 | if (upm < UPMA || upm > UPMC) { | |
117 | printf("Error: %s() Bad UPM index %d\n", __func__, upm); | |
118 | hang(); | |
119 | } | |
120 | ||
121 | /* | |
122 | * Find the address for the dummy write - scan all of the BRs until we | |
123 | * find one matching the UPM and extract the base address bits from it. | |
124 | */ | |
125 | for (i = 0; i < 8; i++) { | |
126 | if ((get_lbc_br(i) & (BR_V | BR_MSEL)) == (BR_V | msel)) { | |
127 | dummy = (volatile u8 *)(get_lbc_br(i) & BR_BA); | |
128 | break; | |
129 | } | |
130 | } | |
131 | ||
132 | if (!dummy) { | |
133 | printf("Error: %s() No matching BR\n", __func__); | |
134 | hang(); | |
135 | } | |
136 | ||
137 | /* Program UPM using steps outlined by the reference manual */ | |
138 | for (i = 0; i < size; i++) { | |
139 | out_be32(mxmr, (in_be32(mxmr) & mask) | MxMR_OP_WARR | i); | |
140 | out_be32(&lbc->mdr, table[i]); | |
e55d637a | 141 | (void)in_be32(&lbc->mdr); |
f2d9a5da BB |
142 | *dummy = 0; |
143 | do { | |
144 | mad = in_be32(mxmr) & MxMR_MAD_MSK; | |
145 | } while (mad <= old_mad && !(!mad && i == (size-1))); | |
146 | old_mad = mad; | |
147 | } | |
148 | ||
149 | /* Return to normal operation */ | |
150 | out_be32(mxmr, (in_be32(mxmr) & mask) | MxMR_OP_NORM); | |
151 | } |