|
@@ -208,6 +208,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
|
|
u8 __iomem *lbc_lcs0_ba = NULL;
|
|
u8 __iomem *lbc_lcs0_ba = NULL;
|
|
u8 __iomem *lbc_lcs1_ba = NULL;
|
|
u8 __iomem *lbc_lcs1_ba = NULL;
|
|
phys_addr_t cs0_addr, cs1_addr;
|
|
phys_addr_t cs0_addr, cs1_addr;
|
|
|
|
+ u32 br0, or0, br1, or1;
|
|
const __be32 *iprop;
|
|
const __be32 *iprop;
|
|
unsigned int num_laws;
|
|
unsigned int num_laws;
|
|
u8 b;
|
|
u8 b;
|
|
@@ -256,11 +257,70 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
|
|
}
|
|
}
|
|
num_laws = be32_to_cpup(iprop);
|
|
num_laws = be32_to_cpup(iprop);
|
|
|
|
|
|
- cs0_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[0].br));
|
|
|
|
- cs1_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[1].br));
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Indirect mode requires both BR0 and BR1 to be set to "GPCM",
|
|
|
|
+ * otherwise writes to these addresses won't actually appear on the
|
|
|
|
+ * local bus, and so the PIXIS won't see them.
|
|
|
|
+ *
|
|
|
|
+ * In FCM mode, writes go to the NAND controller, which does not pass
|
|
|
|
+ * them to the localbus directly. So we force BR0 and BR1 into GPCM
|
|
|
|
+ * mode, since we don't care about what's behind the localbus any
|
|
|
|
+ * more.
|
|
|
|
+ */
|
|
|
|
+ br0 = in_be32(&lbc->bank[0].br);
|
|
|
|
+ br1 = in_be32(&lbc->bank[1].br);
|
|
|
|
+ or0 = in_be32(&lbc->bank[0].or);
|
|
|
|
+ or1 = in_be32(&lbc->bank[1].or);
|
|
|
|
+
|
|
|
|
+ /* Make sure CS0 and CS1 are programmed */
|
|
|
|
+ if (!(br0 & BR_V) || !(br1 & BR_V)) {
|
|
|
|
+ pr_err("p1022ds: CS0 and/or CS1 is not programmed\n");
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Use the existing BRx/ORx values if it's already GPCM. Otherwise,
|
|
|
|
+ * force the values to simple 32KB GPCM windows with the most
|
|
|
|
+ * conservative timing.
|
|
|
|
+ */
|
|
|
|
+ if ((br0 & BR_MSEL) != BR_MS_GPCM) {
|
|
|
|
+ br0 = (br0 & BR_BA) | BR_V;
|
|
|
|
+ or0 = 0xFFFF8000 | 0xFF7;
|
|
|
|
+ out_be32(&lbc->bank[0].br, br0);
|
|
|
|
+ out_be32(&lbc->bank[0].or, or0);
|
|
|
|
+ }
|
|
|
|
+ if ((br1 & BR_MSEL) != BR_MS_GPCM) {
|
|
|
|
+ br1 = (br1 & BR_BA) | BR_V;
|
|
|
|
+ or1 = 0xFFFF8000 | 0xFF7;
|
|
|
|
+ out_be32(&lbc->bank[1].br, br1);
|
|
|
|
+ out_be32(&lbc->bank[1].or, or1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cs0_addr = lbc_br_to_phys(ecm, num_laws, br0);
|
|
|
|
+ if (!cs0_addr) {
|
|
|
|
+ pr_err("p1022ds: could not determine physical address for CS0"
|
|
|
|
+ " (BR0=%08x)\n", br0);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
+ cs1_addr = lbc_br_to_phys(ecm, num_laws, br1);
|
|
|
|
+ if (!cs0_addr) {
|
|
|
|
+ pr_err("p1022ds: could not determine physical address for CS1"
|
|
|
|
+ " (BR1=%08x)\n", br1);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
|
|
lbc_lcs0_ba = ioremap(cs0_addr, 1);
|
|
lbc_lcs0_ba = ioremap(cs0_addr, 1);
|
|
|
|
+ if (!lbc_lcs0_ba) {
|
|
|
|
+ pr_err("p1022ds: could not ioremap CS0 address %llx\n",
|
|
|
|
+ (unsigned long long)cs0_addr);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
lbc_lcs1_ba = ioremap(cs1_addr, 1);
|
|
lbc_lcs1_ba = ioremap(cs1_addr, 1);
|
|
|
|
+ if (!lbc_lcs1_ba) {
|
|
|
|
+ pr_err("p1022ds: could not ioremap CS1 address %llx\n",
|
|
|
|
+ (unsigned long long)cs1_addr);
|
|
|
|
+ goto exit;
|
|
|
|
+ }
|
|
|
|
|
|
/* Make sure we're in indirect mode first. */
|
|
/* Make sure we're in indirect mode first. */
|
|
if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
|
|
if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
|