PERFORCE change 150333 for review
Rafal Jaworowski
raj at FreeBSD.org
Tue Sep 23 09:27:40 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=150333
Change 150333 by raj at raj_mimi on 2008/09/23 09:27:25
Move IDMA decode windows routines to common area, provide minimal decode
table for Discovery.
Affected files ...
.. //depot/projects/arm/src/sys/arm/mv/common.c#4 edit
.. //depot/projects/arm/src/sys/arm/mv/discovery/discovery.c#2 edit
.. //depot/projects/arm/src/sys/arm/mv/orion/orion.c#3 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/mv/common.c#4 (text+ko) ====
@@ -189,26 +189,16 @@
soc_id(&dev, &rev);
if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
- decode_win_eth_valid() != 1)
- return (-1);
-
-#if defined(SOC_MV_ORION)
- if (decode_win_idma_valid() != 1)
- return (-1);
-#endif
- if (decode_win_pcie_valid() != 1)
+ decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
+ decode_win_pcie_valid() != 1)
return(-1);
decode_win_cpu_setup();
decode_win_usb_setup(MV_USB0_BASE);
-
decode_win_eth_setup(MV_ETH0_BASE);
-#if defined(SOC_MV_DISCOVERY)
- decode_win_eth_setup(MV_ETH1_BASE);
-#endif
-#if defined(SOC_MV_ORION)
+ if (dev == MV_DEV_MV78100)
+ decode_win_eth_setup(MV_ETH1_BASE);
decode_win_idma_setup();
-#endif
decode_win_pcie_setup(MV_PCIE_BASE);
/* TODO set up decode wins for SATA */
@@ -255,6 +245,17 @@
WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
+WIN_REG_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
+WIN_REG_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
+WIN_REG_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
+WIN_REG_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
+WIN_REG_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
+WIN_REG_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
+WIN_REG_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
+WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
+WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
+WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
+
/**************************************************************************
* Decode windows helper routines
**************************************************************************/
@@ -316,10 +317,11 @@
win_cpu_can_remap(int i)
{
- /* Depending on the SoC windows 0-1, or 0-3 have remap capability */
+ /* Depending on the SoC certain windows have remap capability */
if ((dev == MV_DEV_88F5182 && i < 2) ||
(dev == MV_DEV_88F5281 && i < 4) ||
- (dev == MV_DEV_88F6281 && i < 4))
+ (dev == MV_DEV_88F6281 && i < 4) ||
+ (dev == MV_DEV_MV78100 && i < 8))
return (1);
return (0);
@@ -382,8 +384,10 @@
b = cpu_wins[i].base;
e = b + s - 1;
if (s > (0xFFFFFFFF - b + 1)) {
- /* XXX this boundary check should accont for 64bit and
- * remapping.. */
+ /*
+ * XXX this boundary check should account for 64bit
+ * and remapping..
+ */
printf("CPU window#%d: no space for size 0x%08x at "
"0x%08x\n", i, s, b);
rv = 0;
@@ -543,7 +547,7 @@
win_usb_br_write(i, 0);
}
- /* Only access to active DRAM banks is required. */
+ /* Only access to active DRAM banks is required */
for (i = 0; i < MV_WIN_DDR_MAX; i++)
if (ddr_is_active(i)) {
br = ddr_base(i);
@@ -631,7 +635,7 @@
win_eth_har_write(base, i, 0);
}
- /* Only access to active DRAM banks is required. */
+ /* Only access to active DRAM banks is required */
for (i = 0; i < MV_WIN_DDR_MAX; i++)
if (ddr_is_active(i)) {
@@ -687,13 +691,13 @@
for (i = 0; i < MV_WIN_DDR_MAX; i++) {
if (ddr_is_active(i)) {
- /* We map DDR to BAR 1 */
+ /* Map DDR to BAR 1 */
cr = (ddr_size(i) - 1) & 0xffff0000;
- size += cr + 0x10000;
+ size += ddr_size(i) & 0xffff0000;
cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
br = ddr_base(i);
- /* Set the first free PCIE window */
+ /* Use the first available PCIE window */
for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
if (win_pcie_cr_read(base, j) != 0)
continue;
@@ -705,6 +709,11 @@
}
}
+ /*
+ * Upper 16 bits in BAR register is interpreted as BAR size
+ * (in 64 kB units) plus 64kB, so substract 0x10000
+ * form value passed to register to get correct value.
+ */
size -= 0x10000;
pcie_bar_write(base, 0, size | 1);
}
@@ -715,3 +724,239 @@
return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
}
+
+/**************************************************************************
+ * IDMA windows routines
+ **************************************************************************/
+#if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
+static int
+idma_bare_read(int i)
+{
+ uint32_t v;
+
+ v = win_idma_bare_read();
+ v &= (1 << i);
+
+ return (v >> i);
+}
+
+static void
+idma_bare_write(int i, int val)
+{
+ uint32_t v;
+
+ v = win_idma_bare_read();
+ v &= ~(1 << i);
+ v |= (val << i);
+ win_idma_bare_write(v);
+}
+
+/*
+ * Sets channel protection 'val' for window 'w' on channel 'c'
+ */
+static void
+idma_cap_write(int c, int w, int val)
+{
+ uint32_t v;
+
+ v = win_idma_cap_read(c);
+ v &= ~(0x3 << (w * 2));
+ v |= (val << (w * 2));
+ win_idma_cap_write(c, v);
+}
+
+/*
+ * Set protection 'val' on all channels for window 'w'
+ */
+static void
+idma_set_prot(int w, int val)
+{
+ int c;
+
+ for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
+ idma_cap_write(c, w, val);
+}
+
+static int
+win_idma_can_remap(int i)
+{
+
+ /* IDMA decode windows 0-3 have remap capability */
+ if (i < 4)
+ return (1);
+
+ return (0);
+}
+
+void
+decode_win_idma_setup(void)
+{
+ uint32_t br, sz;
+ int i, j;
+
+ /*
+ * Disable and clear all IDMA windows, revoke protection for all channels
+ */
+ for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
+
+ idma_bare_write(i, 1);
+ win_idma_br_write(i, 0);
+ win_idma_sz_write(i, 0);
+ if (win_idma_can_remap(i) == 1)
+ win_idma_har_write(i, 0);
+ }
+ for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
+ win_idma_cap_write(i, 0);
+
+ /*
+ * Set up access to all active DRAM banks
+ */
+ for (i = 0; i < MV_WIN_DDR_MAX; i++)
+ if (ddr_is_active(i)) {
+ br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
+ sz = ((ddr_size(i) - 1) & 0xffff0000);
+
+ /* Place DDR entries in non-remapped windows */
+ for (j = 0; j < MV_WIN_IDMA_MAX; j++)
+ if (win_idma_can_remap(j) != 1 &&
+ idma_bare_read(j) == 1) {
+
+ /* Configure window */
+ win_idma_br_write(j, br);
+ win_idma_sz_write(j, sz);
+
+ /* Set protection RW on all channels */
+ idma_set_prot(j, 0x3);
+
+ /* Enable window */
+ idma_bare_write(j, 0);
+ break;
+ }
+ }
+
+ /*
+ * Remaining targets -- from statically defined table
+ */
+ for (i = 0; i < idma_wins_no; i++)
+ if (idma_wins[i].target > 0) {
+ br = (idma_wins[i].base & 0xffff0000) |
+ (idma_wins[i].attr << 8) | idma_wins[i].target;
+ sz = ((idma_wins[i].size - 1) & 0xffff0000);
+
+ /* Set the first free IDMA window */
+ for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
+ if (idma_bare_read(j) == 0)
+ continue;
+
+ /* Configure window */
+ win_idma_br_write(j, br);
+ win_idma_sz_write(j, sz);
+ if (win_idma_can_remap(j) && idma_wins[j].remap >= 0)
+ win_idma_har_write(j, idma_wins[j].remap);
+
+ /* Set protection RW on all channels */
+ idma_set_prot(j, 0x3);
+
+ /* Enable window */
+ idma_bare_write(j, 0);
+ break;
+ }
+ }
+}
+
+int
+decode_win_idma_valid(void)
+{
+ const struct decode_win *wintab;
+ int c, i, j, rv;
+ uint32_t b, e, s;
+
+ if (idma_wins_no > MV_WIN_IDMA_MAX) {
+ printf("IDMA windows: too many entries: %d\n", idma_wins_no);
+ return (-1);
+ }
+ for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
+ if (ddr_is_active(i))
+ c++;
+
+ if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
+ printf("IDMA windows: too many entries: %d, available: %d\n",
+ idma_wins_no, MV_WIN_IDMA_MAX - c);
+ return (-1);
+ }
+
+ wintab = idma_wins;
+ rv = 1;
+ for (i = 0; i < idma_wins_no; i++, wintab++) {
+
+ if (wintab->target == 0) {
+ printf("IDMA window#%d: DDR target window is not supposed "
+ "to be reprogrammed!\n", i);
+ rv = 0;
+ }
+
+ if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
+ printf("IDMA window#%d: not capable of remapping, but "
+ "val 0x%08x defined\n", i, wintab->remap);
+ rv = 0;
+ }
+
+ s = wintab->size;
+ b = wintab->base;
+ e = b + s - 1;
+ if (s > (0xFFFFFFFF - b + 1)) {
+ /* XXX this boundary check should accont for 64bit and
+ * remapping.. */
+ printf("IDMA window#%d: no space for size 0x%08x at "
+ "0x%08x\n", i, s, b);
+ rv = 0;
+ continue;
+ }
+
+ j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
+ if (j >= 0) {
+ printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps with "
+ "#%d (0x%08x - 0x%08x)\n", i, b, e, j,
+ idma_wins[j].base,
+ idma_wins[j].base + idma_wins[j].size - 1);
+ rv = 0;
+ }
+ }
+
+ return (rv);
+}
+
+void
+decode_win_idma_dump(void)
+{
+ int i;
+
+ for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
+ printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
+ win_idma_br_read(i), win_idma_sz_read(i));
+
+ if (win_idma_can_remap(i))
+ printf(", ha 0x%08x", win_idma_har_read(i));
+
+ printf("\n");
+ }
+ for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
+ printf("IDMA channel#%d: ap 0x%08x\n", i,
+ win_idma_cap_read(i));
+ printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read());
+}
+#else
+
+/* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
+int
+decode_win_idma_valid(void)
+{
+
+ return (1);
+}
+
+void
+decode_win_idma_setup(void)
+{
+}
+#endif
==== //depot/projects/arm/src/sys/arm/mv/discovery/discovery.c#2 (text+ko) ====
@@ -139,3 +139,19 @@
};
const struct decode_win *cpu_wins = cpu_win_tbl;
int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
+
+/*
+ * Note: the decode windows table for IDMA does not explicitly have DRAM
+ * entries, which are not statically defined: active DDR banks (== windows)
+ * are established in run time from actual DDR windows settings. All active
+ * DDR banks are mapped into IDMA decode windows, so at least one IDMA decode
+ * window is occupied by the DDR bank; in case when all (MV_WIN_DDR_MAX)
+ * DDR banks are active, the remaining available IDMA decode windows for other
+ * targets is only MV_WIN_IDMA_MAX - MV_WIN_DDR_MAX.
+ */
+const struct decode_win idma_win_tbl[] = {
+ /* PCIE MEM */
+ { 4, 0x59, MV_PCIE_MEM_PHYS_BASE, -1 },
+};
+const struct decode_win *idma_wins = idma_win_tbl;
+int idma_wins_no = sizeof(idma_win_tbl) / sizeof(struct decode_win);
==== //depot/projects/arm/src/sys/arm/mv/orion/orion.c#3 (text+ko) ====
@@ -187,237 +187,3 @@
};
const struct decode_win *idma_wins = idma_win_tbl;
int idma_wins_no = sizeof(idma_win_tbl) / sizeof(struct decode_win);
-
-/**************************************************************************
- * IDMA decode windows registers accessors
- **************************************************************************/
-WIN_REG_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
-WIN_REG_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
-WIN_REG_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
-WIN_REG_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
-WIN_REG_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
-WIN_REG_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
-WIN_REG_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
-WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
-WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
-WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
-
-/**************************************************************************
- * IDMA windows routines
- **************************************************************************/
-static int
-idma_bare_read(int i)
-{
- uint32_t v;
-
- v = win_idma_bare_read();
- v &= (1 << i);
-
- return (v >> i);
-}
-
-static void
-idma_bare_write(int i, int val)
-{
- uint32_t v;
-
- v = win_idma_bare_read();
- v &= ~(1 << i);
- v |= (val << i);
- win_idma_bare_write(v);
-}
-
-/*
- * Sets channel protection 'val' for window 'w' on channel 'c'
- */
-static void
-idma_cap_write(int c, int w, int val)
-{
- uint32_t v;
-
- v = win_idma_cap_read(c);
- v &= ~(0x3 << (w * 2));
- v |= (val << (w * 2));
- win_idma_cap_write(c, v);
-}
-
-/*
- * Set protection 'val' on all channels for window 'w'
- */
-static void
-idma_set_prot(int w, int val)
-{
- int c;
-
- for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
- idma_cap_write(c, w, val);
-}
-
-static int
-win_idma_can_remap(int i)
-{
-
- /* IDMA decode windows 0-3 have remap capability */
- if (i < 4)
- return (1);
-
- return (0);
-}
-
-void
-decode_win_idma_setup(void)
-{
- uint32_t br, sz;
- int i, j;
-
- /*
- * Disable and clear all IDMA windows, revoke protection for all channels
- */
- for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
-
- idma_bare_write(i, 1);
- win_idma_br_write(i, 0);
- win_idma_sz_write(i, 0);
- if (win_idma_can_remap(i) == 1)
- win_idma_har_write(i, 0);
- }
- for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
- win_idma_cap_write(i, 0);
-
- /*
- * Set up access to all active DRAM banks
- */
- for (i = 0; i < MV_WIN_DDR_MAX; i++)
- if (ddr_is_active(i)) {
- br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
- sz = ((ddr_size(i) - 1) & 0xffff0000);
-
- /* Place DDR entries in non-remapped windows */
- for (j = 0; j < MV_WIN_IDMA_MAX; j++)
- if (win_idma_can_remap(j) != 1 &&
- idma_bare_read(j) == 1) {
-
- /* Configure window */
- win_idma_br_write(j, br);
- win_idma_sz_write(j, sz);
-
- /* Set protection RW on all channels */
- idma_set_prot(j, 0x3);
-
- /* Enable window */
- idma_bare_write(j, 0);
- break;
- }
- }
-
- /*
- * Remaining targets -- from statically defined table
- */
- for (i = 0; i < idma_wins_no; i++)
- if (idma_wins[i].target > 0) {
- br = (idma_wins[i].base & 0xffff0000) |
- (idma_wins[i].attr << 8) | idma_wins[i].target;
- sz = ((idma_wins[i].size - 1) & 0xffff0000);
-
- /* Set the first free IDMA window */
- for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
- if (idma_bare_read(j) == 0)
- continue;
-
- /* Configure window */
- win_idma_br_write(j, br);
- win_idma_sz_write(j, sz);
- if (win_idma_can_remap(j) && idma_wins[j].remap >= 0)
- win_idma_har_write(j, idma_wins[j].remap);
-
- /* Set protection RW on all channels */
- idma_set_prot(j, 0x3);
-
- /* Enable window */
- idma_bare_write(j, 0);
- break;
- }
- }
-}
-
-int
-decode_win_idma_valid(void)
-{
- const struct decode_win *wintab;
- int c, i, j, rv;
- uint32_t b, e, s;
-
- if (idma_wins_no > MV_WIN_IDMA_MAX) {
- printf("IDMA windows: too many entries: %d\n", idma_wins_no);
- return (-1);
- }
- for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
- if (ddr_is_active(i))
- c++;
-
- if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
- printf("IDMA windows: too many entries: %d, available: %d\n",
- idma_wins_no, MV_WIN_IDMA_MAX - c);
- return (-1);
- }
-
- wintab = idma_wins;
- rv = 1;
- for (i = 0; i < idma_wins_no; i++, wintab++) {
-
- if (wintab->target == 0) {
- printf("IDMA window#%d: DDR target window is not supposed "
- "to be reprogrammed!\n", i);
- rv = 0;
- }
-
- if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
- printf("IDMA window#%d: not capable of remapping, but "
- "val 0x%08x defined\n", i, wintab->remap);
- rv = 0;
- }
-
- s = wintab->size;
- b = wintab->base;
- e = b + s - 1;
- if (s > (0xFFFFFFFF - b + 1)) {
- /* XXX this boundary check should accont for 64bit and
- * remapping.. */
- printf("IDMA window#%d: no space for size 0x%08x at "
- "0x%08x\n", i, s, b);
- rv = 0;
- continue;
- }
-
- j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
- if (j >= 0) {
- printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps with "
- "#%d (0x%08x - 0x%08x)\n", i, b, e, j,
- idma_wins[j].base,
- idma_wins[j].base + idma_wins[j].size - 1);
- rv = 0;
- }
- }
-
- return (rv);
-}
-
-void
-decode_win_idma_dump(void)
-{
- int i;
-
- for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
- printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
- win_idma_br_read(i), win_idma_sz_read(i));
-
- if (win_idma_can_remap(i))
- printf(", ha 0x%08x", win_idma_har_read(i));
-
- printf("\n");
- }
- for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
- printf("IDMA channel#%d: ap 0x%08x\n", i,
- win_idma_cap_read(i));
- printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read());
-}
More information about the p4-projects
mailing list