]> Pileus Git - ~andy/linux/blobdiff - drivers/parisc/sba_iommu.c
parisc: fix partly 16/64k PAGE_SIZE boot
[~andy/linux] / drivers / parisc / sba_iommu.c
index 42cfcd9eb9aaeb3e8239e646a2634c4b23c54003..1ff1b67e8b274cc6869aab822694a1859954e132 100644 (file)
@@ -575,7 +575,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
 
        mtsp(sid,1);
        asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
-       pa |= (ci >> 12) & 0xff;  /* move CI (8 bits) into lowest byte */
+       pa |= (ci >> PAGE_SHIFT) & 0xff;  /* move CI (8 bits) into lowest byte */
 
        pa |= SBA_PDIR_VALID_BIT;       /* set "valid" bit */
        *pdir_ptr = cpu_to_le64(pa);    /* swap and store into I/O Pdir */
@@ -1376,7 +1376,7 @@ static void
 sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
 {
        u32 iova_space_size, iova_space_mask;
-       unsigned int pdir_size, iov_order;
+       unsigned int pdir_size, iov_order, tcnfg;
 
        /*
        ** Determine IOVA Space size from memory size.
@@ -1468,8 +1468,19 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
        WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa+IOC_IBASE);
        WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
 
-       /* Set I/O PDIR Page size to 4K */
-       WRITE_REG(0, ioc->ioc_hpa+IOC_TCNFG);
+       /* Set I/O PDIR Page size to system page size */
+       switch (PAGE_SHIFT) {
+               case 12: tcnfg = 0; break;      /*  4K */
+               case 13: tcnfg = 1; break;      /*  8K */
+               case 14: tcnfg = 2; break;      /* 16K */
+               case 16: tcnfg = 3; break;      /* 64K */
+               default:
+                       panic(__FILE__ "Unsupported system page size %d",
+                               1 << PAGE_SHIFT);
+                       break;
+       }
+       /* Set I/O PDIR Page size to PAGE_SIZE (4k/16k/...) */
+       WRITE_REG(tcnfg, ioc->ioc_hpa+IOC_TCNFG);
 
        /*
        ** Clear I/O TLB of any possible entries.