// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Copyright (c) by Takashi Iwai <tiwai@suse.de> * Copyright (c) by Scott McNab <sdm@fractalgraphics.com.au> * * Trident 4DWave-NX memory page allocation (TLB area) * Trident chip can handle only 16MByte of the memory at the same time.
*/
/* fill TLB entries -- we need to fill two entries */ staticinlinevoid set_tlb_bus(struct snd_trident *trident, int page,
dma_addr_t addr)
{
page <<= 1;
__set_tlb_bus(trident, page, addr);
__set_tlb_bus(trident, page+1, addr + SNDRV_TRIDENT_PAGE_SIZE);
} staticinlinevoid set_silent_tlb(struct snd_trident *trident, int page)
{
page <<= 1;
__set_tlb_bus(trident, page, trident->tlb.silent_page->addr);
__set_tlb_bus(trident, page+1, trident->tlb.silent_page->addr);
}
#else /* arbitrary size */ #define UNIT_PAGES (PAGE_SIZE / SNDRV_TRIDENT_PAGE_SIZE) #define ALIGN_PAGE_SIZE (SNDRV_TRIDENT_PAGE_SIZE * UNIT_PAGES) #define MAX_ALIGN_PAGES (SNDRV_TRIDENT_MAX_PAGES / UNIT_PAGES) /* Note: if alignment doesn't match to the maximum size, the last few blocks * become unusable. To use such blocks, you'll need to check the validity * of accessing page in set_tlb_bus and set_silent_tlb. search_empty() * should also check it, too.
*/ #define get_aligned_page(offset) ((offset) / ALIGN_PAGE_SIZE) #define aligned_page_offset(page) ((page) * ALIGN_PAGE_SIZE) #define page_to_addr(trident,page) __tlb_to_addr(trident, (page) * UNIT_PAGES)
/* fill TLB entries -- UNIT_PAGES entries must be filled */ staticinlinevoid set_tlb_bus(struct snd_trident *trident, int page,
dma_addr_t addr)
{ int i;
page *= UNIT_PAGES; for (i = 0; i < UNIT_PAGES; i++, page++) {
__set_tlb_bus(trident, page, addr);
addr += SNDRV_TRIDENT_PAGE_SIZE;
}
} staticinlinevoid set_silent_tlb(struct snd_trident *trident, int page)
{ int i;
page *= UNIT_PAGES; for (i = 0; i < UNIT_PAGES; i++, page++)
__set_tlb_bus(trident, page, trident->tlb.silent_page->addr);
}
#endif/* PAGE_SIZE */
/* first and last (aligned) pages of memory block */ #define firstpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->first_page) #define lastpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->last_page)
/* * search empty pages which may contain given size
*/ staticstruct snd_util_memblk *
search_empty(struct snd_util_memhdr *hdr, int size)
{ struct snd_util_memblk *blk; int page, psize; struct list_head *p;
/* * check if the given pointer is valid for pages
*/ staticint is_valid_page(struct snd_trident *trident, unsignedlong ptr)
{ if (ptr & ~0x3fffffffUL) {
dev_err(trident->card->dev, "max memory size is 1GB!!\n"); return 0;
} if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
dev_err(trident->card->dev, "page is not aligned\n"); return 0;
} return 1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.