Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/fsl_pamu: remove support for multiple windows

The only domains allocated forces use of a single window. Remove all
the code related to multiple window support, as well as the need for
qman_portal to force a single window.

Remove the now unused DOMAIN_ATTR_WINDOWS iommu_attr.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Li Yang <leoyang.li@nxp.com>
Link: https://lore.kernel.org/r/20210401155256.298656-6-hch@lst.de
Signed-off-by: Joerg Roedel <jroedel@suse.de>

authored by

Christoph Hellwig and committed by
Joerg Roedel
ba58d121 c8224508

+60 -513
+8 -256
drivers/iommu/fsl_pamu.c
··· 63 63 /* maximum subwindows permitted per liodn */ 64 64 static u32 max_subwindow_count; 65 65 66 - /* Pool for fspi allocation */ 67 - static struct gen_pool *spaace_pool; 68 - 69 - /** 70 - * pamu_get_max_subwin_cnt() - Return the maximum supported 71 - * subwindow count per liodn. 72 - * 73 - */ 74 - u32 pamu_get_max_subwin_cnt(void) 75 - { 76 - return max_subwindow_count; 77 - } 78 - 79 66 /** 80 67 * pamu_get_ppaace() - Return the primary PACCE 81 68 * @liodn: liodn PAACT index for desired PAACE ··· 142 155 return fls64(addrspace_size) - 2; 143 156 } 144 157 145 - /* Derive the PAACE window count encoding for the subwindow count */ 146 - static unsigned int map_subwindow_cnt_to_wce(u32 subwindow_cnt) 147 - { 148 - /* window count is 2^(WCE+1) bytes */ 149 - return __ffs(subwindow_cnt) - 1; 150 - } 151 - 152 158 /* 153 159 * Set the PAACE type as primary and set the coherency required domain 154 160 * attribute ··· 155 175 } 156 176 157 177 /* 158 - * Set the PAACE type as secondary and set the coherency required domain 159 - * attribute. 160 - */ 161 - static void pamu_init_spaace(struct paace *spaace) 162 - { 163 - set_bf(spaace->addr_bitfields, PAACE_AF_PT, PAACE_PT_SECONDARY); 164 - set_bf(spaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR, 165 - PAACE_M_COHERENCE_REQ); 166 - } 167 - 168 - /* 169 - * Return the spaace (corresponding to the secondary window index) 170 - * for a particular ppaace. 171 - */ 172 - static struct paace *pamu_get_spaace(struct paace *paace, u32 wnum) 173 - { 174 - u32 subwin_cnt; 175 - struct paace *spaace = NULL; 176 - 177 - subwin_cnt = 1UL << (get_bf(paace->impl_attr, PAACE_IA_WCE) + 1); 178 - 179 - if (wnum < subwin_cnt) 180 - spaace = &spaact[paace->fspi + wnum]; 181 - else 182 - pr_debug("secondary paace out of bounds\n"); 183 - 184 - return spaace; 185 - } 186 - 187 - /** 188 - * pamu_get_fspi_and_allocate() - Allocates fspi index and reserves subwindows 189 - * required for primary PAACE in the secondary 190 - * PAACE table. 191 - * @subwin_cnt: Number of subwindows to be reserved. 192 - * 193 - * A PPAACE entry may have a number of associated subwindows. A subwindow 194 - * corresponds to a SPAACE entry in the SPAACT table. Each PAACE entry stores 195 - * the index (fspi) of the first SPAACE entry in the SPAACT table. This 196 - * function returns the index of the first SPAACE entry. The remaining 197 - * SPAACE entries are reserved contiguously from that index. 198 - * 199 - * Returns a valid fspi index in the range of 0 - SPAACE_NUMBER_ENTRIES on success. 200 - * If no SPAACE entry is available or the allocator can not reserve the required 201 - * number of contiguous entries function returns ULONG_MAX indicating a failure. 202 - * 203 - */ 204 - static unsigned long pamu_get_fspi_and_allocate(u32 subwin_cnt) 205 - { 206 - unsigned long spaace_addr; 207 - 208 - spaace_addr = gen_pool_alloc(spaace_pool, subwin_cnt * sizeof(struct paace)); 209 - if (!spaace_addr) 210 - return ULONG_MAX; 211 - 212 - return (spaace_addr - (unsigned long)spaact) / (sizeof(struct paace)); 213 - } 214 - 215 - /* Release the subwindows reserved for a particular LIODN */ 216 - void pamu_free_subwins(int liodn) 217 - { 218 - struct paace *ppaace; 219 - u32 subwin_cnt, size; 220 - 221 - ppaace = pamu_get_ppaace(liodn); 222 - if (!ppaace) { 223 - pr_debug("Invalid liodn entry\n"); 224 - return; 225 - } 226 - 227 - if (get_bf(ppaace->addr_bitfields, PPAACE_AF_MW)) { 228 - subwin_cnt = 1UL << (get_bf(ppaace->impl_attr, PAACE_IA_WCE) + 1); 229 - size = (subwin_cnt - 1) * sizeof(struct paace); 230 - gen_pool_free(spaace_pool, (unsigned long)&spaact[ppaace->fspi], size); 231 - set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0); 232 - } 233 - } 234 - 235 - /* 236 178 * Function used for updating stash destination for the coressponding 237 179 * LIODN. 238 180 */ 239 - int pamu_update_paace_stash(int liodn, u32 subwin, u32 value) 181 + int pamu_update_paace_stash(int liodn, u32 value) 240 182 { 241 183 struct paace *paace; 242 184 ··· 166 264 if (!paace) { 167 265 pr_debug("Invalid liodn entry\n"); 168 266 return -ENOENT; 169 - } 170 - if (subwin) { 171 - paace = pamu_get_spaace(paace, subwin - 1); 172 - if (!paace) 173 - return -ENOENT; 174 267 } 175 268 set_bf(paace->impl_attr, PAACE_IA_CID, value); 176 - 177 - mb(); 178 - 179 - return 0; 180 - } 181 - 182 - /* Disable a subwindow corresponding to the LIODN */ 183 - int pamu_disable_spaace(int liodn, u32 subwin) 184 - { 185 - struct paace *paace; 186 - 187 - paace = pamu_get_ppaace(liodn); 188 - if (!paace) { 189 - pr_debug("Invalid liodn entry\n"); 190 - return -ENOENT; 191 - } 192 - if (subwin) { 193 - paace = pamu_get_spaace(paace, subwin - 1); 194 - if (!paace) 195 - return -ENOENT; 196 - set_bf(paace->addr_bitfields, PAACE_AF_V, PAACE_V_INVALID); 197 - } else { 198 - set_bf(paace->addr_bitfields, PAACE_AF_AP, 199 - PAACE_AP_PERMS_DENIED); 200 - } 201 269 202 270 mb(); 203 271 ··· 186 314 * stashid not defined 187 315 * @snoopid: snoop id for hardware coherency -- if ~snoopid == 0 then 188 316 * snoopid not defined 189 - * @subwin_cnt: number of sub-windows 190 317 * @prot: window permissions 191 318 * 192 319 * Returns 0 upon success else error code < 0 returned 193 320 */ 194 321 int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size, 195 322 u32 omi, unsigned long rpn, u32 snoopid, u32 stashid, 196 - u32 subwin_cnt, int prot) 323 + int prot) 197 324 { 198 325 struct paace *ppaace; 199 - unsigned long fspi; 200 326 201 327 if ((win_size & (win_size - 1)) || win_size < PAMU_PAGE_SIZE) { 202 328 pr_debug("window size too small or not a power of two %pa\n", ··· 238 368 if (~snoopid != 0) 239 369 ppaace->domain_attr.to_host.snpid = snoopid; 240 370 241 - if (subwin_cnt) { 242 - /* The first entry is in the primary PAACE instead */ 243 - fspi = pamu_get_fspi_and_allocate(subwin_cnt - 1); 244 - if (fspi == ULONG_MAX) { 245 - pr_debug("spaace indexes exhausted\n"); 246 - return -EINVAL; 247 - } 248 - 249 - /* window count is 2^(WCE+1) bytes */ 250 - set_bf(ppaace->impl_attr, PAACE_IA_WCE, 251 - map_subwindow_cnt_to_wce(subwin_cnt)); 252 - set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0x1); 253 - ppaace->fspi = fspi; 254 - } else { 255 - set_bf(ppaace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE); 256 - ppaace->twbah = rpn >> 20; 257 - set_bf(ppaace->win_bitfields, PAACE_WIN_TWBAL, rpn); 258 - set_bf(ppaace->addr_bitfields, PAACE_AF_AP, prot); 259 - set_bf(ppaace->impl_attr, PAACE_IA_WCE, 0); 260 - set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0); 261 - } 262 - mb(); 263 - 264 - return 0; 265 - } 266 - 267 - /** 268 - * pamu_config_spaace() - Sets up SPAACE entry for specified subwindow 269 - * 270 - * @liodn: Logical IO device number 271 - * @subwin_cnt: number of sub-windows associated with dma-window 272 - * @subwin: subwindow index 273 - * @subwin_size: size of subwindow 274 - * @omi: Operation mapping index 275 - * @rpn: real (true physical) page number 276 - * @snoopid: snoop id for hardware coherency -- if ~snoopid == 0 then 277 - * snoopid not defined 278 - * @stashid: cache stash id for associated cpu 279 - * @enable: enable/disable subwindow after reconfiguration 280 - * @prot: sub window permissions 281 - * 282 - * Returns 0 upon success else error code < 0 returned 283 - */ 284 - int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin, 285 - phys_addr_t subwin_size, u32 omi, unsigned long rpn, 286 - u32 snoopid, u32 stashid, int enable, int prot) 287 - { 288 - struct paace *paace; 289 - 290 - /* setup sub-windows */ 291 - if (!subwin_cnt) { 292 - pr_debug("Invalid subwindow count\n"); 293 - return -EINVAL; 294 - } 295 - 296 - paace = pamu_get_ppaace(liodn); 297 - if (subwin > 0 && subwin < subwin_cnt && paace) { 298 - paace = pamu_get_spaace(paace, subwin - 1); 299 - 300 - if (paace && !(paace->addr_bitfields & PAACE_V_VALID)) { 301 - pamu_init_spaace(paace); 302 - set_bf(paace->addr_bitfields, SPAACE_AF_LIODN, liodn); 303 - } 304 - } 305 - 306 - if (!paace) { 307 - pr_debug("Invalid liodn entry\n"); 308 - return -ENOENT; 309 - } 310 - 311 - if ((subwin_size & (subwin_size - 1)) || subwin_size < PAMU_PAGE_SIZE) { 312 - pr_debug("subwindow size out of range, or not a power of 2\n"); 313 - return -EINVAL; 314 - } 315 - 316 - if (rpn == ULONG_MAX) { 317 - pr_debug("real page number out of range\n"); 318 - return -EINVAL; 319 - } 320 - 321 - /* window size is 2^(WSE+1) bytes */ 322 - set_bf(paace->win_bitfields, PAACE_WIN_SWSE, 323 - map_addrspace_size_to_wse(subwin_size)); 324 - 325 - set_bf(paace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE); 326 - paace->twbah = rpn >> 20; 327 - set_bf(paace->win_bitfields, PAACE_WIN_TWBAL, rpn); 328 - set_bf(paace->addr_bitfields, PAACE_AF_AP, prot); 329 - 330 - /* configure snoop id */ 331 - if (~snoopid != 0) 332 - paace->domain_attr.to_host.snpid = snoopid; 333 - 334 - /* set up operation mapping if it's configured */ 335 - if (omi < OME_NUMBER_ENTRIES) { 336 - set_bf(paace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED); 337 - paace->op_encode.index_ot.omi = omi; 338 - } else if (~omi != 0) { 339 - pr_debug("bad operation mapping index: %d\n", omi); 340 - return -EINVAL; 341 - } 342 - 343 - if (~stashid != 0) 344 - set_bf(paace->impl_attr, PAACE_IA_CID, stashid); 345 - 346 - smp_wmb(); 347 - 348 - if (enable) 349 - set_bf(paace->addr_bitfields, PAACE_AF_V, PAACE_V_VALID); 350 - 371 + set_bf(ppaace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE); 372 + ppaace->twbah = rpn >> 20; 373 + set_bf(ppaace->win_bitfields, PAACE_WIN_TWBAL, rpn); 374 + set_bf(ppaace->addr_bitfields, PAACE_AF_AP, prot); 375 + set_bf(ppaace->impl_attr, PAACE_IA_WCE, 0); 376 + set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0); 351 377 mb(); 352 378 353 379 return 0; ··· 895 1129 spaact_phys = virt_to_phys(spaact); 896 1130 omt_phys = virt_to_phys(omt); 897 1131 898 - spaace_pool = gen_pool_create(ilog2(sizeof(struct paace)), -1); 899 - if (!spaace_pool) { 900 - ret = -ENOMEM; 901 - dev_err(dev, "Failed to allocate spaace gen pool\n"); 902 - goto error; 903 - } 904 - 905 - ret = gen_pool_add(spaace_pool, (unsigned long)spaact, SPAACT_SIZE, -1); 906 - if (ret) 907 - goto error_genpool; 908 - 909 1132 pamubypenr = in_be32(&guts_regs->pamubypenr); 910 1133 911 1134 for (pamu_reg_off = 0, pamu_counter = 0x80000000; pamu_reg_off < size; ··· 921 1166 probed = true; 922 1167 923 1168 return 0; 924 - 925 - error_genpool: 926 - gen_pool_destroy(spaace_pool); 927 1169 928 1170 error: 929 1171 if (irq != NO_IRQ)
+2 -8
drivers/iommu/fsl_pamu.h
··· 383 383 int pamu_domain_init(void); 384 384 int pamu_enable_liodn(int liodn); 385 385 int pamu_disable_liodn(int liodn); 386 - void pamu_free_subwins(int liodn); 387 386 int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size, 388 387 u32 omi, unsigned long rpn, u32 snoopid, uint32_t stashid, 389 - u32 subwin_cnt, int prot); 390 - int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin_addr, 391 - phys_addr_t subwin_size, u32 omi, unsigned long rpn, 392 - uint32_t snoopid, u32 stashid, int enable, int prot); 388 + int prot); 393 389 394 390 u32 get_stash_id(u32 stash_dest_hint, u32 vcpu); 395 391 void get_ome_index(u32 *omi_index, struct device *dev); 396 - int pamu_update_paace_stash(int liodn, u32 subwin, u32 value); 397 - int pamu_disable_spaace(int liodn, u32 subwin); 398 - u32 pamu_get_max_subwin_cnt(void); 392 + int pamu_update_paace_stash(int liodn, u32 value); 399 393 400 394 #endif /* __FSL_PAMU_H */
+48 -227
drivers/iommu/fsl_pamu_domain.c
··· 56 56 57 57 static phys_addr_t get_phys_addr(struct fsl_dma_domain *dma_domain, dma_addr_t iova) 58 58 { 59 - u32 win_cnt = dma_domain->win_cnt; 60 59 struct dma_window *win_ptr = &dma_domain->win_arr[0]; 61 60 struct iommu_domain_geometry *geom; 62 61 63 62 geom = &dma_domain->iommu_domain.geometry; 64 - 65 - if (!win_cnt) { 66 - pr_debug("Number of windows/geometry not configured for the domain\n"); 67 - return 0; 68 - } 69 - 70 - if (win_cnt > 1) { 71 - u64 subwin_size; 72 - dma_addr_t subwin_iova; 73 - u32 wnd; 74 - 75 - subwin_size = (geom->aperture_end + 1) >> ilog2(win_cnt); 76 - subwin_iova = iova & ~(subwin_size - 1); 77 - wnd = (subwin_iova - geom->aperture_start) >> ilog2(subwin_size); 78 - win_ptr = &dma_domain->win_arr[wnd]; 79 - } 80 63 81 64 if (win_ptr->valid) 82 65 return win_ptr->paddr + (iova & (win_ptr->size - 1)); ··· 67 84 return 0; 68 85 } 69 86 70 - static int map_subwins(int liodn, struct fsl_dma_domain *dma_domain) 71 - { 72 - struct dma_window *sub_win_ptr = &dma_domain->win_arr[0]; 73 - int i, ret; 74 - unsigned long rpn, flags; 75 - 76 - for (i = 0; i < dma_domain->win_cnt; i++) { 77 - if (sub_win_ptr[i].valid) { 78 - rpn = sub_win_ptr[i].paddr >> PAMU_PAGE_SHIFT; 79 - spin_lock_irqsave(&iommu_lock, flags); 80 - ret = pamu_config_spaace(liodn, dma_domain->win_cnt, i, 81 - sub_win_ptr[i].size, 82 - ~(u32)0, 83 - rpn, 84 - dma_domain->snoop_id, 85 - dma_domain->stash_id, 86 - (i > 0) ? 1 : 0, 87 - sub_win_ptr[i].prot); 88 - spin_unlock_irqrestore(&iommu_lock, flags); 89 - if (ret) { 90 - pr_debug("SPAACE configuration failed for liodn %d\n", 91 - liodn); 92 - return ret; 93 - } 94 - } 95 - } 96 - 97 - return ret; 98 - } 99 - 100 - static int map_win(int liodn, struct fsl_dma_domain *dma_domain) 87 + /* Map the DMA window corresponding to the LIODN */ 88 + static int map_liodn(int liodn, struct fsl_dma_domain *dma_domain) 101 89 { 102 90 int ret; 103 91 struct dma_window *wnd = &dma_domain->win_arr[0]; ··· 81 127 ~(u32)0, 82 128 wnd->paddr >> PAMU_PAGE_SHIFT, 83 129 dma_domain->snoop_id, dma_domain->stash_id, 84 - 0, wnd->prot); 130 + wnd->prot); 85 131 spin_unlock_irqrestore(&iommu_lock, flags); 86 132 if (ret) 87 133 pr_debug("PAACE configuration failed for liodn %d\n", liodn); ··· 89 135 return ret; 90 136 } 91 137 92 - /* Map the DMA window corresponding to the LIODN */ 93 - static int map_liodn(int liodn, struct fsl_dma_domain *dma_domain) 94 - { 95 - if (dma_domain->win_cnt > 1) 96 - return map_subwins(liodn, dma_domain); 97 - else 98 - return map_win(liodn, dma_domain); 99 - } 100 - 101 138 /* Update window/subwindow mapping for the LIODN */ 102 139 static int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32 wnd_nr) 103 140 { 104 141 int ret; 105 142 struct dma_window *wnd = &dma_domain->win_arr[wnd_nr]; 143 + phys_addr_t wnd_addr; 106 144 unsigned long flags; 107 145 108 146 spin_lock_irqsave(&iommu_lock, flags); 109 - if (dma_domain->win_cnt > 1) { 110 - ret = pamu_config_spaace(liodn, dma_domain->win_cnt, wnd_nr, 111 - wnd->size, 112 - ~(u32)0, 113 - wnd->paddr >> PAMU_PAGE_SHIFT, 114 - dma_domain->snoop_id, 115 - dma_domain->stash_id, 116 - (wnd_nr > 0) ? 1 : 0, 117 - wnd->prot); 118 - if (ret) 119 - pr_debug("Subwindow reconfiguration failed for liodn %d\n", 120 - liodn); 121 - } else { 122 - phys_addr_t wnd_addr; 123 147 124 - wnd_addr = dma_domain->iommu_domain.geometry.aperture_start; 148 + wnd_addr = dma_domain->iommu_domain.geometry.aperture_start; 125 149 126 - ret = pamu_config_ppaace(liodn, wnd_addr, 127 - wnd->size, 128 - ~(u32)0, 129 - wnd->paddr >> PAMU_PAGE_SHIFT, 130 - dma_domain->snoop_id, dma_domain->stash_id, 131 - 0, wnd->prot); 132 - if (ret) 133 - pr_debug("Window reconfiguration failed for liodn %d\n", 134 - liodn); 135 - } 150 + ret = pamu_config_ppaace(liodn, wnd_addr, 151 + wnd->size, 152 + ~(u32)0, 153 + wnd->paddr >> PAMU_PAGE_SHIFT, 154 + dma_domain->snoop_id, dma_domain->stash_id, 155 + wnd->prot); 156 + if (ret) 157 + pr_debug("Window reconfiguration failed for liodn %d\n", 158 + liodn); 136 159 137 160 spin_unlock_irqrestore(&iommu_lock, flags); 138 161 ··· 123 192 unsigned long flags; 124 193 125 194 spin_lock_irqsave(&iommu_lock, flags); 126 - if (!dma_domain->win_arr) { 127 - pr_debug("Windows not configured, stash destination update failed for liodn %d\n", 128 - liodn); 195 + ret = pamu_update_paace_stash(liodn, val); 196 + if (ret) { 197 + pr_debug("Failed to update SPAACE %d field for liodn %d\n ", 198 + i, liodn); 129 199 spin_unlock_irqrestore(&iommu_lock, flags); 130 - return -EINVAL; 131 - } 132 - 133 - for (i = 0; i < dma_domain->win_cnt; i++) { 134 - ret = pamu_update_paace_stash(liodn, i, val); 135 - if (ret) { 136 - pr_debug("Failed to update SPAACE %d field for liodn %d\n ", 137 - i, liodn); 138 - spin_unlock_irqrestore(&iommu_lock, flags); 139 - return ret; 140 - } 200 + return ret; 141 201 } 142 202 143 203 spin_unlock_irqrestore(&iommu_lock, flags); ··· 139 217 /* Set the geometry parameters for a LIODN */ 140 218 static int pamu_set_liodn(int liodn, struct device *dev, 141 219 struct fsl_dma_domain *dma_domain, 142 - struct iommu_domain_geometry *geom_attr, 143 - u32 win_cnt) 220 + struct iommu_domain_geometry *geom_attr) 144 221 { 145 222 phys_addr_t window_addr, window_size; 146 - phys_addr_t subwin_size; 147 - int ret = 0, i; 148 223 u32 omi_index = ~(u32)0; 149 224 unsigned long flags; 225 + int ret; 150 226 151 227 /* 152 228 * Configure the omi_index at the geometry setup time. ··· 161 241 if (!ret) 162 242 ret = pamu_config_ppaace(liodn, window_addr, window_size, omi_index, 163 243 0, dma_domain->snoop_id, 164 - dma_domain->stash_id, win_cnt, 0); 244 + dma_domain->stash_id, 0); 165 245 spin_unlock_irqrestore(&iommu_lock, flags); 166 246 if (ret) { 167 - pr_debug("PAACE configuration failed for liodn %d, win_cnt =%d\n", 168 - liodn, win_cnt); 247 + pr_debug("PAACE configuration failed for liodn %d\n", 248 + liodn); 169 249 return ret; 170 - } 171 - 172 - if (win_cnt > 1) { 173 - subwin_size = window_size >> ilog2(win_cnt); 174 - for (i = 0; i < win_cnt; i++) { 175 - spin_lock_irqsave(&iommu_lock, flags); 176 - ret = pamu_disable_spaace(liodn, i); 177 - if (!ret) 178 - ret = pamu_config_spaace(liodn, win_cnt, i, 179 - subwin_size, omi_index, 180 - 0, dma_domain->snoop_id, 181 - dma_domain->stash_id, 182 - 0, 0); 183 - spin_unlock_irqrestore(&iommu_lock, flags); 184 - if (ret) { 185 - pr_debug("SPAACE configuration failed for liodn %d\n", 186 - liodn); 187 - return ret; 188 - } 189 - } 190 250 } 191 251 192 252 return ret; ··· 192 292 return 0; 193 293 } 194 294 195 - static void remove_device_ref(struct device_domain_info *info, u32 win_cnt) 295 + static void remove_device_ref(struct device_domain_info *info) 196 296 { 197 297 unsigned long flags; 198 298 199 299 list_del(&info->link); 200 300 spin_lock_irqsave(&iommu_lock, flags); 201 - if (win_cnt > 1) 202 - pamu_free_subwins(info->liodn); 203 301 pamu_disable_liodn(info->liodn); 204 302 spin_unlock_irqrestore(&iommu_lock, flags); 205 303 spin_lock_irqsave(&device_domain_lock, flags); ··· 215 317 /* Remove the device from the domain device list */ 216 318 list_for_each_entry_safe(info, tmp, &dma_domain->devices, link) { 217 319 if (!dev || (info->dev == dev)) 218 - remove_device_ref(info, dma_domain->win_cnt); 320 + remove_device_ref(info); 219 321 } 220 322 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 221 323 } ··· 297 399 298 400 dma_domain->stash_id = ~(u32)0; 299 401 dma_domain->snoop_id = ~(u32)0; 300 - dma_domain->win_cnt = pamu_get_max_subwin_cnt(); 301 402 INIT_LIST_HEAD(&dma_domain->devices); 302 403 spin_lock_init(&dma_domain->domain_lock); 303 404 ··· 306 409 dma_domain->iommu_domain.geometry.force_aperture = true; 307 410 308 411 return &dma_domain->iommu_domain; 309 - } 310 - 311 - /* Configure geometry settings for all LIODNs associated with domain */ 312 - static int pamu_set_domain_geometry(struct fsl_dma_domain *dma_domain, 313 - struct iommu_domain_geometry *geom_attr, 314 - u32 win_cnt) 315 - { 316 - struct device_domain_info *info; 317 - int ret = 0; 318 - 319 - list_for_each_entry(info, &dma_domain->devices, link) { 320 - ret = pamu_set_liodn(info->liodn, info->dev, dma_domain, 321 - geom_attr, win_cnt); 322 - if (ret) 323 - break; 324 - } 325 - 326 - return ret; 327 412 } 328 413 329 414 /* Update stash destination for all LIODNs associated with the domain */ ··· 354 475 pamu_prot |= PAACE_AP_PERMS_UPDATE; 355 476 356 477 spin_lock_irqsave(&dma_domain->domain_lock, flags); 357 - if (!dma_domain->win_arr) { 358 - pr_debug("Number of windows not configured\n"); 359 - spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 360 - return -ENODEV; 361 - } 362 - 363 - if (wnd_nr >= dma_domain->win_cnt) { 478 + if (wnd_nr > 0) { 364 479 pr_debug("Invalid window index\n"); 365 480 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 366 481 return -EINVAL; 367 482 } 368 483 369 - win_size = (domain->geometry.aperture_end + 1) >> 370 - ilog2(dma_domain->win_cnt); 484 + win_size = (domain->geometry.aperture_end + 1) >> ilog2(1); 371 485 if (size > win_size) { 372 486 pr_debug("Invalid window size\n"); 373 487 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 374 488 return -EINVAL; 375 489 } 376 490 377 - if (dma_domain->win_cnt == 1) { 378 - if (dma_domain->enabled) { 379 - pr_debug("Disable the window before updating the mapping\n"); 380 - spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 381 - return -EBUSY; 382 - } 491 + if (dma_domain->enabled) { 492 + pr_debug("Disable the window before updating the mapping\n"); 493 + spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 494 + return -EBUSY; 495 + } 383 496 384 - ret = check_size(size, domain->geometry.aperture_start); 385 - if (ret) { 386 - pr_debug("Aperture start not aligned to the size\n"); 387 - spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 388 - return -EINVAL; 389 - } 497 + ret = check_size(size, domain->geometry.aperture_start); 498 + if (ret) { 499 + pr_debug("Aperture start not aligned to the size\n"); 500 + spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 501 + return -EINVAL; 390 502 } 391 503 392 504 wnd = &dma_domain->win_arr[wnd_nr]; ··· 430 560 * for the domain. If yes, set the geometry for 431 561 * the LIODN. 432 562 */ 433 - if (dma_domain->win_arr) { 434 - u32 win_cnt = dma_domain->win_cnt > 1 ? dma_domain->win_cnt : 0; 435 - 436 - ret = pamu_set_liodn(liodn[i], dev, dma_domain, 437 - &domain->geometry, win_cnt); 563 + ret = pamu_set_liodn(liodn[i], dev, dma_domain, 564 + &domain->geometry); 565 + if (ret) 566 + break; 567 + if (dma_domain->mapped) { 568 + /* 569 + * Create window/subwindow mapping for 570 + * the LIODN. 571 + */ 572 + ret = map_liodn(liodn[i], dma_domain); 438 573 if (ret) 439 574 break; 440 - if (dma_domain->mapped) { 441 - /* 442 - * Create window/subwindow mapping for 443 - * the LIODN. 444 - */ 445 - ret = map_liodn(liodn[i], dma_domain); 446 - if (ret) 447 - break; 448 - } 449 575 } 450 576 } 451 577 spin_unlock_irqrestore(&dma_domain->domain_lock, flags); ··· 572 706 return 0; 573 707 } 574 708 575 - static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count) 576 - { 577 - struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain); 578 - unsigned long flags; 579 - int ret; 580 - 581 - spin_lock_irqsave(&dma_domain->domain_lock, flags); 582 - /* Ensure domain is inactive i.e. DMA should be disabled for the domain */ 583 - if (dma_domain->enabled) { 584 - pr_debug("Can't set geometry attributes as domain is active\n"); 585 - spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 586 - return -EBUSY; 587 - } 588 - 589 - /* 590 - * Ensure we have valid window count i.e. it should be less than 591 - * maximum permissible limit and should be a power of two. 592 - */ 593 - if (w_count > pamu_get_max_subwin_cnt() || !is_power_of_2(w_count)) { 594 - pr_debug("Invalid window count\n"); 595 - spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 596 - return -EINVAL; 597 - } 598 - 599 - ret = pamu_set_domain_geometry(dma_domain, &domain->geometry, 600 - w_count > 1 ? w_count : 0); 601 - if (!ret) { 602 - kfree(dma_domain->win_arr); 603 - dma_domain->win_arr = kcalloc(w_count, 604 - sizeof(*dma_domain->win_arr), 605 - GFP_ATOMIC); 606 - if (!dma_domain->win_arr) { 607 - spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 608 - return -ENOMEM; 609 - } 610 - dma_domain->win_cnt = w_count; 611 - } 612 - spin_unlock_irqrestore(&dma_domain->domain_lock, flags); 613 - 614 - return ret; 615 - } 616 - 617 709 static int fsl_pamu_set_domain_attr(struct iommu_domain *domain, 618 710 enum iommu_attr attr_type, void *data) 619 711 { ··· 584 760 break; 585 761 case DOMAIN_ATTR_FSL_PAMU_ENABLE: 586 762 ret = configure_domain_dma_state(dma_domain, *(int *)data); 587 - break; 588 - case DOMAIN_ATTR_WINDOWS: 589 - ret = fsl_pamu_set_windows(domain, *(u32 *)data); 590 763 break; 591 764 default: 592 765 pr_debug("Unsupported attribute type\n");
+2 -14
drivers/iommu/fsl_pamu_domain.h
··· 18 18 19 19 struct fsl_dma_domain { 20 20 /* 21 - * Number of windows assocaited with this domain. 22 - * During domain initialization, it is set to the 23 - * the maximum number of subwindows allowed for a LIODN. 24 - * Minimum value for this is 1 indicating a single PAMU 25 - * window, without any sub windows. Value can be set/ 26 - * queried by set_attr/get_attr API for DOMAIN_ATTR_WINDOWS. 27 - * Value can only be set once the geometry has been configured. 28 - */ 29 - u32 win_cnt; 30 - /* 31 21 * win_arr contains information of the configured 32 - * windows for a domain. This is allocated only 33 - * when the number of windows for the domain are 34 - * set. 22 + * windows for a domain. 35 23 */ 36 - struct dma_window *win_arr; 24 + struct dma_window win_arr[1]; 37 25 /* list of devices associated with the domain */ 38 26 struct list_head devices; 39 27 /* dma_domain states:
-7
drivers/soc/fsl/qbman/qman_portal.c
··· 55 55 dev_err(dev, "%s(): iommu_domain_alloc() failed", __func__); 56 56 goto no_iommu; 57 57 } 58 - ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS, 59 - &window_count); 60 - if (ret < 0) { 61 - dev_err(dev, "%s(): iommu_domain_set_attr() = %d", __func__, 62 - ret); 63 - goto out_domain_free; 64 - } 65 58 stash_attr.cpu = cpu; 66 59 stash_attr.cache = PAMU_ATTR_CACHE_L1; 67 60 ret = iommu_domain_set_attr(pcfg->iommu_domain,
-1
include/linux/iommu.h
··· 109 109 enum iommu_attr { 110 110 DOMAIN_ATTR_GEOMETRY, 111 111 DOMAIN_ATTR_PAGING, 112 - DOMAIN_ATTR_WINDOWS, 113 112 DOMAIN_ATTR_FSL_PAMU_STASH, 114 113 DOMAIN_ATTR_FSL_PAMU_ENABLE, 115 114 DOMAIN_ATTR_NESTING, /* two stages of translation */