in bridges/vme_ca91cx42.c [333:437]
static int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
unsigned long long vme_base, unsigned long long size,
dma_addr_t pci_base, u32 aspace, u32 cycle)
{
unsigned int i, addr = 0, granularity;
unsigned int temp_ctl = 0;
unsigned int vme_bound, pci_offset;
struct vme_bridge *ca91cx42_bridge;
struct ca91cx42_driver *bridge;
ca91cx42_bridge = image->parent;
bridge = ca91cx42_bridge->driver_priv;
i = image->number;
switch (aspace) {
case VME_A16:
addr |= CA91CX42_VSI_CTL_VAS_A16;
break;
case VME_A24:
addr |= CA91CX42_VSI_CTL_VAS_A24;
break;
case VME_A32:
addr |= CA91CX42_VSI_CTL_VAS_A32;
break;
case VME_USER1:
addr |= CA91CX42_VSI_CTL_VAS_USER1;
break;
case VME_USER2:
addr |= CA91CX42_VSI_CTL_VAS_USER2;
break;
case VME_A64:
case VME_CRCSR:
case VME_USER3:
case VME_USER4:
default:
dev_err(ca91cx42_bridge->parent, "Invalid address space\n");
return -EINVAL;
break;
}
/*
* Bound address is a valid address for the window, adjust
* accordingly
*/
vme_bound = vme_base + size;
pci_offset = pci_base - vme_base;
if ((i == 0) || (i == 4))
granularity = 0x1000;
else
granularity = 0x10000;
if (vme_base & (granularity - 1)) {
dev_err(ca91cx42_bridge->parent, "Invalid VME base "
"alignment\n");
return -EINVAL;
}
if (vme_bound & (granularity - 1)) {
dev_err(ca91cx42_bridge->parent, "Invalid VME bound "
"alignment\n");
return -EINVAL;
}
if (pci_offset & (granularity - 1)) {
dev_err(ca91cx42_bridge->parent, "Invalid PCI Offset "
"alignment\n");
return -EINVAL;
}
/* Disable while we are mucking around */
temp_ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]);
temp_ctl &= ~CA91CX42_VSI_CTL_EN;
iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
/* Setup mapping */
iowrite32(vme_base, bridge->base + CA91CX42_VSI_BS[i]);
iowrite32(vme_bound, bridge->base + CA91CX42_VSI_BD[i]);
iowrite32(pci_offset, bridge->base + CA91CX42_VSI_TO[i]);
/* Setup address space */
temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M;
temp_ctl |= addr;
/* Setup cycle types */
temp_ctl &= ~(CA91CX42_VSI_CTL_PGM_M | CA91CX42_VSI_CTL_SUPER_M);
if (cycle & VME_SUPER)
temp_ctl |= CA91CX42_VSI_CTL_SUPER_SUPR;
if (cycle & VME_USER)
temp_ctl |= CA91CX42_VSI_CTL_SUPER_NPRIV;
if (cycle & VME_PROG)
temp_ctl |= CA91CX42_VSI_CTL_PGM_PGM;
if (cycle & VME_DATA)
temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA;
/* Write ctl reg without enable */
iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
if (enabled)
temp_ctl |= CA91CX42_VSI_CTL_EN;
iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
return 0;
}