Improve and extend Marvell SOCs platform code.
- Allow for setting per platform MPP/GPIO configuration in the kernel, so that we can override all settings firmware might set. - Set decode windows for the remaining on-chip peripherals: CESA, SATA and XOR. - Improve handling of USB controllers so that all port are available on the given SOC/platform (e.g. up to three on DB-78xxx), this includes rework of USB decode windows set-up. - Other minor fixes and cosmetics. Obtained from: Semihalf
This commit is contained in:
parent
b098744265
commit
673c4fe419
@ -46,13 +46,19 @@ static int decode_win_cpu_valid(void);
|
||||
static int decode_win_usb_valid(void);
|
||||
static int decode_win_eth_valid(void);
|
||||
static int decode_win_pcie_valid(void);
|
||||
static int decode_win_sata_valid(void);
|
||||
static int decode_win_cesa_valid(void);
|
||||
|
||||
static void decode_win_cpu_setup(void);
|
||||
static void decode_win_usb_setup(uint32_t ctrl);
|
||||
static void decode_win_usb_setup(void);
|
||||
static void decode_win_eth_setup(uint32_t base);
|
||||
static void decode_win_pcie_setup(uint32_t base);
|
||||
static void decode_win_sata_setup(void);
|
||||
static void decode_win_cesa_setup(void);
|
||||
|
||||
static void decode_win_cesa_dump(void);
|
||||
static void decode_win_usb_dump(void);
|
||||
|
||||
static uint32_t dev, rev;
|
||||
static uint32_t used_cpu_wins;
|
||||
|
||||
uint32_t
|
||||
@ -81,6 +87,7 @@ cpu_reset(void)
|
||||
uint32_t
|
||||
cpu_extra_feat(void)
|
||||
{
|
||||
uint32_t dev, rev;
|
||||
uint32_t ef = 0;
|
||||
|
||||
soc_id(&dev, &rev);
|
||||
@ -178,22 +185,27 @@ soc_identify(void)
|
||||
int
|
||||
soc_decode_win(void)
|
||||
{
|
||||
uint32_t dev, rev;
|
||||
|
||||
/* Retrieve our ID: some windows facilities vary between SoC models */
|
||||
soc_id(&dev, &rev);
|
||||
|
||||
if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
|
||||
decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
|
||||
decode_win_pcie_valid() != 1)
|
||||
decode_win_pcie_valid() != 1 || decode_win_sata_valid() != 1 ||
|
||||
decode_win_cesa_valid() != 1)
|
||||
return(-1);
|
||||
|
||||
decode_win_cpu_setup();
|
||||
decode_win_usb_setup(MV_USB0_BASE);
|
||||
decode_win_usb_setup();
|
||||
decode_win_eth_setup(MV_ETH0_BASE);
|
||||
if (dev == MV_DEV_MV78100)
|
||||
decode_win_eth_setup(MV_ETH1_BASE);
|
||||
if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100)
|
||||
decode_win_cesa_setup();
|
||||
|
||||
decode_win_idma_setup();
|
||||
decode_win_xor_setup();
|
||||
|
||||
if (dev == MV_DEV_MV78100) {
|
||||
decode_win_pcie_setup(MV_PCIE00_BASE);
|
||||
@ -207,7 +219,8 @@ soc_decode_win(void)
|
||||
} else
|
||||
decode_win_pcie_setup(MV_PCIE_BASE);
|
||||
|
||||
/* TODO set up decode wins for SATA */
|
||||
if (dev != MV_DEV_88F5281)
|
||||
decode_win_sata_setup();
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -227,10 +240,15 @@ WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
|
||||
WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
|
||||
WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
|
||||
|
||||
WIN_REG_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
|
||||
WIN_REG_IDX_RD(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
|
||||
WIN_REG_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
|
||||
WIN_REG_IDX_WR(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
|
||||
WIN_REG_IDX_RD2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
|
||||
WIN_REG_IDX_RD2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
|
||||
WIN_REG_IDX_WR2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
|
||||
WIN_REG_IDX_WR2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
|
||||
|
||||
WIN_REG_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
|
||||
WIN_REG_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
|
||||
WIN_REG_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
|
||||
WIN_REG_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
|
||||
|
||||
WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
|
||||
WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
|
||||
@ -238,6 +256,16 @@ WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
|
||||
WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
|
||||
WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
|
||||
WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
|
||||
|
||||
WIN_REG_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
|
||||
WIN_REG_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
|
||||
WIN_REG_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
|
||||
WIN_REG_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
|
||||
WIN_REG_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
|
||||
WIN_REG_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
|
||||
WIN_REG_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
|
||||
WIN_REG_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
|
||||
|
||||
WIN_REG_BASE_RD(win_eth, bare, 0x290)
|
||||
WIN_REG_BASE_RD(win_eth, epap, 0x294)
|
||||
WIN_REG_BASE_WR(win_eth, bare, 0x290)
|
||||
@ -262,12 +290,18 @@ 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)
|
||||
|
||||
WIN_REG_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
|
||||
WIN_REG_IDX_RD(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
|
||||
WIN_REG_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
|
||||
WIN_REG_IDX_WR(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
|
||||
|
||||
/**************************************************************************
|
||||
* Decode windows helper routines
|
||||
**************************************************************************/
|
||||
void
|
||||
soc_dump_decode_win(void)
|
||||
{
|
||||
uint32_t dev, rev;
|
||||
int i;
|
||||
|
||||
soc_id(&dev, &rev);
|
||||
@ -290,10 +324,6 @@ soc_dump_decode_win(void)
|
||||
for (i = 0; i < MV_WIN_DDR_MAX; i++)
|
||||
printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
|
||||
ddr_br_read(i), ddr_sz_read(i));
|
||||
|
||||
for (i = 0; i < MV_WIN_USB_MAX; i++)
|
||||
printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
|
||||
win_usb_cr_read(i), win_usb_br_read(i));
|
||||
|
||||
for (i = 0; i < MV_WIN_ETH_MAX; i++) {
|
||||
printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
|
||||
@ -311,6 +341,8 @@ soc_dump_decode_win(void)
|
||||
win_eth_epap_read(MV_ETH0_BASE));
|
||||
|
||||
decode_win_idma_dump();
|
||||
decode_win_cesa_dump();
|
||||
decode_win_usb_dump();
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@ -320,6 +352,9 @@ soc_dump_decode_win(void)
|
||||
int
|
||||
win_cpu_can_remap(int i)
|
||||
{
|
||||
uint32_t dev, rev;
|
||||
|
||||
soc_id(&dev, &rev);
|
||||
|
||||
/* Depending on the SoC certain windows have remap capability */
|
||||
if ((dev == MV_DEV_88F5182 && i < 2) ||
|
||||
@ -549,42 +584,69 @@ decode_win_usb_valid(void)
|
||||
return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
usb_max_ports(void)
|
||||
{
|
||||
uint32_t dev, rev;
|
||||
|
||||
soc_id(&dev, &rev);
|
||||
return (dev == MV_DEV_MV78100 ? 3 : 1);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_win_usb_dump(void)
|
||||
{
|
||||
int i, p, m;
|
||||
|
||||
m = usb_max_ports();
|
||||
for (p = 0; p < m; p++)
|
||||
for (i = 0; i < MV_WIN_USB_MAX; i++)
|
||||
printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
|
||||
win_usb_cr_read(i, p), win_usb_br_read(i, p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set USB decode windows.
|
||||
*/
|
||||
static void
|
||||
decode_win_usb_setup(uint32_t ctrl)
|
||||
decode_win_usb_setup(void)
|
||||
{
|
||||
uint32_t br, cr;
|
||||
int i, j;
|
||||
int i, j, p, m;
|
||||
|
||||
/* Disable and clear all USB windows */
|
||||
for (i = 0; i < MV_WIN_USB_MAX; i++) {
|
||||
win_usb_cr_write(i, 0);
|
||||
win_usb_br_write(i, 0);
|
||||
}
|
||||
/* Disable and clear all USB windows for all ports */
|
||||
m = usb_max_ports();
|
||||
for (p = 0; p < m; p++) {
|
||||
|
||||
/* 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);
|
||||
/*
|
||||
* XXX for 6281 we should handle Mbus write burst limit
|
||||
* field in the ctrl reg
|
||||
*/
|
||||
cr = (((ddr_size(i) - 1) & 0xffff0000) |
|
||||
(ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
|
||||
for (i = 0; i < MV_WIN_USB_MAX; i++) {
|
||||
win_usb_cr_write(i, p, 0);
|
||||
win_usb_br_write(i, p, 0);
|
||||
}
|
||||
|
||||
/* Set the first free USB window */
|
||||
for (j = 0; j < MV_WIN_USB_MAX; j++) {
|
||||
if (win_usb_cr_read(j) & 0x1)
|
||||
continue;
|
||||
/* 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);
|
||||
/*
|
||||
* XXX for 6281 we should handle Mbus write
|
||||
* burst limit field in the ctrl reg
|
||||
*/
|
||||
cr = (((ddr_size(i) - 1) & 0xffff0000) |
|
||||
(ddr_attr(i) << 8) |
|
||||
(ddr_target(i) << 4) | 1);
|
||||
|
||||
win_usb_br_write(j, br);
|
||||
win_usb_cr_write(j, cr);
|
||||
break;
|
||||
/* Set the first free USB window */
|
||||
for (j = 0; j < MV_WIN_USB_MAX; j++) {
|
||||
if (win_usb_cr_read(j, p) & 0x1)
|
||||
continue;
|
||||
|
||||
win_usb_br_write(j, p, br);
|
||||
win_usb_cr_write(j, p, cr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
@ -934,7 +996,7 @@ decode_win_idma_valid(void)
|
||||
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,
|
||||
"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;
|
||||
@ -983,3 +1045,413 @@ decode_win_idma_dump(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* XOR windows routines
|
||||
**************************************************************************/
|
||||
#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
|
||||
static int
|
||||
xor_ctrl_read(int i, int c, int e)
|
||||
{
|
||||
uint32_t v;
|
||||
v = win_xor_ctrl_read(c, e);
|
||||
v &= (1 << i);
|
||||
|
||||
return (v >> i);
|
||||
}
|
||||
|
||||
static void
|
||||
xor_ctrl_write(int i, int c, int e, int val)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
v = win_xor_ctrl_read(c, e);
|
||||
v &= ~(1 << i);
|
||||
v |= (val << i);
|
||||
win_xor_ctrl_write(c, e, v);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set channel protection 'val' for window 'w' on channel 'c'
|
||||
*/
|
||||
|
||||
static void
|
||||
xor_chan_write(int c, int e, int w, int val)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
v = win_xor_ctrl_read(c, e);
|
||||
v &= ~(0x3 << (w * 2 + 16));
|
||||
v |= (val << (w * 2 + 16));
|
||||
win_xor_ctrl_write(c, e, v);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set protection 'val' on all channels for window 'w' on engine 'e'
|
||||
*/
|
||||
static void
|
||||
xor_set_prot(int w, int e, int val)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < MV_XOR_CHAN_MAX; c++)
|
||||
xor_chan_write(c, e, w, val);
|
||||
}
|
||||
|
||||
static int
|
||||
win_xor_can_remap(int i)
|
||||
{
|
||||
|
||||
/* XOR decode windows 0-3 have remap capability */
|
||||
if (i < 4)
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
xor_max_eng(void)
|
||||
{
|
||||
uint32_t dev, rev;
|
||||
|
||||
soc_id(&dev, &rev);
|
||||
return ((dev == MV_DEV_88F6281) ? 2 :
|
||||
(dev == MV_DEV_MV78100) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
xor_active_dram(int c, int e, int *window)
|
||||
{
|
||||
uint32_t br, sz;
|
||||
int i, m, w;
|
||||
|
||||
/*
|
||||
* Set up access to all active DRAM banks
|
||||
*/
|
||||
m = xor_max_eng();
|
||||
for (i = 0; i < m; 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 (w = 0; w < MV_WIN_XOR_MAX; w++)
|
||||
if (win_xor_can_remap(w) != 1 &&
|
||||
(xor_ctrl_read(w, c, e) == 0) &&
|
||||
w > *window) {
|
||||
/* Configure window */
|
||||
win_xor_br_write(w, e, br);
|
||||
win_xor_sz_write(w, e, sz);
|
||||
|
||||
/* Set protection RW on all channels */
|
||||
xor_set_prot(w, e, 0x3);
|
||||
|
||||
/* Enable window */
|
||||
xor_ctrl_write(w, c, e, 1);
|
||||
(*window)++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
decode_win_xor_setup(void)
|
||||
{
|
||||
uint32_t br, sz;
|
||||
int i, j, z, e = 1, m, window;
|
||||
|
||||
/*
|
||||
* Disable and clear all XOR windows, revoke protection for all
|
||||
* channels
|
||||
*/
|
||||
m = xor_max_eng();
|
||||
for (j = 0; j < m; j++, e--) {
|
||||
|
||||
/* Number of non-remaped windows */
|
||||
window = MV_XOR_NON_REMAP - 1;
|
||||
|
||||
for (i = 0; i < MV_WIN_XOR_MAX; i++) {
|
||||
win_xor_br_write(i, e, 0);
|
||||
win_xor_sz_write(i, e, 0);
|
||||
}
|
||||
|
||||
if (win_xor_can_remap(i) == 1)
|
||||
win_xor_har_write(i, e, 0);
|
||||
|
||||
for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
|
||||
win_xor_ctrl_write(i, e, 0);
|
||||
xor_active_dram(i, e, &window);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remaining targets -- from a statically defined table
|
||||
*/
|
||||
for (i = 0; i < xor_wins_no; i++)
|
||||
if (xor_wins[i].target > 0) {
|
||||
br = (xor_wins[i].base & 0xffff0000) |
|
||||
(xor_wins[i].attr << 8) |
|
||||
xor_wins[i].target;
|
||||
sz = ((xor_wins[i].size - 1) & 0xffff0000);
|
||||
|
||||
/* Set the first free XOR window */
|
||||
for (z = 0; z < MV_WIN_XOR_MAX; z++) {
|
||||
if (xor_ctrl_read(z, 0, e) &&
|
||||
xor_ctrl_read(z, 1, e))
|
||||
continue;
|
||||
|
||||
/* Configure window */
|
||||
win_xor_br_write(z, e, br);
|
||||
win_xor_sz_write(z, e, sz);
|
||||
if (win_xor_can_remap(z) &&
|
||||
xor_wins[z].remap >= 0)
|
||||
win_xor_har_write(z, e,
|
||||
xor_wins[z].remap);
|
||||
|
||||
/* Set protection RW on all channels */
|
||||
xor_set_prot(z, e, 0x3);
|
||||
|
||||
/* Enable window */
|
||||
xor_ctrl_write(z, 0, e, 1);
|
||||
xor_ctrl_write(z, 1, e, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
decode_win_xor_valid(void)
|
||||
{
|
||||
const struct decode_win *wintab;
|
||||
int c, i, j, rv;
|
||||
uint32_t b, e, s;
|
||||
|
||||
if (xor_wins_no > MV_WIN_XOR_MAX) {
|
||||
printf("XOR windows: too many entries: %d\n", xor_wins_no);
|
||||
return (-1);
|
||||
}
|
||||
for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
|
||||
if (ddr_is_active(i))
|
||||
c++;
|
||||
|
||||
if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
|
||||
printf("XOR windows: too many entries: %d, available: %d\n",
|
||||
xor_wins_no, MV_WIN_IDMA_MAX - c);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
wintab = xor_wins;
|
||||
rv = 1;
|
||||
for (i = 0; i < xor_wins_no; i++, wintab++) {
|
||||
|
||||
if (wintab->target == 0) {
|
||||
printf("XOR 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("XOR 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 account for 64bit
|
||||
* and remapping..
|
||||
*/
|
||||
printf("XOR window#%d: no space for size 0x%08x at "
|
||||
"0x%08x\n", i, s, b);
|
||||
rv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
|
||||
if (j >= 0) {
|
||||
printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
|
||||
"with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
|
||||
xor_wins[j].base,
|
||||
xor_wins[j].base + xor_wins[j].size - 1);
|
||||
rv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
void
|
||||
decode_win_xor_dump(void)
|
||||
{
|
||||
int i, j;
|
||||
int e = 1;
|
||||
|
||||
for (j = 0; j < xor_max_eng(); j++, e--) {
|
||||
for (i = 0; i < MV_WIN_XOR_MAX; i++) {
|
||||
printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
|
||||
win_xor_br_read(i, e), win_xor_sz_read(i, e));
|
||||
|
||||
if (win_xor_can_remap(i))
|
||||
printf(", ha 0x%08x", win_xor_har_read(i, e));
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
for (i = 0; i < MV_XOR_CHAN_MAX; i++)
|
||||
printf("XOR control#%d: 0x%08x\n", i,
|
||||
win_xor_ctrl_read(i, e));
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
|
||||
int
|
||||
decode_win_xor_valid(void)
|
||||
{
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
decode_win_xor_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
decode_win_xor_dump(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* CESA TDMA windows routines
|
||||
**************************************************************************/
|
||||
#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
|
||||
/*
|
||||
* Dump CESA TDMA decode windows.
|
||||
*/
|
||||
static void
|
||||
decode_win_cesa_dump(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MV_WIN_CESA_MAX; i++)
|
||||
printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
|
||||
win_cesa_cr_read(i), win_cesa_br_read(i));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set CESA TDMA decode windows.
|
||||
*/
|
||||
static void
|
||||
decode_win_cesa_setup(void)
|
||||
{
|
||||
uint32_t br, cr;
|
||||
int i, j;
|
||||
|
||||
/* Disable and clear all CESA windows */
|
||||
for (i = 0; i < MV_WIN_CESA_MAX; i++) {
|
||||
win_cesa_cr_write(i, 0);
|
||||
win_cesa_br_write(i, 0);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
cr = (((ddr_size(i) - 1) & 0xffff0000) |
|
||||
(ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
|
||||
|
||||
/* Set the first available CESA window */
|
||||
for (j = 0; j < MV_WIN_CESA_MAX; j++) {
|
||||
if (win_cesa_cr_read(j) & 0x1)
|
||||
continue;
|
||||
|
||||
win_cesa_br_write(j, br);
|
||||
win_cesa_cr_write(j, cr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check CESA TDMA decode windows.
|
||||
*/
|
||||
static int
|
||||
decode_win_cesa_valid(void)
|
||||
{
|
||||
|
||||
return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* Provide dummy functions to satisfy the build for SoCs not equipped with
|
||||
* CESA
|
||||
*/
|
||||
|
||||
int
|
||||
decode_win_cesa_valid(void)
|
||||
{
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
decode_win_cesa_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
decode_win_cesa_dump(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* SATA windows routines
|
||||
**************************************************************************/
|
||||
static void
|
||||
decode_win_sata_setup(void)
|
||||
{
|
||||
uint32_t cr, br;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < MV_WIN_SATA_MAX; i++) {
|
||||
win_sata_cr_write(i, 0);
|
||||
win_sata_br_write(i, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < MV_WIN_DDR_MAX; i++)
|
||||
if (ddr_is_active(i)) {
|
||||
cr = ((ddr_size(i) - 1) & 0xffff0000) |
|
||||
(ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
|
||||
br = ddr_base(i);
|
||||
|
||||
/* Use the first available SATA window */
|
||||
for (j = 0; j < MV_WIN_SATA_MAX; j++) {
|
||||
if ((win_sata_cr_read(j) & 1) != 0)
|
||||
continue;
|
||||
|
||||
win_sata_br_write(j, br);
|
||||
win_sata_cr_write(j, cr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
decode_win_sata_valid(void)
|
||||
{
|
||||
uint32_t dev, rev;
|
||||
|
||||
soc_id(&dev, &rev);
|
||||
if (dev == MV_DEV_88F5281)
|
||||
return (1);
|
||||
|
||||
return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/vmparam.h>
|
||||
@ -99,6 +100,10 @@ static const struct pmap_devmap pmap_devmap[] = {
|
||||
{ 0, 0, 0, 0, 0, }
|
||||
};
|
||||
|
||||
const struct gpio_config mv_gpio_config[] = {
|
||||
{ -1, -1, -1 }
|
||||
};
|
||||
|
||||
int
|
||||
platform_pmap_init(void)
|
||||
{
|
||||
@ -109,6 +114,52 @@ platform_pmap_init(void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
platform_mpp_init(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* MPP Configuration for DB-78100-BP
|
||||
*
|
||||
* MPP[0]: GE1_TXCLK
|
||||
* MPP[1]: GE1_TXCTL
|
||||
* MPP[2]: GE1_RXCTL
|
||||
* MPP[3]: GE1_RXCLK
|
||||
* MPP[4]: GE1_TXD[0]
|
||||
* MPP[5]: GE1_TXD[1]
|
||||
* MPP[6]: GE1_TXD[2]
|
||||
* MPP[7]: GE1_TXD[3]
|
||||
* MPP[8]: GE1_RXD[0]
|
||||
* MPP[9]: GE1_RXD[1]
|
||||
* MPP[10]: GE1_RXD[2]
|
||||
* MPP[11]: GE1_RXD[3]
|
||||
* MPP[13]: SYSRST_OUTn
|
||||
* MPP[14]: SATA1_ACT
|
||||
* MPP[15]: SATA0_ACT
|
||||
* MPP[16]: UA2_TXD
|
||||
* MPP[17]: UA2_RXD
|
||||
* MPP[18]: <UNKNOWN>
|
||||
* MPP[19]: <UNKNOWN>
|
||||
* MPP[20]: <UNKNOWN>
|
||||
* MPP[21]: <UNKNOWN>
|
||||
* MPP[22]: UA3_TXD
|
||||
* MPP[23]: UA3_RXD
|
||||
* MPP[48]: <UNKNOWN>
|
||||
* MPP[49]: <UNKNOWN>
|
||||
*
|
||||
* Others: GPIO
|
||||
*
|
||||
* <UNKNOWN> entries are not documented, not on the schematics etc.
|
||||
*/
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x22222222);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x33302222);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x44333344);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00000000);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x0000FFFF);
|
||||
}
|
||||
|
||||
static void
|
||||
platform_identify(void *dummy)
|
||||
{
|
||||
@ -121,7 +172,3 @@ platform_identify(void *dummy)
|
||||
*/
|
||||
}
|
||||
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
|
||||
|
||||
/*
|
||||
* TODO routine setting GPIO/MPP pins
|
||||
*/
|
||||
|
@ -103,6 +103,16 @@ struct obio_device obio_devices[] = {
|
||||
{ -1 },
|
||||
CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
|
||||
},
|
||||
{ "ehci", MV_USB1_BASE, MV_USB_SIZE,
|
||||
{ MV_INT_USB_ERR, MV_INT_USB1, -1 },
|
||||
{ -1 },
|
||||
CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
|
||||
},
|
||||
{ "ehci", MV_USB2_BASE, MV_USB_SIZE,
|
||||
{ MV_INT_USB_ERR, MV_INT_USB2, -1 },
|
||||
{ -1 },
|
||||
CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
|
||||
},
|
||||
{ "mge", MV_ETH0_BASE, MV_ETH_SIZE,
|
||||
{ MV_INT_GBERX, MV_INT_GBETX, MV_INT_GBEMISC,
|
||||
MV_INT_GBESUM, MV_INT_GBE_ERR, -1 },
|
||||
@ -177,7 +187,7 @@ const struct obio_pci mv_pci_info[] = {
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
struct resource_spec mv_gpio_spec[] = {
|
||||
struct resource_spec mv_gpio_res[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 1, RF_ACTIVE },
|
||||
@ -186,7 +196,7 @@ struct resource_spec mv_gpio_spec[] = {
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
struct resource_spec mv_xor_spec[] = {
|
||||
struct resource_spec mv_xor_res[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 1, RF_ACTIVE },
|
||||
@ -206,6 +216,9 @@ const struct decode_win cpu_win_tbl[] = {
|
||||
|
||||
/* Device bus CS2 */
|
||||
{ 1, 0x3b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
|
||||
|
||||
/* CESA */
|
||||
{ 9, 0x01, MV_CESA_SRAM_PHYS_BASE, MV_CESA_SRAM_SIZE, -1 },
|
||||
};
|
||||
const struct decode_win *cpu_wins = cpu_win_tbl;
|
||||
int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
|
||||
@ -227,6 +240,14 @@ const struct decode_win idma_win_tbl[] = {
|
||||
const struct decode_win *idma_wins = idma_win_tbl;
|
||||
int idma_wins_no = sizeof(idma_win_tbl) / sizeof(struct decode_win);
|
||||
|
||||
const struct decode_win xor_win_tbl[] = {
|
||||
/* PCIE MEM */
|
||||
{ 4, 0xE8, _MV_PCIE_MEM_PHYS(0), _MV_PCIE_MEM_SIZE, -1},
|
||||
{ 4, 0xD8, _MV_PCIE_MEM_PHYS(1), _MV_PCIE_MEM_SIZE, -1},
|
||||
};
|
||||
const struct decode_win *xor_wins = xor_win_tbl;
|
||||
int xor_wins_no = sizeof(xor_win_tbl) / sizeof(struct decode_win);
|
||||
|
||||
uint32_t
|
||||
get_tclk(void)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ struct mv_gpio_softc {
|
||||
uint8_t use_high;
|
||||
};
|
||||
|
||||
extern struct resource_spec mv_gpio_spec[];
|
||||
extern struct resource_spec mv_gpio_res[];
|
||||
|
||||
static struct mv_gpio_softc *mv_gpio_softc = NULL;
|
||||
static uint32_t gpio_setup[MV_GPIO_MAX_NPINS];
|
||||
@ -143,7 +143,7 @@ mv_gpio_attach(device_t dev)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
error = bus_alloc_resources(dev, mv_gpio_spec, sc->res);
|
||||
error = bus_alloc_resources(dev, mv_gpio_res, sc->res);
|
||||
if (error) {
|
||||
device_printf(dev, "could not allocate resources\n");
|
||||
return (ENXIO);
|
||||
@ -171,21 +171,33 @@ mv_gpio_attach(device_t dev)
|
||||
INTR_TYPE_MISC | INTR_FAST,
|
||||
(driver_filter_t *)mv_gpio_intr, NULL,
|
||||
sc, &sc->ih_cookie[i]) != 0) {
|
||||
bus_release_resources(dev, mv_gpio_spec, sc->res);
|
||||
bus_release_resources(dev, mv_gpio_res, sc->res);
|
||||
device_printf(dev, "could not set up intr %d\n", i);
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup GPIO lines */
|
||||
for (i = 0; mv_gpio_config[i].gc_gpio >= 0; i++) {
|
||||
mv_gpio_configure(mv_gpio_config[i].gc_gpio,
|
||||
mv_gpio_config[i].gc_flags, ~0u);
|
||||
|
||||
if (mv_gpio_config[i].gc_output < 0)
|
||||
mv_gpio_out_en(mv_gpio_config[i].gc_gpio, 0);
|
||||
else
|
||||
mv_gpio_out(mv_gpio_config[i].gc_gpio,
|
||||
mv_gpio_config[i].gc_output, 1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
mv_gpio_intr(void *arg)
|
||||
{
|
||||
uint32_t int_cause, gpio_val;
|
||||
uint32_t int_cause_hi, gpio_val_hi = 0;
|
||||
int i;
|
||||
uint32_t int_cause, gpio_val;
|
||||
uint32_t int_cause_hi, gpio_val_hi = 0;
|
||||
int i;
|
||||
|
||||
int_cause = mv_gpio_reg_read(GPIO_INT_CAUSE);
|
||||
gpio_val = mv_gpio_reg_read(GPIO_DATA_IN);
|
||||
@ -295,8 +307,8 @@ mv_gpio_configure(uint32_t pin, uint32_t flags, uint32_t mask)
|
||||
|
||||
if (mask & MV_GPIO_BLINK)
|
||||
mv_gpio_blink(pin, flags & MV_GPIO_BLINK);
|
||||
if (mask & MV_GPIO_POLARITY)
|
||||
mv_gpio_polarity(pin, flags & MV_GPIO_POLARITY);
|
||||
if (mask & MV_GPIO_POLAR_LOW)
|
||||
mv_gpio_polarity(pin, flags & MV_GPIO_POLAR_LOW);
|
||||
if (mask & MV_GPIO_EDGE)
|
||||
mv_gpio_edge(pin, flags & MV_GPIO_EDGE);
|
||||
if (mask & MV_GPIO_LEVEL)
|
||||
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/vmparam.h>
|
||||
@ -99,6 +100,10 @@ static const struct pmap_devmap pmap_devmap[] = {
|
||||
{ 0, 0, 0, 0, 0, }
|
||||
};
|
||||
|
||||
const struct gpio_config mv_gpio_config[] = {
|
||||
{ -1, -1, -1 }
|
||||
};
|
||||
|
||||
int
|
||||
platform_pmap_init(void)
|
||||
{
|
||||
@ -109,6 +114,47 @@ platform_pmap_init(void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
platform_mpp_init(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* MPP configuration for DB-88F6281-BP and DB-88F6281-BP-A
|
||||
*
|
||||
* MPP[0]: NF_IO[2]
|
||||
* MPP[1]: NF_IO[3]
|
||||
* MPP[2]: NF_IO[4]
|
||||
* MPP[3]: NF_IO[5]
|
||||
* MPP[4]: NF_IO[6]
|
||||
* MPP[5]: NF_IO[7]
|
||||
* MPP[6]: SYSRST_OUTn
|
||||
* MPP[7]: SPI_SCn
|
||||
* MPP[8]: TW_SDA
|
||||
* MPP[9]: TW_SCK
|
||||
* MPP[10]: UA0_TXD
|
||||
* MPP[11]: UA0_RXD
|
||||
* MPP[12]: SD_CLK
|
||||
* MPP[13]: SD_CMD
|
||||
* MPP[14]: SD_D[0]
|
||||
* MPP[15]: SD_D[1]
|
||||
* MPP[16]: SD_D[2]
|
||||
* MPP[17]: SD_D[3]
|
||||
* MPP[18]: NF_IO[0]
|
||||
* MPP[19]: NF_IO[1]
|
||||
* MPP[20]: SATA1_AC
|
||||
* MPP[21]: SATA0_AC
|
||||
*
|
||||
* Others: GPIO
|
||||
*/
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x21111111);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x11113311);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00551111);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00000000);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x00000000);
|
||||
}
|
||||
|
||||
static void
|
||||
platform_identify(void *dummy)
|
||||
{
|
||||
@ -121,7 +167,3 @@ platform_identify(void *dummy)
|
||||
*/
|
||||
}
|
||||
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
|
||||
|
||||
/*
|
||||
* TODO routine setting GPIO/MPP pins
|
||||
*/
|
||||
|
@ -112,7 +112,7 @@ const struct obio_pci mv_pci_info[] = {
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
struct resource_spec mv_gpio_spec[] = {
|
||||
struct resource_spec mv_gpio_res[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 1, RF_ACTIVE },
|
||||
@ -124,7 +124,7 @@ struct resource_spec mv_gpio_spec[] = {
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
struct resource_spec mv_xor_spec[] = {
|
||||
struct resource_spec mv_xor_res[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 1, RF_ACTIVE },
|
||||
@ -147,10 +147,21 @@ const struct decode_win cpu_win_tbl[] = {
|
||||
|
||||
/* Device bus CS2 */
|
||||
{ 1, 0x1b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
|
||||
|
||||
/* CESA */
|
||||
{ 3, 0x00, MV_CESA_SRAM_PHYS_BASE, MV_CESA_SRAM_SIZE, -1 },
|
||||
|
||||
};
|
||||
const struct decode_win *cpu_wins = cpu_win_tbl;
|
||||
int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
|
||||
|
||||
const struct decode_win xor_win_tbl[] = {
|
||||
/* PCIE MEM */
|
||||
{ 4, 0xE8, MV_PCIE_MEM_PHYS_BASE, MV_PCIE_MEM_SIZE, -1 },
|
||||
};
|
||||
const struct decode_win *xor_wins = xor_win_tbl;
|
||||
int xor_wins_no = sizeof(xor_win_tbl) / sizeof(struct decode_win);
|
||||
|
||||
uint32_t
|
||||
get_tclk(void)
|
||||
{
|
||||
|
@ -550,6 +550,11 @@ initarm(void *mdp, void *unused __unused)
|
||||
print_kernel_section_addr();
|
||||
print_kenv();
|
||||
|
||||
/*
|
||||
* Re-initialise MPP
|
||||
*/
|
||||
platform_mpp_init();
|
||||
|
||||
/*
|
||||
* Re-initialise decode windows
|
||||
*/
|
||||
|
@ -74,8 +74,12 @@
|
||||
#define MV_DEV_CS2_PHYS_BASE (MV_DEV_CS1_PHYS_BASE + MV_DEV_CS1_SIZE)
|
||||
#define MV_DEV_CS2_SIZE 1024 /* XXX u-boot has 1MB */
|
||||
|
||||
#define MV_CESA_SRAM_PHYS_BASE 0xFD000000
|
||||
#define MV_CESA_SRAM_BASE MV_CESA_SRAM_PHYS_BASE /* VA == PA mapping */
|
||||
#define MV_CESA_SRAM_SIZE (1024 * 1024)
|
||||
|
||||
/* XXX this is probably not robust against wraparounds... */
|
||||
#if ((MV_DEV_CS2_PHYS_BASE + MV_DEV_CS2_SIZE) > 0xFFFEFFFF)
|
||||
#if ((MV_CESA_SRAM_PHYS_BASE + MV_CESA_SRAM_SIZE) > 0xFFFEFFFF)
|
||||
#error Devices memory layout overlaps reset vectors range!
|
||||
#endif
|
||||
|
||||
@ -103,6 +107,12 @@
|
||||
#define MV_TIMERS_SIZE 0x30
|
||||
#define MV_PCI_BASE (MV_BASE + 0x30000)
|
||||
#define MV_PCI_SIZE 0x2000
|
||||
#if defined (SOC_MV_KIRKWOOD)
|
||||
#define MV_CESA_BASE (MV_BASE + 0x30000) /* CESA,PCI don't coexist */
|
||||
#elif defined (SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
|
||||
#define MV_CESA_BASE (MV_BASE + 0x90000)
|
||||
#endif
|
||||
#define MV_CESA_SIZE 0x10000
|
||||
#define MV_PCIE_BASE (MV_BASE + 0x40000)
|
||||
#define MV_PCIE_SIZE 0x2000
|
||||
|
||||
@ -128,6 +138,13 @@
|
||||
#define MV_ETH0_BASE (MV_BASE + 0x72000)
|
||||
#define MV_ETH1_BASE (MV_BASE + 0x76000)
|
||||
#define MV_ETH_SIZE 0x2000
|
||||
#if defined(SOC_MV_ORION) || defined(SOC_MV_KIRKWOOD)
|
||||
#define MV_SATAHC_BASE (MV_BASE + 0x80000)
|
||||
#define MV_SATAHC_SIZE 0x6000
|
||||
#elif defined(SOC_MV_DISCOVERY)
|
||||
#define MV_SATAHC_BASE (MV_BASE + 0xA0000)
|
||||
#define MV_SATAHC_SIZE 0x6000
|
||||
#endif
|
||||
|
||||
#define MV_DEV_CS0_BASE MV_DEV_CS0_PHYS_BASE
|
||||
|
||||
@ -178,6 +195,7 @@
|
||||
#define MV_INT_GBE1MISC 18 /* GbE1 misc. interrupt */
|
||||
#define MV_INT_USB_CI 19 /* USB Controller interrupt */
|
||||
#define MV_INT_SATA 21 /* Serial-ATA Interrupt */
|
||||
#define MV_INT_CESA 22 /* Security engine completion int. */
|
||||
#define MV_INT_IDMA_ERR 23 /* DMA error interrupt */
|
||||
#define MV_INT_UART0 33 /* UART0 Interrupt */
|
||||
#define MV_INT_UART1 34
|
||||
@ -216,7 +234,7 @@
|
||||
#define MV_INT_USB0 16 /* USB0 interrupt */
|
||||
#define MV_INT_USB1 17 /* USB1 interrupt */
|
||||
#define MV_INT_USB2 18 /* USB2 interrupt */
|
||||
#define MV_INT_CRYPTO 19 /* Crypto engine completion interrupt */
|
||||
#define MV_INT_CESA 19 /* Crypto engine completion interrupt */
|
||||
#define MV_INT_XOR0 22 /* XOR engine 0 completion interrupt */
|
||||
#define MV_INT_XOR1 23 /* XOR engine 1 completion interrupt */
|
||||
#define MV_INT_SATA 26 /* SATA interrupt */
|
||||
@ -394,7 +412,7 @@
|
||||
#define MV_GPIO_MAX_NPINS 64
|
||||
|
||||
#define MV_GPIO_BLINK 0x1
|
||||
#define MV_GPIO_POLARITY 0x2
|
||||
#define MV_GPIO_POLAR_LOW 0x2
|
||||
#define MV_GPIO_EDGE 0x4
|
||||
#define MV_GPIO_LEVEL 0x8
|
||||
|
||||
@ -476,8 +494,12 @@
|
||||
#define MV_WIN_DDR_SIZE(n) (0x8 * (n) + 0x4)
|
||||
#define MV_WIN_DDR_MAX 4
|
||||
|
||||
#define MV_WIN_USB_CTRL(n) (0x10 * (n) + 0x0)
|
||||
#define MV_WIN_USB_BASE(n) (0x10 * (n) + 0x4)
|
||||
#define MV_WIN_CESA_CTRL(n) (0x8 * (n) + 0xa04)
|
||||
#define MV_WIN_CESA_BASE(n) (0x8 * (n) + 0xa00)
|
||||
#define MV_WIN_CESA_MAX 4
|
||||
|
||||
#define MV_WIN_USB_CTRL(n, m) (0x10 * (n) + (m) * 0x1000 + 0x0)
|
||||
#define MV_WIN_USB_BASE(n, m) (0x10 * (n) + (m) * 0x1000 + 0x4)
|
||||
#define MV_WIN_USB_MAX 4
|
||||
|
||||
#define MV_WIN_ETH_BASE(n) (0x8 * (n) + 0x200)
|
||||
@ -492,6 +514,15 @@
|
||||
#define MV_WIN_IDMA_MAX 8
|
||||
#define MV_IDMA_CHAN_MAX 4
|
||||
|
||||
#define MV_WIN_XOR_BASE(n, m) (0x4 * (n) + 0xa50 + (m) * 0x100)
|
||||
#define MV_WIN_XOR_SIZE(n, m) (0x4 * (n) + 0xa70 + (m) * 0x100)
|
||||
#define MV_WIN_XOR_REMAP(n, m) (0x4 * (n) + 0xa90 + (m) * 0x100)
|
||||
#define MV_WIN_XOR_CTRL(n, m) (0x4 * (n) + 0xa40 + (m) * 0x100)
|
||||
#define MV_WIN_XOR_OVERR(n, m) (0x4 * (n) + 0xaa0 + (m) * 0x100)
|
||||
#define MV_WIN_XOR_MAX 8
|
||||
#define MV_XOR_CHAN_MAX 2
|
||||
#define MV_XOR_NON_REMAP 4
|
||||
|
||||
#define MV_WIN_PCIE_CTRL(n) (0x10 * (((n) < 5) ? (n) : \
|
||||
(n) + 1) + 0x1820)
|
||||
#define MV_WIN_PCIE_BASE(n) (0x10 * (((n) < 5) ? (n) : \
|
||||
@ -503,6 +534,10 @@
|
||||
#define MV_PCIE_BAR(n) (0x04 * (n) + 0x1804)
|
||||
#define MV_PCIE_BAR_MAX 3
|
||||
|
||||
#define MV_WIN_SATA_CTRL(n) (0x10 * (n) + 0x30)
|
||||
#define MV_WIN_SATA_BASE(n) (0x10 * (n) + 0x34)
|
||||
#define MV_WIN_SATA_MAX 4
|
||||
|
||||
#define WIN_REG_IDX_RD(pre,reg,off,base) \
|
||||
static __inline uint32_t \
|
||||
pre ## _ ## reg ## _read(int i) \
|
||||
@ -510,6 +545,13 @@
|
||||
return (bus_space_read_4(obio_tag, base, off(i))); \
|
||||
}
|
||||
|
||||
#define WIN_REG_IDX_RD2(pre,reg,off,base) \
|
||||
static __inline uint32_t \
|
||||
pre ## _ ## reg ## _read(int i, int j) \
|
||||
{ \
|
||||
return (bus_space_read_4(obio_tag, base, off(i, j))); \
|
||||
} \
|
||||
|
||||
#define WIN_REG_BASE_IDX_RD(pre,reg,off) \
|
||||
static __inline uint32_t \
|
||||
pre ## _ ## reg ## _read(uint32_t base, int i) \
|
||||
@ -524,6 +566,13 @@
|
||||
bus_space_write_4(obio_tag, base, off(i), val); \
|
||||
}
|
||||
|
||||
#define WIN_REG_IDX_WR2(pre,reg,off,base) \
|
||||
static __inline void \
|
||||
pre ## _ ## reg ## _write(int i, int j, uint32_t val) \
|
||||
{ \
|
||||
bus_space_write_4(obio_tag, base, off(i, j), val); \
|
||||
}
|
||||
|
||||
#define WIN_REG_BASE_IDX_WR(pre,reg,off) \
|
||||
static __inline void \
|
||||
pre ## _ ## reg ## _write(uint32_t base, int i, uint32_t val) \
|
||||
|
@ -86,6 +86,12 @@ struct obio_pci {
|
||||
int op_irq; /* used if callback is NULL */
|
||||
};
|
||||
|
||||
struct gpio_config {
|
||||
int gc_gpio; /* GPIO number */
|
||||
uint32_t gc_flags; /* GPIO flags */
|
||||
int gc_output; /* GPIO output value */
|
||||
};
|
||||
|
||||
struct decode_win {
|
||||
int target; /* Mbus unit ID */
|
||||
int attr; /* Attributes of the target interface */
|
||||
@ -95,12 +101,15 @@ struct decode_win {
|
||||
};
|
||||
|
||||
extern const struct obio_pci mv_pci_info[];
|
||||
extern const struct gpio_config mv_gpio_config[];
|
||||
extern bus_space_tag_t obio_tag;
|
||||
extern struct obio_device obio_devices[];
|
||||
extern const struct decode_win *cpu_wins;
|
||||
extern const struct decode_win *idma_wins;
|
||||
extern const struct decode_win *xor_wins;
|
||||
extern int cpu_wins_no;
|
||||
extern int idma_wins_no;
|
||||
extern int xor_wins_no;
|
||||
|
||||
/* Function prototypes */
|
||||
int mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
|
||||
@ -112,6 +121,7 @@ void mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable);
|
||||
uint8_t mv_gpio_in(uint32_t pin);
|
||||
|
||||
int platform_pmap_init(void);
|
||||
void platform_mpp_init(void);
|
||||
int soc_decode_win(void);
|
||||
void soc_id(uint32_t *dev, uint32_t *rev);
|
||||
void soc_identify(void);
|
||||
@ -127,6 +137,10 @@ void decode_win_idma_dump(void);
|
||||
void decode_win_idma_setup(void);
|
||||
int decode_win_idma_valid(void);
|
||||
|
||||
void decode_win_xor_dump(void);
|
||||
void decode_win_xor_setup(void);
|
||||
int decode_win_xor_valid(void);
|
||||
|
||||
int ddr_is_active(int i);
|
||||
uint32_t ddr_base(int i);
|
||||
uint32_t ddr_size(int i);
|
||||
|
@ -131,8 +131,7 @@ mbus_print_child(device_t dev, device_t child)
|
||||
if (od == NULL)
|
||||
panic("Unknown device on %s", device_get_nameunit(dev));
|
||||
|
||||
rv = 0;
|
||||
rv += bus_print_child_header(dev, child);
|
||||
rv = bus_print_child_header(dev, child);
|
||||
|
||||
rv += resource_list_print_type(&od->od_resources, "at mem",
|
||||
SYS_RES_MEMORY, "0x%08lx");
|
||||
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/vmparam.h>
|
||||
@ -146,12 +147,44 @@ int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin)
|
||||
* away once we set up GPIO in a generic way in a proper place (TBD).
|
||||
*/
|
||||
if (irq >= 0)
|
||||
mv_gpio_configure(IRQ2GPIO(irq), MV_GPIO_POLARITY |
|
||||
mv_gpio_configure(IRQ2GPIO(irq), MV_GPIO_POLAR_LOW |
|
||||
MV_GPIO_LEVEL, ~0u);
|
||||
|
||||
return (irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* mv_gpio_config row structure:
|
||||
* <GPIO number>, <GPIO flags>, <GPIO mode>
|
||||
*
|
||||
* - GPIO pin number (less than zero marks end of table)
|
||||
* - GPIO flags:
|
||||
* MV_GPIO_BLINK
|
||||
* MV_GPIO_POLAR_LOW
|
||||
* MV_GPIO_EDGE
|
||||
* MV_GPIO_LEVEL
|
||||
* - GPIO mode:
|
||||
* 1 - Output, set to HIGH.
|
||||
* 0 - Output, set to LOW.
|
||||
* -1 - Input.
|
||||
*/
|
||||
|
||||
/* GPIO Configuration for DB-88F5281 */
|
||||
const struct gpio_config mv_gpio_config[] = {
|
||||
{ 12, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
|
||||
{ 13, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
|
||||
{ -1, -1, -1 }
|
||||
};
|
||||
|
||||
#if 0
|
||||
/* GPIO Configuration for DB-88F5182 */
|
||||
const struct gpio_config mv_gpio_config[] = {
|
||||
{ 0, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
|
||||
{ 1, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
|
||||
{ -1, -1, -1 }
|
||||
};
|
||||
#endif
|
||||
|
||||
int
|
||||
platform_pmap_init(void)
|
||||
{
|
||||
@ -162,6 +195,63 @@ platform_pmap_init(void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
platform_mpp_init(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* MPP configuration for DB-88F5281
|
||||
*
|
||||
* MPP[2]: PCI_REQn[3]
|
||||
* MPP[3]: PCI_GNTn[3]
|
||||
* MPP[4]: PCI_REQn[4]
|
||||
* MPP[5]: PCI_GNTn[4]
|
||||
* MPP[6]: <UNKNOWN>
|
||||
* MPP[7]: <UNKNOWN>
|
||||
* MPP[8]: <UNKNOWN>
|
||||
* MPP[9]: <UNKNOWN>
|
||||
* MPP[14]: NAND Flash REn[2]
|
||||
* MPP[15]: NAND Flash WEn[2]
|
||||
* MPP[16]: UA1_RXD
|
||||
* MPP[17]: UA1_TXD
|
||||
* MPP[18]: UA1_CTS
|
||||
* MPP[19]: UA1_RTS
|
||||
*
|
||||
* Others: GPIO
|
||||
*
|
||||
* <UNKNOWN> entries are not documented, not on the schematics etc.
|
||||
*/
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x33222203);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x44000033);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00000000);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* MPP configuration for DB-88F5182
|
||||
*
|
||||
* MPP[2]: PCI_REQn[3]
|
||||
* MPP[3]: PCI_GNTn[3]
|
||||
* MPP[4]: PCI_REQn[4]
|
||||
* MPP[5]: PCI_GNTn[4]
|
||||
* MPP[6]: SATA0_ACT
|
||||
* MPP[7]: SATA1_ACT
|
||||
* MPP[12]: SATA0_PRESENT
|
||||
* MPP[13]: SATA1_PRESENT
|
||||
* MPP[14]: NAND_FLASH_REn[2]
|
||||
* MPP[15]: NAND_FLASH_WEn[2]
|
||||
* MPP[16]: UA1_RXD
|
||||
* MPP[17]: UA1_TXD
|
||||
* MPP[18]: UA1_CTS
|
||||
* MPP[19]: UA1_RTS
|
||||
*
|
||||
* Others: GPIO
|
||||
*/
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x55222203);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x44550000);
|
||||
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00000000);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
platform_identify(void *dummy)
|
||||
{
|
||||
@ -174,7 +264,3 @@ platform_identify(void *dummy)
|
||||
*/
|
||||
}
|
||||
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
|
||||
|
||||
/*
|
||||
* TODO routine setting GPIO/MPP pins
|
||||
*/
|
||||
|
@ -112,7 +112,7 @@ const struct obio_pci mv_pci_info[] = {
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
struct resource_spec mv_gpio_spec[] = {
|
||||
struct resource_spec mv_gpio_res[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 1, RF_ACTIVE },
|
||||
|
Loading…
x
Reference in New Issue
Block a user