Date: Tue, 23 Sep 2008 09:27:40 GMT From: Rafal Jaworowski <raj@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 150333 for review Message-ID: <200809230927.m8N9ReqW043926@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=150333 Change 150333 by raj@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()); -}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200809230927.m8N9ReqW043926>