struct page *kvm_alloc_hpt(unsigned long nr_pages) { unsigned long align_pages = HPT_ALIGN_PAGES; VM_BUG_ON(order_base_2(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); /* Old CPUs require HPT aligned on a multiple of its size */ if (!cpu_has_feature(CPU_FTR_ARCH_206)) align_pages = nr_pages; return cma_alloc(kvm_cma, nr_pages, order_base_2(align_pages)); }
static int update_mqd_sdma(struct mqd_manager *mm, void *mqd, struct queue_properties *q) { struct cik_sdma_rlc_registers *m; m = get_sdma_mqd(mqd); m->sdma_rlc_rb_cntl = order_base_2(q->queue_size / 4) << SDMA0_RLC0_RB_CNTL__RB_SIZE__SHIFT | q->vmid << SDMA0_RLC0_RB_CNTL__RB_VMID__SHIFT | 1 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT | 6 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT; m->sdma_rlc_rb_base = lower_32_bits(q->queue_address >> 8); m->sdma_rlc_rb_base_hi = upper_32_bits(q->queue_address >> 8); m->sdma_rlc_rb_rptr_addr_lo = lower_32_bits((uint64_t)q->read_ptr); m->sdma_rlc_rb_rptr_addr_hi = upper_32_bits((uint64_t)q->read_ptr); m->sdma_rlc_doorbell = q->doorbell_off << SDMA0_RLC0_DOORBELL__OFFSET__SHIFT; m->sdma_rlc_virtual_addr = q->sdma_vm_addr; m->sdma_engine_id = q->sdma_engine_id; m->sdma_queue_id = q->sdma_queue_id; q->is_active = (q->queue_size > 0 && q->queue_address != 0 && q->queue_percent > 0 && !q->is_evicted); return 0; }
static struct pcpu_chunk *pcpu_create_chunk(void) { const int nr_pages = pcpu_group_sizes[0] >> PAGE_SHIFT; struct pcpu_chunk *chunk; struct page *pages; int i; chunk = pcpu_alloc_chunk(); if (!chunk) return NULL; pages = alloc_pages(GFP_KERNEL, order_base_2(nr_pages)); if (!pages) { pcpu_free_chunk(chunk); return NULL; } for (i = 0; i < nr_pages; i++) pcpu_set_page_chunk(nth_page(pages, i), chunk); chunk->data = pages; chunk->base_addr = page_address(pages) - pcpu_group_offsets[0]; spin_lock_irq(&pcpu_lock); pcpu_chunk_populated(chunk, 0, nr_pages); spin_unlock_irq(&pcpu_lock); return chunk; }
/* This is data timeout. Response timeout is fixed to 640 clock cycles */ static void usdhi6_timeout_set(struct usdhi6_host *host) { struct mmc_request *mrq = host->mrq; u32 val; unsigned long ticks; if (!mrq->data) ticks = host->rate / 1000 * mrq->cmd->busy_timeout; else ticks = host->rate / 1000000 * (mrq->data->timeout_ns / 1000) + mrq->data->timeout_clks; if (!ticks || ticks > 1 << 27) /* Max timeout */ val = 14; else if (ticks < 1 << 13) /* Min timeout */ val = 0; else val = order_base_2(ticks) - 13; dev_dbg(mmc_dev(host->mmc), "Set %s timeout %lu ticks @ %lu Hz\n", mrq->data ? "data" : "cmd", ticks, host->rate); /* Timeout Counter mask: 0xf0 */ usdhi6_write(host, USDHI6_SD_OPTION, (val << USDHI6_SD_OPTION_TIMEOUT_SHIFT) | (usdhi6_read(host, USDHI6_SD_OPTION) & ~USDHI6_SD_OPTION_TIMEOUT_MASK)); }
static struct pcpu_chunk *pcpu_create_chunk(gfp_t gfp) { const int nr_pages = pcpu_group_sizes[0] >> PAGE_SHIFT; struct pcpu_chunk *chunk; struct page *pages; unsigned long flags; int i; chunk = pcpu_alloc_chunk(gfp); if (!chunk) return NULL; pages = alloc_pages(gfp, order_base_2(nr_pages)); if (!pages) { pcpu_free_chunk(chunk); return NULL; } for (i = 0; i < nr_pages; i++) pcpu_set_page_chunk(nth_page(pages, i), chunk); chunk->data = pages; chunk->base_addr = page_address(pages) - pcpu_group_offsets[0]; spin_lock_irqsave(&pcpu_lock, flags); pcpu_chunk_populated(chunk, 0, nr_pages, false); spin_unlock_irqrestore(&pcpu_lock, flags); pcpu_stats_chunk_alloc(); trace_percpu_create_chunk(chunk->base_addr); return chunk; }
static int update_mqd_hiq(struct mqd_manager *mm, void *mqd, struct queue_properties *q) { struct cik_mqd *m; m = get_mqd(mqd); m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE | DEFAULT_MIN_AVAIL_SIZE | PRIV_STATE | KMD_QUEUE; /* * Calculating queue size which is log base 2 of actual queue * size -1 dwords */ m->cp_hqd_pq_control |= order_base_2(q->queue_size / 4) - 1; m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8); m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr); m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr); m->cp_hqd_pq_doorbell_control = DOORBELL_OFFSET(q->doorbell_off); m->cp_hqd_vmid = q->vmid; q->is_active = (q->queue_size > 0 && q->queue_address != 0 && q->queue_percent > 0 && !q->is_evicted); return 0; }
static struct gen_pool *iova_pool_setup(unsigned long start, unsigned long end, unsigned long align) { struct gen_pool *pool = NULL; int ret = 0; pool = gen_pool_create(order_base_2(align), -1); if (!pool) { printk(KERN_ERR "Create gen pool failed!\n"); return NULL; } /* iova start should not be 0, because return 0 when alloc iova is considered as error */ if (0 == start) { WARN(1, "iova start should not be 0!\n"); } ret = gen_pool_add(pool, start, (end - start), -1); if (ret) { printk(KERN_ERR "Gen pool add failed!\n"); gen_pool_destroy(pool); return NULL; } return pool; }
static void pcpu_destroy_chunk(struct pcpu_chunk *chunk) { const int nr_pages = pcpu_group_sizes[0] >> PAGE_SHIFT; if (chunk && chunk->data) __free_pages(chunk->data, order_base_2(nr_pages)); pcpu_free_chunk(chunk); }
/** * iceland_ih_irq_init - init and enable the interrupt ring * * @adev: amdgpu_device pointer * * Allocate a ring buffer for the interrupt controller, * enable the RLC, disable interrupts, enable the IH * ring buffer and enable it (VI). * Called at device load and reume. * Returns 0 for success, errors for failure. */ static int iceland_ih_irq_init(struct amdgpu_device *adev) { int ret = 0; int rb_bufsz; u32 interrupt_cntl, ih_cntl, ih_rb_cntl; u64 wptr_off; /* disable irqs */ iceland_ih_disable_interrupts(adev); /* setup interrupt control */ WREG32(mmINTERRUPT_CNTL2, adev->dummy_page.addr >> 8); interrupt_cntl = RREG32(mmINTERRUPT_CNTL); /* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN */ interrupt_cntl = REG_SET_FIELD(interrupt_cntl, INTERRUPT_CNTL, IH_DUMMY_RD_OVERRIDE, 0); /* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */ interrupt_cntl = REG_SET_FIELD(interrupt_cntl, INTERRUPT_CNTL, IH_REQ_NONSNOOP_EN, 0); WREG32(mmINTERRUPT_CNTL, interrupt_cntl); /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/ WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8); rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4); ih_rb_cntl = REG_SET_FIELD(0, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz); /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register value is written to memory */ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1); /* set the writeback address whether it's enabled or not */ wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4); WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off)); WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF); WREG32(mmIH_RB_CNTL, ih_rb_cntl); /* set rptr, wptr to 0 */ WREG32(mmIH_RB_RPTR, 0); WREG32(mmIH_RB_WPTR, 0); /* Default settings for IH_CNTL (disabled at first) */ ih_cntl = RREG32(mmIH_CNTL); ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL, MC_VMID, 0); if (adev->irq.msi_enabled) ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL, RPTR_REARM, 1); WREG32(mmIH_CNTL, ih_cntl); pci_set_master(adev->pdev); /* enable interrupts */ iceland_ih_enable_interrupts(adev); return ret; }
/** * cik_ih_irq_init - init and enable the interrupt ring * * @adev: amdgpu_device pointer * * Allocate a ring buffer for the interrupt controller, * enable the RLC, disable interrupts, enable the IH * ring buffer and enable it (CIK). * Called at device load and reume. * Returns 0 for success, errors for failure. */ static int cik_ih_irq_init(struct amdgpu_device *adev) { int ret = 0; int rb_bufsz; u32 interrupt_cntl, ih_cntl, ih_rb_cntl; u64 wptr_off; /* disable irqs */ cik_ih_disable_interrupts(adev); /* setup interrupt control */ WREG32(mmINTERRUPT_CNTL2, adev->dummy_page.addr >> 8); interrupt_cntl = RREG32(mmINTERRUPT_CNTL); /* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN */ interrupt_cntl &= ~INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK; /* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */ interrupt_cntl &= ~INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK; WREG32(mmINTERRUPT_CNTL, interrupt_cntl); WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8); rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4); ih_rb_cntl = (IH_RB_CNTL__WPTR_OVERFLOW_ENABLE_MASK | IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK | (rb_bufsz << 1)); ih_rb_cntl |= IH_RB_CNTL__WPTR_WRITEBACK_ENABLE_MASK; /* set the writeback address whether it's enabled or not */ wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4); WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off)); WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF); WREG32(mmIH_RB_CNTL, ih_rb_cntl); /* set rptr, wptr to 0 */ WREG32(mmIH_RB_RPTR, 0); WREG32(mmIH_RB_WPTR, 0); /* Default settings for IH_CNTL (disabled at first) */ ih_cntl = (0x10 << IH_CNTL__MC_WRREQ_CREDIT__SHIFT) | (0x10 << IH_CNTL__MC_WR_CLEAN_CNT__SHIFT) | (0 << IH_CNTL__MC_VMID__SHIFT); /* IH_CNTL__RPTR_REARM_MASK only works if msi's are enabled */ if (adev->irq.msi_enabled) ih_cntl |= IH_CNTL__RPTR_REARM_MASK; WREG32(mmIH_CNTL, ih_cntl); pci_set_master(adev->pdev); /* enable irqs */ cik_ih_enable_interrupts(adev); return ret; }
static void __pdc_wdt_set_timeout(struct pdc_wdt_dev *wdt) { unsigned long clk_rate = clk_get_rate(wdt->wdt_clk); unsigned int val; val = readl(wdt->base + PDC_WDT_CONFIG) & ~PDC_WDT_CONFIG_DELAY_MASK; val |= order_base_2(wdt->wdt_dev.timeout * clk_rate) - 1; writel(val, wdt->base + PDC_WDT_CONFIG); }
struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, int *num_elem, unsigned int elem_size) { struct rxe_queue *q; size_t buf_size; unsigned int num_slots; /* num_elem == 0 is allowed, but uninteresting */ if (*num_elem < 0) goto err1; q = kmalloc(sizeof(*q), GFP_KERNEL); if (!q) goto err1; q->rxe = rxe; /* used in resize, only need to copy used part of queue */ q->elem_size = elem_size; /* pad element up to at least a cacheline and always a power of 2 */ if (elem_size < cache_line_size()) elem_size = cache_line_size(); elem_size = roundup_pow_of_two(elem_size); q->log2_elem_size = order_base_2(elem_size); num_slots = *num_elem + 1; num_slots = roundup_pow_of_two(num_slots); q->index_mask = num_slots - 1; buf_size = sizeof(struct rxe_queue_buf) + num_slots * elem_size; q->buf = vmalloc_user(buf_size); if (!q->buf) goto err2; q->buf->log2_elem_size = q->log2_elem_size; q->buf->index_mask = q->index_mask; q->buf_size = buf_size; *num_elem = num_slots - 1; return q; err2: kfree(q); err1: return NULL; }
static void pcpu_destroy_chunk(struct pcpu_chunk *chunk) { const int nr_pages = pcpu_group_sizes[0] >> PAGE_SHIFT; if (!chunk) return; pcpu_stats_chunk_dealloc(); trace_percpu_destroy_chunk(chunk->base_addr); if (chunk->data) __free_pages(chunk->data, order_base_2(nr_pages)); pcpu_free_chunk(chunk); }
static int pdc_wdt_set_timeout(struct watchdog_device *wdt_dev, unsigned int new_timeout) { unsigned int val; struct pdc_wdt_dev *wdt = watchdog_get_drvdata(wdt_dev); unsigned long clk_rate = clk_get_rate(wdt->wdt_clk); wdt->wdt_dev.timeout = new_timeout; val = readl(wdt->base + PDC_WDT_CONFIG) & ~PDC_WDT_CONFIG_DELAY_MASK; val |= order_base_2(new_timeout * clk_rate) - 1; writel(val, wdt->base + PDC_WDT_CONFIG); return 0; }
static void sun9i_a80_get_ahb_factors(struct factors_request *req) { u32 _p; if (req->parent_rate < req->rate) req->rate = req->parent_rate; _p = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* maximum p is 3 */ if (_p > 3) _p = 3; req->rate = req->parent_rate >> _p; req->p = _p; }
static void sun9i_a80_get_apb1_factors(struct factors_request *req) { u32 div; if (req->parent_rate < req->rate) req->rate = req->parent_rate; div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Highest possible divider is 256 (p = 3, m = 31) */ if (div > 256) div = 256; req->p = order_base_2(div); req->m = (req->parent_rate >> req->p) - 1; req->rate = (req->parent_rate >> req->p) / (req->m + 1); }
/** * amdgpu_ih_ring_init - initialize the IH state * * @adev: amdgpu_device pointer * * Initializes the IH state and allocates a buffer * for the IH ring buffer. * Returns 0 for success, errors for failure. */ int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, bool use_bus_addr) { u32 rb_bufsz; int r; /* Align ring size */ rb_bufsz = order_base_2(ring_size / 4); ring_size = (1 << rb_bufsz) * 4; adev->irq.ih.ring_size = ring_size; adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1; adev->irq.ih.rptr = 0; adev->irq.ih.use_bus_addr = use_bus_addr; if (adev->irq.ih.use_bus_addr) { if (!adev->irq.ih.ring) { /* add 8 bytes for the rptr/wptr shadows and * add them to the end of the ring allocation. */ adev->irq.ih.ring = pci_alloc_consistent(adev->pdev, adev->irq.ih.ring_size + 8, &adev->irq.ih.rb_dma_addr); if (adev->irq.ih.ring == NULL) return -ENOMEM; memset((void *)adev->irq.ih.ring, 0, adev->irq.ih.ring_size + 8); adev->irq.ih.wptr_offs = (adev->irq.ih.ring_size / 4) + 0; adev->irq.ih.rptr_offs = (adev->irq.ih.ring_size / 4) + 1; } return 0; } else { r = amdgpu_wb_get(adev, &adev->irq.ih.wptr_offs); if (r) { dev_err(adev->dev, "(%d) ih wptr_offs wb alloc failed\n", r); return r; } r = amdgpu_wb_get(adev, &adev->irq.ih.rptr_offs); if (r) { amdgpu_wb_free(adev, adev->irq.ih.wptr_offs); dev_err(adev->dev, "(%d) ih rptr_offs wb alloc failed\n", r); return r; } return amdgpu_ih_ring_alloc(adev); } }
struct kvm_rma_info *kvm_alloc_rma() { struct page *page; struct kvm_rma_info *ri; ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL); if (!ri) return NULL; page = cma_alloc(kvm_cma, kvm_rma_pages, order_base_2(kvm_rma_pages)); if (!page) goto err_out; atomic_set(&ri->use_count, 1); ri->base_pfn = page_to_pfn(page); return ri; err_out: kfree(ri); return NULL; }
static int __update_mqd(struct mqd_manager *mm, void *mqd, struct queue_properties *q, unsigned int atc_bit) { struct cik_mqd *m; m = get_mqd(mqd); m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE | DEFAULT_MIN_AVAIL_SIZE; m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE; if (atc_bit) { m->cp_hqd_pq_control |= PQ_ATC_EN; m->cp_hqd_ib_control |= IB_ATC_EN; } /* * Calculating queue size which is log base 2 of actual queue size -1 * dwords and another -1 for ffs */ m->cp_hqd_pq_control |= order_base_2(q->queue_size / 4) - 1; m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8); m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr); m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr); m->cp_hqd_pq_doorbell_control = DOORBELL_OFFSET(q->doorbell_off); m->cp_hqd_vmid = q->vmid; if (q->format == KFD_QUEUE_FORMAT_AQL) m->cp_hqd_pq_control |= NO_UPDATE_RPTR; update_cu_mask(mm, mqd, q); q->is_active = (q->queue_size > 0 && q->queue_address != 0 && q->queue_percent > 0 && !q->is_evicted); return 0; }
static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl) { int rb_bufsz = order_base_2(ih->ring_size / 4); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, ih->use_bus_addr ? 1 : 4); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz); /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register * value is written to memory */ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0); return ih_rb_cntl; }
/** * cik_sdma_gfx_resume - setup and start the async dma engines * * @rdev: radeon_device pointer * * Set up the gfx DMA ring buffers and enable them (CIK). * Returns 0 for success, error for failure. */ static int cik_sdma_gfx_resume(struct radeon_device *rdev) { struct radeon_ring *ring; u32 rb_cntl, ib_cntl; u32 rb_bufsz; u32 reg_offset, wb_offset; int i, r; for (i = 0; i < 2; i++) { if (i == 0) { ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; reg_offset = SDMA0_REGISTER_OFFSET; wb_offset = R600_WB_DMA_RPTR_OFFSET; } else { ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; reg_offset = SDMA1_REGISTER_OFFSET; wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET; } WREG32(SDMA0_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0); WREG32(SDMA0_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0); /* Set ring buffer size in dwords */ rb_bufsz = order_base_2(ring->ring_size / 4); rb_cntl = rb_bufsz << 1; #ifdef __BIG_ENDIAN rb_cntl |= SDMA_RB_SWAP_ENABLE | SDMA_RPTR_WRITEBACK_SWAP_ENABLE; #endif WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); /* Initialize the ring buffer's read and write pointers */ WREG32(SDMA0_GFX_RB_RPTR + reg_offset, 0); WREG32(SDMA0_GFX_RB_WPTR + reg_offset, 0); /* set the wb address whether it's enabled or not */ WREG32(SDMA0_GFX_RB_RPTR_ADDR_HI + reg_offset, upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF); WREG32(SDMA0_GFX_RB_RPTR_ADDR_LO + reg_offset, ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC)); if (rdev->wb.enabled) rb_cntl |= SDMA_RPTR_WRITEBACK_ENABLE; WREG32(SDMA0_GFX_RB_BASE + reg_offset, ring->gpu_addr >> 8); WREG32(SDMA0_GFX_RB_BASE_HI + reg_offset, ring->gpu_addr >> 40); ring->wptr = 0; WREG32(SDMA0_GFX_RB_WPTR + reg_offset, ring->wptr << 2); /* enable DMA RB */ WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl | SDMA_RB_ENABLE); ib_cntl = SDMA_IB_ENABLE; #ifdef __BIG_ENDIAN ib_cntl |= SDMA_IB_SWAP_ENABLE; #endif /* enable DMA IBs */ WREG32(SDMA0_GFX_IB_CNTL + reg_offset, ib_cntl); ring->ready = true; r = radeon_ring_test(rdev, ring->idx, ring); if (r) { ring->ready = false; return r; } } if ((rdev->asic->copy.copy_ring_index == R600_RING_TYPE_DMA_INDEX) || (rdev->asic->copy.copy_ring_index == CAYMAN_RING_TYPE_DMA1_INDEX)) radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; }
static int si_dma_start(struct amdgpu_device *adev) { struct amdgpu_ring *ring; u32 rb_cntl, dma_cntl, ib_cntl, rb_bufsz; int i, r; uint64_t rptr_addr; for (i = 0; i < adev->sdma.num_instances; i++) { ring = &adev->sdma.instance[i].ring; WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + sdma_offsets[i], 0); WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 0); /* Set ring buffer size in dwords */ rb_bufsz = order_base_2(ring->ring_size / 4); rb_cntl = rb_bufsz << 1; #ifdef __BIG_ENDIAN rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE; #endif WREG32(DMA_RB_CNTL + sdma_offsets[i], rb_cntl); /* Initialize the ring buffer's read and write pointers */ WREG32(DMA_RB_RPTR + sdma_offsets[i], 0); WREG32(DMA_RB_WPTR + sdma_offsets[i], 0); rptr_addr = adev->wb.gpu_addr + (ring->rptr_offs * 4); WREG32(DMA_RB_RPTR_ADDR_LO + sdma_offsets[i], lower_32_bits(rptr_addr)); WREG32(DMA_RB_RPTR_ADDR_HI + sdma_offsets[i], upper_32_bits(rptr_addr) & 0xFF); rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE; WREG32(DMA_RB_BASE + sdma_offsets[i], ring->gpu_addr >> 8); /* enable DMA IBs */ ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE; #ifdef __BIG_ENDIAN ib_cntl |= DMA_IB_SWAP_ENABLE; #endif WREG32(DMA_IB_CNTL + sdma_offsets[i], ib_cntl); dma_cntl = RREG32(DMA_CNTL + sdma_offsets[i]); dma_cntl &= ~CTXEMPTY_INT_ENABLE; WREG32(DMA_CNTL + sdma_offsets[i], dma_cntl); ring->wptr = 0; WREG32(DMA_RB_WPTR + sdma_offsets[i], ring->wptr << 2); WREG32(DMA_RB_CNTL + sdma_offsets[i], rb_cntl | DMA_RB_ENABLE); ring->ready = true; r = amdgpu_ring_test_ring(ring); if (r) { ring->ready = false; return r; } if (adev->mman.buffer_funcs_ring == ring) amdgpu_ttm_set_active_vram_size(adev, adev->mc.real_vram_size); } return 0; }
/** * uvd_v5_0_start - start UVD block * * @adev: amdgpu_device pointer * * Setup and start the UVD block */ static int uvd_v5_0_start(struct amdgpu_device *adev) { struct amdgpu_ring *ring = &adev->uvd.ring; uint32_t rb_bufsz, tmp; uint32_t lmi_swap_cntl; uint32_t mp_swap_cntl; int i, j, r; /*disable DPG */ WREG32_P(mmUVD_POWER_STATUS, 0, ~(1 << 2)); /* disable byte swapping */ lmi_swap_cntl = 0; mp_swap_cntl = 0; uvd_v5_0_mc_resume(adev); amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); uvd_v5_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); uvd_v5_0_enable_mgcg(adev, true); /* disable interupt */ WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1)); /* stall UMC and register bus before resetting VCPU */ WREG32_P(mmUVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); mdelay(1); /* put LMI, VCPU, RBC etc... into reset */ WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); mdelay(5); /* take UVD block out of reset */ WREG32_P(mmSRBM_SOFT_RESET, 0, ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK); mdelay(5); /* initialize UVD memory controller */ WREG32(mmUVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) | (1 << 21) | (1 << 9) | (1 << 20)); #ifdef __BIG_ENDIAN /* swap (8 in 32) RB and IB */ lmi_swap_cntl = 0xa; mp_swap_cntl = 0; #endif WREG32(mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); WREG32(mmUVD_MP_SWAP_CNTL, mp_swap_cntl); WREG32(mmUVD_MPC_SET_MUXA0, 0x40c2040); WREG32(mmUVD_MPC_SET_MUXA1, 0x0); WREG32(mmUVD_MPC_SET_MUXB0, 0x40c2040); WREG32(mmUVD_MPC_SET_MUXB1, 0x0); WREG32(mmUVD_MPC_SET_ALU, 0); WREG32(mmUVD_MPC_SET_MUX, 0x88); /* take all subblocks out of reset, except VCPU */ WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); mdelay(5); /* enable VCPU clock */ WREG32(mmUVD_VCPU_CNTL, 1 << 9); /* enable UMC */ WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8)); /* boot up the VCPU */ WREG32(mmUVD_SOFT_RESET, 0); mdelay(10); for (i = 0; i < 10; ++i) { uint32_t status; for (j = 0; j < 100; ++j) { status = RREG32(mmUVD_STATUS); if (status & 2) break; mdelay(10); } r = 0; if (status & 2) break; DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n"); WREG32_P(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK, ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); mdelay(10); WREG32_P(mmUVD_SOFT_RESET, 0, ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); mdelay(10); r = -1; } if (r) { DRM_ERROR("UVD not responding, giving up!!!\n"); return r; } /* enable master interrupt */ WREG32_P(mmUVD_MASTINT_EN, 3 << 1, ~(3 << 1)); /* clear the bit 4 of UVD_STATUS */ WREG32_P(mmUVD_STATUS, 0, ~(2 << 1)); rb_bufsz = order_base_2(ring->ring_size); tmp = 0; tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); /* force RBC into idle state */ WREG32(mmUVD_RBC_RB_CNTL, tmp); /* set the write pointer delay */ WREG32(mmUVD_RBC_RB_WPTR_CNTL, 0); /* set the wb address */ WREG32(mmUVD_RBC_RB_RPTR_ADDR, (upper_32_bits(ring->gpu_addr) >> 2)); /* programm the RB_BASE for ring buffer */ WREG32(mmUVD_LMI_RBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr)); WREG32(mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr)); /* Initialize the ring buffer's read and write pointers */ WREG32(mmUVD_RBC_RB_RPTR, 0); ring->wptr = RREG32(mmUVD_RBC_RB_RPTR); WREG32(mmUVD_RBC_RB_WPTR, ring->wptr); WREG32_P(mmUVD_RBC_RB_CNTL, 0, ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); return 0; }
/** * cik_sdma_gfx_resume - setup and start the async dma engines * * @adev: amdgpu_device pointer * * Set up the gfx DMA ring buffers and enable them (CIK). * Returns 0 for success, error for failure. */ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) { struct amdgpu_ring *ring; u32 rb_cntl, ib_cntl; u32 rb_bufsz; u32 wb_offset; int i, j, r; for (i = 0; i < adev->sdma.num_instances; i++) { ring = &adev->sdma.instance[i].ring; wb_offset = (ring->rptr_offs * 4); mutex_lock(&adev->srbm_mutex); for (j = 0; j < 16; j++) { cik_srbm_select(adev, 0, 0, 0, j); /* SDMA GFX */ WREG32(mmSDMA0_GFX_VIRTUAL_ADDR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_APE1_CNTL + sdma_offsets[i], 0); /* XXX SDMA RLC - todo */ } cik_srbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); WREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i], adev->gfx.config.gb_addr_config & 0x70); WREG32(mmSDMA0_SEM_INCOMPLETE_TIMER_CNTL + sdma_offsets[i], 0); WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 0); /* Set ring buffer size in dwords */ rb_bufsz = order_base_2(ring->ring_size / 4); rb_cntl = rb_bufsz << 1; #ifdef __BIG_ENDIAN rb_cntl |= SDMA0_GFX_RB_CNTL__RB_SWAP_ENABLE_MASK | SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_SWAP_ENABLE_MASK; #endif WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); /* Initialize the ring buffer's read and write pointers */ WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); /* set the wb address whether it's enabled or not */ WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], upper_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF); WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_LO + sdma_offsets[i], ((adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC)); rb_cntl |= SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_ENABLE_MASK; WREG32(mmSDMA0_GFX_RB_BASE + sdma_offsets[i], ring->gpu_addr >> 8); WREG32(mmSDMA0_GFX_RB_BASE_HI + sdma_offsets[i], ring->gpu_addr >> 40); ring->wptr = 0; WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], lower_32_bits(ring->wptr) << 2); /* enable DMA RB */ WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl | SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK); ib_cntl = SDMA0_GFX_IB_CNTL__IB_ENABLE_MASK; #ifdef __BIG_ENDIAN ib_cntl |= SDMA0_GFX_IB_CNTL__IB_SWAP_ENABLE_MASK; #endif /* enable DMA IBs */ WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); ring->ready = true; } cik_sdma_enable(adev, true); for (i = 0; i < adev->sdma.num_instances; i++) { ring = &adev->sdma.instance[i].ring; r = amdgpu_ring_test_ring(ring); if (r) { ring->ready = false; return r; } if (adev->mman.buffer_funcs_ring == ring) amdgpu_ttm_set_active_vram_size(adev, adev->mc.real_vram_size); } return 0; }
/** * r600_dma_resume - setup and start the async dma engine * * @rdev: radeon_device pointer * * Set up the DMA ring buffer and enable it. (r6xx-evergreen). * Returns 0 for success, error for failure. */ int r600_dma_resume(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; u32 rb_cntl, dma_cntl, ib_cntl; u32 rb_bufsz; int r; /* Reset dma */ if (rdev->family >= CHIP_RV770) WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA); else WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA); RREG32(SRBM_SOFT_RESET); udelay(50); WREG32(SRBM_SOFT_RESET, 0); WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL, 0); WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL, 0); /* Set ring buffer size in dwords */ rb_bufsz = order_base_2(ring->ring_size / 4); rb_cntl = rb_bufsz << 1; #ifdef __BIG_ENDIAN rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE; #endif WREG32(DMA_RB_CNTL, rb_cntl); /* Initialize the ring buffer's read and write pointers */ WREG32(DMA_RB_RPTR, 0); WREG32(DMA_RB_WPTR, 0); /* set the wb address whether it's enabled or not */ WREG32(DMA_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_DMA_RPTR_OFFSET) & 0xFF); WREG32(DMA_RB_RPTR_ADDR_LO, ((rdev->wb.gpu_addr + R600_WB_DMA_RPTR_OFFSET) & 0xFFFFFFFC)); if (rdev->wb.enabled) rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE; WREG32(DMA_RB_BASE, ring->gpu_addr >> 8); /* enable DMA IBs */ ib_cntl = DMA_IB_ENABLE; #ifdef __BIG_ENDIAN ib_cntl |= DMA_IB_SWAP_ENABLE; #endif WREG32(DMA_IB_CNTL, ib_cntl); dma_cntl = RREG32(DMA_CNTL); dma_cntl &= ~CTXEMPTY_INT_ENABLE; WREG32(DMA_CNTL, dma_cntl); if (rdev->family >= CHIP_RV770) WREG32(DMA_MODE, 1); ring->wptr = 0; WREG32(DMA_RB_WPTR, ring->wptr << 2); ring->rptr = RREG32(DMA_RB_RPTR) >> 2; WREG32(DMA_RB_CNTL, rb_cntl | DMA_RB_ENABLE); ring->ready = true; r = radeon_ring_test(rdev, R600_RING_TYPE_DMA_INDEX, ring); if (r) { ring->ready = false; return r; } if (rdev->asic->copy.copy_ring_index == R600_RING_TYPE_DMA_INDEX) radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; }
/** * uvd_v1_0_start - start UVD block * * @rdev: radeon_device pointer * * Setup and start the UVD block */ int uvd_v1_0_start(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; uint32_t rb_bufsz; int i, j, r; /* disable byte swapping */ u32 lmi_swap_cntl = 0; u32 mp_swap_cntl = 0; /* disable clock gating */ WREG32(UVD_CGC_GATE, 0); /* disable interupt */ WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1)); /* Stall UMC and register bus before resetting VCPU */ WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); mdelay(1); /* put LMI, VCPU, RBC etc... into reset */ WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET | LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET | CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET); mdelay(5); /* take UVD block out of reset */ WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD); mdelay(5); /* initialize UVD memory controller */ WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) | (1 << 21) | (1 << 9) | (1 << 20)); #ifdef __BIG_ENDIAN /* swap (8 in 32) RB and IB */ lmi_swap_cntl = 0xa; mp_swap_cntl = 0; #endif WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl); WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl); WREG32(UVD_MPC_SET_MUXA0, 0x40c2040); WREG32(UVD_MPC_SET_MUXA1, 0x0); WREG32(UVD_MPC_SET_MUXB0, 0x40c2040); WREG32(UVD_MPC_SET_MUXB1, 0x0); WREG32(UVD_MPC_SET_ALU, 0); WREG32(UVD_MPC_SET_MUX, 0x88); /* take all subblocks out of reset, except VCPU */ WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); mdelay(5); /* enable VCPU clock */ WREG32(UVD_VCPU_CNTL, 1 << 9); /* enable UMC */ WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8)); /* boot up the VCPU */ WREG32(UVD_SOFT_RESET, 0); mdelay(10); WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3)); for (i = 0; i < 10; ++i) { uint32_t status; for (j = 0; j < 100; ++j) { status = RREG32(UVD_STATUS); if (status & 2) break; mdelay(10); } r = 0; if (status & 2) break; DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n"); WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET); mdelay(10); WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET); mdelay(10); r = -1; } if (r) { DRM_ERROR("UVD not responding, giving up!!!\n"); return r; } /* enable interupt */ WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1)); /* force RBC into idle state */ WREG32(UVD_RBC_RB_CNTL, 0x11010101); /* Set the write pointer delay */ WREG32(UVD_RBC_RB_WPTR_CNTL, 0); /* programm the 4GB memory segment for rptr and ring buffer */ WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) | (0x7 << 16) | (0x1 << 31)); /* Initialize the ring buffer's read and write pointers */ WREG32(UVD_RBC_RB_RPTR, 0x0); ring->wptr = ring->rptr = RREG32(UVD_RBC_RB_RPTR); WREG32(UVD_RBC_RB_WPTR, ring->wptr); /* set the ring address */ WREG32(UVD_RBC_RB_BASE, ring->gpu_addr); /* Set ring buffer size */ rb_bufsz = order_base_2(ring->ring_size); rb_bufsz = (0x1 << 8) | rb_bufsz; WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f); return 0; }
struct page *kvm_alloc_hpt(unsigned long nr_pages) { VM_BUG_ON(order_base_2(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); return cma_alloc(kvm_cma, nr_pages, order_base_2(HPT_ALIGN_PAGES)); }
static int update_mqd(struct mqd_manager *mm, void *mqd, struct queue_properties *q) { struct v9_mqd *m; m = get_mqd(mqd); m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT; m->cp_hqd_pq_control |= order_base_2(q->queue_size / 4) - 1; pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control); m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8); m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr); m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr); m->cp_hqd_pq_wptr_poll_addr_lo = lower_32_bits((uint64_t)q->write_ptr); m->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits((uint64_t)q->write_ptr); m->cp_hqd_pq_doorbell_control = q->doorbell_off << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT; pr_debug("cp_hqd_pq_doorbell_control 0x%x\n", m->cp_hqd_pq_doorbell_control); m->cp_hqd_ib_control = 3 << CP_HQD_IB_CONTROL__MIN_IB_AVAIL_SIZE__SHIFT | 1 << CP_HQD_IB_CONTROL__IB_EXE_DISABLE__SHIFT; /* * HW does not clamp this field correctly. Maximum EOP queue size * is constrained by per-SE EOP done signal count, which is 8-bit. * Limit is 0xFF EOP entries (= 0x7F8 dwords). CP will not submit * more than (EOP entry count - 1) so a queue size of 0x800 dwords * is safe, giving a maximum field value of 0xA. */ m->cp_hqd_eop_control = min(0xA, order_base_2(q->eop_ring_buffer_size / 4) - 1); m->cp_hqd_eop_base_addr_lo = lower_32_bits(q->eop_ring_buffer_address >> 8); m->cp_hqd_eop_base_addr_hi = upper_32_bits(q->eop_ring_buffer_address >> 8); m->cp_hqd_iq_timer = 0; m->cp_hqd_vmid = q->vmid; if (q->format == KFD_QUEUE_FORMAT_AQL) { m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__NO_UPDATE_RPTR_MASK | 2 << CP_HQD_PQ_CONTROL__SLOT_BASED_WPTR__SHIFT | 1 << CP_HQD_PQ_CONTROL__QUEUE_FULL_EN__SHIFT | 1 << CP_HQD_PQ_CONTROL__WPP_CLAMP_EN__SHIFT; m->cp_hqd_pq_doorbell_control |= 1 << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_BIF_DROP__SHIFT; } if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address) m->cp_hqd_ctx_save_control = 0; update_cu_mask(mm, mqd, q); q->is_active = (q->queue_size > 0 && q->queue_address != 0 && q->queue_percent > 0 && !q->is_evicted); return 0; }
/** * uvd_v6_0_start - start UVD block * * @adev: amdgpu_device pointer * * Setup and start the UVD block */ static int uvd_v6_0_start(struct amdgpu_device *adev) { struct amdgpu_ring *ring = &adev->uvd.ring; uint32_t rb_bufsz, tmp; uint32_t lmi_swap_cntl; uint32_t mp_swap_cntl; int i, j, r; /* disable DPG */ WREG32_P(mmUVD_POWER_STATUS, 0, ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); /* disable byte swapping */ lmi_swap_cntl = 0; mp_swap_cntl = 0; uvd_v6_0_mc_resume(adev); /* disable clock gating */ WREG32_FIELD(UVD_CGC_CTRL, DYN_CLOCK_MODE, 0); /* disable interupt */ WREG32_FIELD(UVD_MASTINT_EN, VCPU_EN, 0); /* stall UMC and register bus before resetting VCPU */ WREG32_FIELD(UVD_LMI_CTRL2, STALL_ARB_UMC, 1); mdelay(1); /* put LMI, VCPU, RBC etc... into reset */ WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); mdelay(5); /* take UVD block out of reset */ WREG32_FIELD(SRBM_SOFT_RESET, SOFT_RESET_UVD, 0); mdelay(5); /* initialize UVD memory controller */ WREG32(mmUVD_LMI_CTRL, (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | UVD_LMI_CTRL__REQ_MODE_MASK | UVD_LMI_CTRL__DISABLE_ON_FWV_FAIL_MASK); #ifdef __BIG_ENDIAN /* swap (8 in 32) RB and IB */ lmi_swap_cntl = 0xa; mp_swap_cntl = 0; #endif WREG32(mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); WREG32(mmUVD_MP_SWAP_CNTL, mp_swap_cntl); WREG32(mmUVD_MPC_SET_MUXA0, 0x40c2040); WREG32(mmUVD_MPC_SET_MUXA1, 0x0); WREG32(mmUVD_MPC_SET_MUXB0, 0x40c2040); WREG32(mmUVD_MPC_SET_MUXB1, 0x0); WREG32(mmUVD_MPC_SET_ALU, 0); WREG32(mmUVD_MPC_SET_MUX, 0x88); /* take all subblocks out of reset, except VCPU */ WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); mdelay(5); /* enable VCPU clock */ WREG32(mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK); /* enable UMC */ WREG32_FIELD(UVD_LMI_CTRL2, STALL_ARB_UMC, 0); /* boot up the VCPU */ WREG32(mmUVD_SOFT_RESET, 0); mdelay(10); for (i = 0; i < 10; ++i) { uint32_t status; for (j = 0; j < 100; ++j) { status = RREG32(mmUVD_STATUS); if (status & 2) break; mdelay(10); } r = 0; if (status & 2) break; DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n"); WREG32_FIELD(UVD_SOFT_RESET, VCPU_SOFT_RESET, 1); mdelay(10); WREG32_FIELD(UVD_SOFT_RESET, VCPU_SOFT_RESET, 0); mdelay(10); r = -1; } if (r) { DRM_ERROR("UVD not responding, giving up!!!\n"); return r; } /* enable master interrupt */ WREG32_P(mmUVD_MASTINT_EN, (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); /* clear the bit 4 of UVD_STATUS */ WREG32_P(mmUVD_STATUS, 0, ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); /* force RBC into idle state */ rb_bufsz = order_base_2(ring->ring_size); tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); WREG32(mmUVD_RBC_RB_CNTL, tmp); /* set the write pointer delay */ WREG32(mmUVD_RBC_RB_WPTR_CNTL, 0); /* set the wb address */ WREG32(mmUVD_RBC_RB_RPTR_ADDR, (upper_32_bits(ring->gpu_addr) >> 2)); /* programm the RB_BASE for ring buffer */ WREG32(mmUVD_LMI_RBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr)); WREG32(mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr)); /* Initialize the ring buffer's read and write pointers */ WREG32(mmUVD_RBC_RB_RPTR, 0); ring->wptr = RREG32(mmUVD_RBC_RB_RPTR); WREG32(mmUVD_RBC_RB_WPTR, ring->wptr); WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0); return 0; }
static int pdc_wdt_probe(struct platform_device *pdev) { int ret, val; unsigned long clk_rate; struct resource *res; struct pdc_wdt_dev *pdc_wdt; pdc_wdt = devm_kzalloc(&pdev->dev, sizeof(*pdc_wdt), GFP_KERNEL); if (!pdc_wdt) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pdc_wdt->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(pdc_wdt->base)) return PTR_ERR(pdc_wdt->base); pdc_wdt->sys_clk = devm_clk_get(&pdev->dev, "sys"); if (IS_ERR(pdc_wdt->sys_clk)) { dev_err(&pdev->dev, "failed to get the sys clock\n"); return PTR_ERR(pdc_wdt->sys_clk); } pdc_wdt->wdt_clk = devm_clk_get(&pdev->dev, "wdt"); if (IS_ERR(pdc_wdt->wdt_clk)) { dev_err(&pdev->dev, "failed to get the wdt clock\n"); return PTR_ERR(pdc_wdt->wdt_clk); } ret = clk_prepare_enable(pdc_wdt->sys_clk); if (ret) { dev_err(&pdev->dev, "could not prepare or enable sys clock\n"); return ret; } ret = clk_prepare_enable(pdc_wdt->wdt_clk); if (ret) { dev_err(&pdev->dev, "could not prepare or enable wdt clock\n"); goto disable_sys_clk; } /* We use the clock rate to calculate the max timeout */ clk_rate = clk_get_rate(pdc_wdt->wdt_clk); if (clk_rate == 0) { dev_err(&pdev->dev, "failed to get clock rate\n"); ret = -EINVAL; goto disable_wdt_clk; } if (order_base_2(clk_rate) > PDC_WDT_CONFIG_DELAY_MASK + 1) { dev_err(&pdev->dev, "invalid clock rate\n"); ret = -EINVAL; goto disable_wdt_clk; } if (order_base_2(clk_rate) == 0) pdc_wdt->wdt_dev.min_timeout = PDC_WDT_MIN_TIMEOUT + 1; else pdc_wdt->wdt_dev.min_timeout = PDC_WDT_MIN_TIMEOUT; pdc_wdt->wdt_dev.info = &pdc_wdt_info; pdc_wdt->wdt_dev.ops = &pdc_wdt_ops; pdc_wdt->wdt_dev.max_timeout = 1 << PDC_WDT_CONFIG_DELAY_MASK; pdc_wdt->wdt_dev.parent = &pdev->dev; ret = watchdog_init_timeout(&pdc_wdt->wdt_dev, heartbeat, &pdev->dev); if (ret < 0) { pdc_wdt->wdt_dev.timeout = pdc_wdt->wdt_dev.max_timeout; dev_warn(&pdev->dev, "Initial timeout out of range! setting max timeout\n"); } pdc_wdt_stop(&pdc_wdt->wdt_dev); /* Find what caused the last reset */ val = readl(pdc_wdt->base + PDC_WDT_TICKLE1); val = (val & PDC_WDT_TICKLE_STATUS_MASK) >> PDC_WDT_TICKLE_STATUS_SHIFT; switch (val) { case PDC_WDT_TICKLE_STATUS_TICKLE: case PDC_WDT_TICKLE_STATUS_TIMEOUT: pdc_wdt->wdt_dev.bootstatus |= WDIOF_CARDRESET; dev_info(&pdev->dev, "watchdog module last reset due to timeout\n"); break; case PDC_WDT_TICKLE_STATUS_HRESET: dev_info(&pdev->dev, "watchdog module last reset due to hard reset\n"); break; case PDC_WDT_TICKLE_STATUS_SRESET: dev_info(&pdev->dev, "watchdog module last reset due to soft reset\n"); break; case PDC_WDT_TICKLE_STATUS_USER: dev_info(&pdev->dev, "watchdog module last reset due to user reset\n"); break; default: dev_info(&pdev->dev, "contains an illegal status code (%08x)\n", val); break; } watchdog_set_nowayout(&pdc_wdt->wdt_dev, nowayout); platform_set_drvdata(pdev, pdc_wdt); watchdog_set_drvdata(&pdc_wdt->wdt_dev, pdc_wdt); ret = watchdog_register_device(&pdc_wdt->wdt_dev); if (ret) goto disable_wdt_clk; return 0; disable_wdt_clk: clk_disable_unprepare(pdc_wdt->wdt_clk); disable_sys_clk: clk_disable_unprepare(pdc_wdt->sys_clk); return ret; }