diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 96eb81693785..f01a4be5a886 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -3,6 +3,7 @@ * Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. */ #include +#include #include #include #include @@ -90,6 +91,39 @@ int adreno_wake_nice = -7; /* Number of milliseconds to stay active active after a wake on touch */ unsigned int adreno_wake_timeout = 100; +int adreno_get_firmware(struct adreno_device *adreno_dev, + const char *fwfile, struct adreno_firmware *firmware) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + const struct firmware *fw = NULL; + int ret; + + if (!IS_ERR_OR_NULL(firmware->memdesc)) + return 0; + + ret = request_firmware(&fw, fwfile, &device->pdev->dev); + + if (ret) { + dev_err(device->dev, "request_firmware(%s) failed: %d\n", + fwfile, ret); + return ret; + } + + firmware->memdesc = kgsl_allocate_global(device, fw->size - 4, + KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_UCODE, + "ucode"); + + ret = PTR_ERR_OR_ZERO(firmware->memdesc); + if (!ret) { + memcpy(firmware->memdesc->hostptr, &fw->data[4], fw->size - 4); + firmware->size = (fw->size - 4) / sizeof(u32); + firmware->version = *((u32 *)&fw->data[4]); + } + + release_firmware(fw); + return ret; +} + void adreno_reglist_write(struct adreno_device *adreno_dev, const struct adreno_reglist *list, u32 count) { @@ -161,7 +195,7 @@ unsigned int adreno_get_rptr(struct adreno_ringbuffer *rb) else { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); - kgsl_sharedmem_readl(&device->scratch, &rptr, + kgsl_sharedmem_readl(device->scratch, &rptr, SCRATCH_RPTR_OFFSET(rb->id)); } @@ -1404,9 +1438,10 @@ static int adreno_probe(struct platform_device *pdev) if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV)) priv |= KGSL_MEMDESC_PRIVILEGED; - status = kgsl_allocate_global(device, &device->memstore, + device->memstore = kgsl_allocate_global(device, KGSL_MEMSTORE_SIZE, 0, priv, "memstore"); + status = PTR_ERR_OR_ZERO(device->memstore); if (status) goto out; @@ -1474,7 +1509,6 @@ static int adreno_probe(struct platform_device *pdev) out: if (status) { adreno_ringbuffer_close(adreno_dev); - kgsl_free_global(device, &device->memstore); kgsl_device_platform_remove(device); device->pdev = NULL; } @@ -1484,13 +1518,9 @@ out: static void _adreno_free_memories(struct adreno_device *adreno_dev) { - struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_firmware *pfp_fw = ADRENO_FW(adreno_dev, ADRENO_FW_PFP); struct adreno_firmware *pm4_fw = ADRENO_FW(adreno_dev, ADRENO_FW_PM4); - if (test_bit(ADRENO_DEVICE_DRAWOBJ_PROFILE, &adreno_dev->priv)) - kgsl_free_global(device, &adreno_dev->profile_buffer); - /* Free local copies of firmware and other command streams */ kfree(pfp_fw->fwvirt); pfp_fw->fwvirt = NULL; @@ -1500,9 +1530,6 @@ static void _adreno_free_memories(struct adreno_device *adreno_dev) kfree(adreno_dev->gpmu_cmds); adreno_dev->gpmu_cmds = NULL; - - kgsl_free_global(device, &pfp_fw->memdesc); - kgsl_free_global(device, &pm4_fw->memdesc); } static int adreno_remove(struct platform_device *pdev) @@ -1558,16 +1585,11 @@ static int adreno_remove(struct platform_device *pdev) if (efuse_base != NULL) iounmap(efuse_base); - kgsl_free_global(device, &device->memstore); - kgsl_device_platform_remove(device); gmu_core_remove(device); - if (test_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv)) { - kgsl_free_global(device, &adreno_dev->pwron_fixup); - clear_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv); - } + clear_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv); clear_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv); return 0; @@ -1676,10 +1698,6 @@ static int adreno_init(struct kgsl_device *device) struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); int ret; - if (!adreno_is_a3xx(adreno_dev)) - kgsl_sharedmem_set(device, &device->scratch, 0, 0, - device->scratch.size); - ret = kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT); if (ret) return ret; @@ -1736,25 +1754,19 @@ static int adreno_init(struct kgsl_device *device) if (!adreno_is_a3xx(adreno_dev)) { unsigned int priv = 0; - int r; if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV)) priv |= KGSL_MEMDESC_PRIVILEGED; - r = kgsl_allocate_global(device, - &adreno_dev->profile_buffer, PAGE_SIZE, - 0, priv, "alwayson"); + adreno_dev->profile_buffer = + kgsl_allocate_global(device, PAGE_SIZE, 0, priv, + "alwayson"); adreno_dev->profile_index = 0; - if (r == 0) { + if (!IS_ERR(adreno_dev->profile_buffer)) set_bit(ADRENO_DEVICE_DRAWOBJ_PROFILE, &adreno_dev->priv); - kgsl_sharedmem_set(device, - &adreno_dev->profile_buffer, 0, 0, - PAGE_SIZE); - } - } return 0; @@ -1857,7 +1869,7 @@ static void adreno_set_active_ctxs_null(struct adreno_device *adreno_dev) rb->drawctxt_active = NULL; kgsl_sharedmem_writel(KGSL_DEVICE(adreno_dev), - &rb->pagetable_desc, PT_INFO_OFFSET(current_rb_ptname), + rb->pagetable_desc, PT_INFO_OFFSET(current_rb_ptname), 0); } } @@ -2314,14 +2326,14 @@ static int adreno_prop_device_shadow(struct kgsl_device *device, { struct kgsl_shadowprop shadowprop = { 0 }; - if (device->memstore.hostptr) { + if (device->memstore->hostptr) { /* * NOTE: with mmu enabled, gpuaddr doesn't mean * anything to mmap(). */ - shadowprop.gpuaddr = (unsigned long)device->memstore.gpuaddr; - shadowprop.size = device->memstore.size; + shadowprop.gpuaddr = (unsigned long)device->memstore->gpuaddr; + shadowprop.size = device->memstore->size; shadowprop.flags = KGSL_FLAGS_INITIALIZED | KGSL_FLAGS_PER_CONTEXT_TIMESTAMPS; @@ -2334,11 +2346,10 @@ static int adreno_prop_device_qdss_stm(struct kgsl_device *device, struct kgsl_device_getproperty *param) { struct kgsl_qdss_stm_prop qdssprop = {0}; - struct kgsl_memdesc *qdss_desc = kgsl_mmu_get_qdss_global_entry(device); - if (qdss_desc) { - qdssprop.gpuaddr = qdss_desc->gpuaddr; - qdssprop.size = qdss_desc->size; + if (!IS_ERR_OR_NULL(device->qdss_desc)) { + qdssprop.gpuaddr = device->qdss_desc->gpuaddr; + qdssprop.size = device->qdss_desc->size; } return copy_prop(param, &qdssprop, sizeof(qdssprop)); @@ -2348,12 +2359,10 @@ static int adreno_prop_device_qtimer(struct kgsl_device *device, struct kgsl_device_getproperty *param) { struct kgsl_qtimer_prop qtimerprop = {0}; - struct kgsl_memdesc *qtimer_desc = - kgsl_mmu_get_qtimer_global_entry(device); - if (qtimer_desc) { - qtimerprop.gpuaddr = qtimer_desc->gpuaddr; - qtimerprop.size = qtimer_desc->size; + if (!IS_ERR_OR_NULL(device->qtimer_desc)) { + qtimerprop.gpuaddr = device->qtimer_desc->gpuaddr; + qtimerprop.size = device->qtimer_desc->size; } return copy_prop(param, &qtimerprop, sizeof(qtimerprop)); @@ -3361,11 +3370,11 @@ static int __adreno_readtimestamp(struct adreno_device *adreno_dev, int index, switch (type) { case KGSL_TIMESTAMP_CONSUMED: - kgsl_sharedmem_readl(&device->memstore, timestamp, + kgsl_sharedmem_readl(device->memstore, timestamp, KGSL_MEMSTORE_OFFSET(index, soptimestamp)); break; case KGSL_TIMESTAMP_RETIRED: - kgsl_sharedmem_readl(&device->memstore, timestamp, + kgsl_sharedmem_readl(device->memstore, timestamp, KGSL_MEMSTORE_OFFSET(index, eoptimestamp)); break; default: diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 6895a7dbcb46..c21ce07945d7 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -270,7 +270,7 @@ enum adreno_preempt_states { */ struct adreno_preemption { atomic_t state; - struct kgsl_memdesc counters; + struct kgsl_memdesc *counters; struct timer_list timer; struct work_struct work; unsigned int preempt_level; @@ -303,7 +303,7 @@ struct adreno_firmware { unsigned int *fwvirt; size_t size; unsigned int version; - struct kgsl_memdesc memdesc; + struct kgsl_memdesc *memdesc; }; /** @@ -481,7 +481,7 @@ struct adreno_device { bool cooperative_reset; struct adreno_profile profile; struct adreno_dispatcher dispatcher; - struct kgsl_memdesc pwron_fixup; + struct kgsl_memdesc *pwron_fixup; unsigned int pwron_fixup_dwords; struct work_struct input_work; struct adreno_busy_data busy_data; @@ -498,9 +498,9 @@ struct adreno_device { struct dentry *ctx_d_debugfs; unsigned long pwrctrl_flag; - struct kgsl_memdesc profile_buffer; + struct kgsl_memdesc *profile_buffer; unsigned int profile_index; - struct kgsl_memdesc pwrup_reglist; + struct kgsl_memdesc *pwrup_reglist; uint32_t *lm_sequence; uint32_t lm_size; struct adreno_preemption preempt; @@ -529,6 +529,10 @@ struct adreno_device { bool gpuhtw_llc_slice_enable; unsigned int zap_loaded; unsigned int soc_hw_rev; + /** + * @critpkts: Memory descriptor for 5xx critical packets if applicable + */ + struct kgsl_memdesc *critpkts; }; /** @@ -1506,7 +1510,7 @@ static inline void adreno_ringbuffer_set_global( struct kgsl_device *device = KGSL_DEVICE(adreno_dev); kgsl_sharedmem_writel(device, - &adreno_dev->ringbuffers[0].pagetable_desc, + adreno_dev->ringbuffers[0].pagetable_desc, PT_INFO_OFFSET(current_global_ptname), name); } @@ -1519,13 +1523,13 @@ static inline void adreno_ringbuffer_set_pagetable(struct adreno_ringbuffer *rb, spin_lock_irqsave(&rb->preempt_lock, flags); - kgsl_sharedmem_writel(device, &rb->pagetable_desc, + kgsl_sharedmem_writel(device, rb->pagetable_desc, PT_INFO_OFFSET(current_rb_ptname), pt->name); - kgsl_sharedmem_writeq(device, &rb->pagetable_desc, + kgsl_sharedmem_writeq(device, rb->pagetable_desc, PT_INFO_OFFSET(ttbr0), kgsl_mmu_pagetable_get_ttbr0(pt)); - kgsl_sharedmem_writel(device, &rb->pagetable_desc, + kgsl_sharedmem_writel(device, rb->pagetable_desc, PT_INFO_OFFSET(contextidr), kgsl_mmu_pagetable_get_contextidr(pt)); @@ -1686,4 +1690,19 @@ int adreno_gmu_fenced_write(struct adreno_device *adreno_dev, unsigned int fence_mask); int adreno_clear_pending_transactions(struct kgsl_device *device); void adreno_gmu_send_nmi(struct adreno_device *adreno_dev); + + +/** + * adreno_get_firwmare - Load firmware into a adreno_firmware struct + * @adreno_dev: An Adreno GPU device handle + * @fwfile: Firmware file to load + * @firmware: A &struct adreno_firmware container for the firmware. + * + * Load the specified firmware file into the memdesc in &struct adreno_firmware + * and get the size and version from the data. + * + * Return: 0 on success or negative on failure + */ +int adreno_get_firmware(struct adreno_device *adreno_dev, + const char *fwfile, struct adreno_firmware *firmware); #endif /*__ADRENO_H */ diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index b30b2bf83a75..409d597895da 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -177,20 +177,18 @@ static int _a3xx_pwron_fixup(struct adreno_device *adreno_dev) { unsigned int *cmds; int count = ARRAY_SIZE(_a3xx_pwron_fixup_fs_instructions); - int ret; /* Return if the fixup is already in place */ if (test_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv)) return 0; - ret = kgsl_allocate_global(KGSL_DEVICE(adreno_dev), - &adreno_dev->pwron_fixup, PAGE_SIZE, - KGSL_MEMFLAGS_GPUREADONLY, 0, "pwron_fixup"); + adreno_dev->pwron_fixup = kgsl_allocate_global(KGSL_DEVICE(adreno_dev), + PAGE_SIZE, KGSL_MEMFLAGS_GPUREADONLY, 0, "pwron_fixup"); - if (ret) - return ret; + if (IS_ERR(adreno_dev->pwron_fixup)) + return PTR_ERR(adreno_dev->pwron_fixup); - cmds = adreno_dev->pwron_fixup.hostptr; + cmds = adreno_dev->pwron_fixup->hostptr; *cmds++ = cp_type0_packet(A3XX_UCHE_CACHE_INVALIDATE0_REG, 2); *cmds++ = 0x00000000; @@ -598,7 +596,7 @@ static int _a3xx_pwron_fixup(struct adreno_device *adreno_dev) * program the indirect buffer call in the ringbuffer */ adreno_dev->pwron_fixup_dwords = - (cmds - (unsigned int *) adreno_dev->pwron_fixup.hostptr); + (cmds - (unsigned int *) adreno_dev->pwron_fixup->hostptr); /* Mark the flag in ->priv to show that we have the fix */ set_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv); @@ -678,7 +676,7 @@ static int a3xx_rb_start(struct adreno_device *adreno_dev) (1 << 27)); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_BASE, - rb->buffer_desc.gpuaddr); + rb->buffer_desc->gpuaddr); a3xx_microcode_load(adreno_dev); diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index ff784ef04a04..890480eb1b35 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -19,8 +19,6 @@ #include "kgsl_trace.h" static int critical_packet_constructed; - -static struct kgsl_memdesc crit_pkts; static unsigned int crit_pkts_dwords; static struct kgsl_memdesc crit_pkts_refbuf0; @@ -129,8 +127,6 @@ static void a5xx_platform_setup(struct adreno_device *adreno_dev) static void a5xx_critical_packet_destroy(struct adreno_device *adreno_dev) { - kgsl_free_global(&adreno_dev->dev, &crit_pkts); - kgsl_iommu_unmap_global_secure_pt_entry(KGSL_DEVICE(adreno_dev), &crit_pkts_refbuf0); kgsl_sharedmem_free(&crit_pkts_refbuf0); @@ -159,10 +155,10 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev) uint64_t gpuaddrs[4]; int ret; - ret = kgsl_allocate_global(&adreno_dev->dev, - &crit_pkts, PAGE_SIZE * 4, 0, 0, "crit_pkts"); - if (ret) - return ret; + adreno_dev->critpkts = kgsl_allocate_global(KGSL_DEVICE(adreno_dev), + PAGE_SIZE * 4, 0, 0, "crit_pkts"); + if (IS_ERR(adreno_dev->critpkts)) + return PTR_ERR(adreno_dev->critpkts); ret = kgsl_allocate_user(&adreno_dev->dev, &crit_pkts_refbuf0, PAGE_SIZE, KGSL_MEMFLAGS_SECURE, 0); @@ -174,12 +170,12 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev) if (ret) return ret; - cmds = crit_pkts.hostptr; + cmds = adreno_dev->critpkts->hostptr; gpuaddrs[0] = crit_pkts_refbuf0.gpuaddr; - gpuaddrs[1] = crit_pkts.gpuaddr + PAGE_SIZE; - gpuaddrs[2] = crit_pkts.gpuaddr + (PAGE_SIZE * 2); - gpuaddrs[3] = crit_pkts.gpuaddr + (PAGE_SIZE * 3); + gpuaddrs[1] = adreno_dev->critpkts->gpuaddr + PAGE_SIZE; + gpuaddrs[2] = adreno_dev->critpkts->gpuaddr + (PAGE_SIZE * 2); + gpuaddrs[3] = adreno_dev->critpkts->gpuaddr + (PAGE_SIZE * 3); crit_pkts_dwords = ARRAY_SIZE(_a5xx_critical_pkts); @@ -188,15 +184,15 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev) _do_fixup(critical_pkt_fixups, ARRAY_SIZE(critical_pkt_fixups), gpuaddrs, cmds); - cmds = crit_pkts.hostptr + PAGE_SIZE; + cmds = adreno_dev->critpkts->hostptr + PAGE_SIZE; memcpy(cmds, _a5xx_critical_pkts_mem01, ARRAY_SIZE(_a5xx_critical_pkts_mem01) << 2); - cmds = crit_pkts.hostptr + (PAGE_SIZE * 2); + cmds = adreno_dev->critpkts->hostptr + (PAGE_SIZE * 2); memcpy(cmds, _a5xx_critical_pkts_mem02, ARRAY_SIZE(_a5xx_critical_pkts_mem02) << 2); - cmds = crit_pkts.hostptr + (PAGE_SIZE * 3); + cmds = adreno_dev->critpkts->hostptr + (PAGE_SIZE * 3); memcpy(cmds, _a5xx_critical_pkts_mem03, ARRAY_SIZE(_a5xx_critical_pkts_mem03) << 2); @@ -1589,7 +1585,7 @@ static int _preemption_init( struct kgsl_context *context) { unsigned int *cmds_orig = cmds; - uint64_t gpuaddr = rb->preemption_desc.gpuaddr; + uint64_t gpuaddr = rb->preemption_desc->gpuaddr; /* Turn CP protection OFF */ cmds += cp_protected_mode(adreno_dev, cmds, 0); @@ -1698,13 +1694,13 @@ static int a5xx_microcode_load(struct adreno_device *adreno_dev) const struct adreno_a5xx_core *a5xx_core = to_a5xx_core(adreno_dev); uint64_t gpuaddr; - gpuaddr = pm4_fw->memdesc.gpuaddr; + gpuaddr = pm4_fw->memdesc->gpuaddr; kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PM4_INSTR_BASE_HI, upper_32_bits(gpuaddr)); - gpuaddr = pfp_fw->memdesc.gpuaddr; + gpuaddr = pfp_fw->memdesc->gpuaddr; kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A5XX_CP_PFP_INSTR_BASE_HI, @@ -1841,7 +1837,7 @@ int a5xx_critical_packet_submit(struct adreno_device *adreno_dev, return PTR_ERR(cmds); *cmds++ = cp_mem_packet(adreno_dev, CP_INDIRECT_BUFFER_PFE, 2, 1); - cmds += cp_gpuaddr(adreno_dev, cmds, crit_pkts.gpuaddr); + cmds += cp_gpuaddr(adreno_dev, cmds, adreno_dev->critpkts->gpuaddr); *cmds++ = crit_pkts_dwords; ret = adreno_ringbuffer_submit_spin(rb, NULL, 20); @@ -1910,7 +1906,7 @@ static int a5xx_rb_start(struct adreno_device *adreno_dev) A5XX_CP_RB_CNTL_DEFAULT); adreno_writereg64(adreno_dev, ADRENO_REG_CP_RB_BASE, - ADRENO_REG_CP_RB_BASE_HI, rb->buffer_desc.gpuaddr); + ADRENO_REG_CP_RB_BASE_HI, rb->buffer_desc->gpuaddr); ret = a5xx_microcode_load(adreno_dev); if (ret) @@ -1937,36 +1933,6 @@ static int a5xx_rb_start(struct adreno_device *adreno_dev) return 0; } -static int _load_firmware(struct kgsl_device *device, const char *fwfile, - struct adreno_firmware *firmware) -{ - const struct firmware *fw = NULL; - int ret; - - ret = request_firmware(&fw, fwfile, device->dev); - - if (ret) { - dev_err(device->dev, "request_firmware(%s) failed: %d\n", - fwfile, ret); - return ret; - } - - ret = kgsl_allocate_global(device, &firmware->memdesc, fw->size - 4, - KGSL_MEMFLAGS_GPUREADONLY, 0, "ucode"); - - if (ret) - goto done; - - memcpy(firmware->memdesc.hostptr, &fw->data[4], fw->size - 4); - firmware->size = (fw->size - 4) / sizeof(uint32_t); - firmware->version = *(unsigned int *)&fw->data[4]; - -done: - release_firmware(fw); - - return ret; -} - /* * a5xx_microcode_read() - Read microcode * @adreno_dev: Pointer to adreno device @@ -1978,19 +1944,13 @@ static int a5xx_microcode_read(struct adreno_device *adreno_dev) struct adreno_firmware *pfp_fw = ADRENO_FW(adreno_dev, ADRENO_FW_PFP); const struct adreno_a5xx_core *a5xx_core = to_a5xx_core(adreno_dev); - if (pm4_fw->memdesc.hostptr == NULL) { - ret = _load_firmware(KGSL_DEVICE(adreno_dev), - a5xx_core->pm4fw_name, pm4_fw); - if (ret) - return ret; - } + ret = adreno_get_firmware(adreno_dev, a5xx_core->pm4fw_name, pm4_fw); + if (ret) + return ret; - if (pfp_fw->memdesc.hostptr == NULL) { - ret = _load_firmware(KGSL_DEVICE(adreno_dev), - a5xx_core->pfpfw_name, pfp_fw); - if (ret) - return ret; - } + ret = adreno_get_firmware(adreno_dev, a5xx_core->pfpfw_name, pfp_fw); + if (ret) + return ret; ret = _load_gpmu_firmware(adreno_dev); if (ret) @@ -2665,7 +2625,7 @@ static void a5xx_cp_callback(struct adreno_device *adreno_dev, int bit) if (test_bit(ADRENO_DEVICE_CACHE_FLUSH_TS_SUSPENDED, &adreno_dev->priv)) return; - kgsl_sharedmem_readl(&device->memstore, &cur, + kgsl_sharedmem_readl(device->memstore, &cur, KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, ref_wait_ts)); diff --git a/drivers/gpu/msm/adreno_a5xx_preempt.c b/drivers/gpu/msm/adreno_a5xx_preempt.c index 195def53d833..69da71962307 100644 --- a/drivers/gpu/msm/adreno_a5xx_preempt.c +++ b/drivers/gpu/msm/adreno_a5xx_preempt.c @@ -241,26 +241,26 @@ void a5xx_preemption_trigger(struct adreno_device *adreno_dev) * preemption_desc at init time, so no need to check if * sharedmem accesses to these memdescs succeed. */ - kgsl_sharedmem_readq(&next->pagetable_desc, &ttbr0, + kgsl_sharedmem_readq(next->pagetable_desc, &ttbr0, PT_INFO_OFFSET(ttbr0)); - kgsl_sharedmem_readl(&next->pagetable_desc, &contextidr, + kgsl_sharedmem_readl(next->pagetable_desc, &contextidr, PT_INFO_OFFSET(contextidr)); - kgsl_sharedmem_writel(device, &next->preemption_desc, + kgsl_sharedmem_writel(device, next->preemption_desc, PREEMPT_RECORD(wptr), next->wptr); spin_unlock_irqrestore(&next->preempt_lock, flags); /* And write it to the smmu info */ - kgsl_sharedmem_writeq(device, &iommu->smmu_info, + kgsl_sharedmem_writeq(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(ttbr0), ttbr0); - kgsl_sharedmem_writel(device, &iommu->smmu_info, + kgsl_sharedmem_writel(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(context_idr), contextidr); kgsl_regwrite(device, A5XX_CP_CONTEXT_SWITCH_RESTORE_ADDR_LO, - lower_32_bits(next->preemption_desc.gpuaddr)); + lower_32_bits(next->preemption_desc->gpuaddr)); kgsl_regwrite(device, A5XX_CP_CONTEXT_SWITCH_RESTORE_ADDR_HI, - upper_32_bits(next->preemption_desc.gpuaddr)); + upper_32_bits(next->preemption_desc->gpuaddr)); adreno_dev->next_rb = next; @@ -346,7 +346,7 @@ unsigned int a5xx_preemption_pre_ibsubmit( unsigned int *cmds, struct kgsl_context *context) { unsigned int *cmds_orig = cmds; - uint64_t gpuaddr = rb->preemption_desc.gpuaddr; + uint64_t gpuaddr = rb->preemption_desc->gpuaddr; unsigned int preempt_style = 0; if (context) { @@ -463,31 +463,31 @@ void a5xx_preemption_start(struct adreno_device *adreno_dev) adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE); /* smmu_info is allocated and mapped in a5xx_preemption_iommu_init */ - kgsl_sharedmem_writel(device, &iommu->smmu_info, + kgsl_sharedmem_writel(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(magic), A5XX_CP_SMMU_INFO_MAGIC_REF); - kgsl_sharedmem_writeq(device, &iommu->smmu_info, + kgsl_sharedmem_writeq(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(ttbr0), MMU_DEFAULT_TTBR0(device)); /* The CP doesn't use the asid record, so poison it */ - kgsl_sharedmem_writel(device, &iommu->smmu_info, + kgsl_sharedmem_writel(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(asid), 0xDECAFBAD); - kgsl_sharedmem_writel(device, &iommu->smmu_info, + kgsl_sharedmem_writel(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(context_idr), MMU_DEFAULT_CONTEXTIDR(device)); adreno_writereg64(adreno_dev, ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_LO, ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_HI, - iommu->smmu_info.gpuaddr); + iommu->smmu_info->gpuaddr); FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { /* * preemption_desc is allocated and mapped at init time, * so no need to check sharedmem_writel return value */ - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(rptr), 0); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(wptr), 0); adreno_ringbuffer_set_pagetable(rb, @@ -500,32 +500,33 @@ static int a5xx_preemption_ringbuffer_init(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb, uint64_t counteraddr) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); - int ret; - ret = kgsl_allocate_global(device, &rb->preemption_desc, - A5XX_CP_CTXRECORD_SIZE_IN_BYTES, 0, KGSL_MEMDESC_PRIVILEGED, - "preemption_desc"); - if (ret) - return ret; + if (IS_ERR_OR_NULL(rb->preemption_desc)) + rb->preemption_desc = kgsl_allocate_global(device, + A5XX_CP_CTXRECORD_SIZE_IN_BYTES, 0, + KGSL_MEMDESC_PRIVILEGED, "preemption_desc"); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + if (IS_ERR(rb->preemption_desc)) + return PTR_ERR(rb->preemption_desc); + + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(magic), A5XX_CP_CTXRECORD_MAGIC_REF); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(info), 0); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(data), 0); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(cntl), A5XX_CP_RB_CNTL_DEFAULT); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(rptr), 0); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(wptr), 0); - kgsl_sharedmem_writeq(device, &rb->preemption_desc, + kgsl_sharedmem_writeq(device, rb->preemption_desc, PREEMPT_RECORD(rptr_addr), SCRATCH_RPTR_GPU_ADDR(device, rb->id)); - kgsl_sharedmem_writeq(device, &rb->preemption_desc, - PREEMPT_RECORD(rbase), rb->buffer_desc.gpuaddr); - kgsl_sharedmem_writeq(device, &rb->preemption_desc, + kgsl_sharedmem_writeq(device, rb->preemption_desc, + PREEMPT_RECORD(rbase), rb->buffer_desc->gpuaddr); + kgsl_sharedmem_writeq(device, rb->preemption_desc, PREEMPT_RECORD(counter), counteraddr); return 0; @@ -538,44 +539,25 @@ static int a5xx_preemption_iommu_init(struct adreno_device *adreno_dev) struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); /* Allocate mem for storing preemption smmu record */ - return kgsl_allocate_global(device, &iommu->smmu_info, PAGE_SIZE, - KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_PRIVILEGED, - "smmu_info"); + if (IS_ERR_OR_NULL(iommu->smmu_info)) + iommu->smmu_info = kgsl_allocate_global(device, PAGE_SIZE, + KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_PRIVILEGED, + "smmu_info"); + + return PTR_ERR_OR_ZERO(iommu->smmu_info); } - -static void a5xx_preemption_iommu_close(struct adreno_device *adreno_dev) -{ - struct kgsl_device *device = KGSL_DEVICE(adreno_dev); - struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); - - kgsl_free_global(device, &iommu->smmu_info); -} - #else static int a5xx_preemption_iommu_init(struct adreno_device *adreno_dev) { return -ENODEV; } - -static void a5xx_preemption_iommu_close(struct adreno_device *adreno_dev) -{ -} #endif static void _preemption_close(struct adreno_device *adreno_dev) { - struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_preemption *preempt = &adreno_dev->preempt; - struct adreno_ringbuffer *rb; - unsigned int i; del_timer(&preempt->timer); - kgsl_free_global(device, &preempt->counters); - a5xx_preemption_iommu_close(adreno_dev); - - FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { - kgsl_free_global(device, &rb->preemption_desc); - } } void a5xx_preemption_close(struct adreno_device *adreno_dev) @@ -604,14 +586,17 @@ int a5xx_preemption_init(struct adreno_device *adreno_dev) timer_setup(&preempt->timer, _a5xx_preemption_timer, 0); /* Allocate mem for storing preemption counters */ - ret = kgsl_allocate_global(device, &preempt->counters, - adreno_dev->num_ringbuffers * - A5XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE, 0, 0, - "preemption_counters"); + if (IS_ERR_OR_NULL(preempt->counters)) + preempt->counters = kgsl_allocate_global(device, + adreno_dev->num_ringbuffers * + A5XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE, 0, 0, + "preemption_counters"); + + ret = PTR_ERR_OR_ZERO(preempt->counters); if (ret) goto err; - addr = preempt->counters.gpuaddr; + addr = preempt->counters->gpuaddr; /* Allocate mem for storing preemption switch record */ FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { diff --git a/drivers/gpu/msm/adreno_a5xx_snapshot.c b/drivers/gpu/msm/adreno_a5xx_snapshot.c index 8f554ba9fdcb..16440fcd4f2d 100644 --- a/drivers/gpu/msm/adreno_a5xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a5xx_snapshot.c @@ -137,7 +137,7 @@ static size_t a5xx_snapshot_cp_pm4(struct kgsl_device *device, u8 *buf, header->type = SNAPSHOT_DEBUG_CP_PM4_RAM; header->size = size; - memcpy(data, fw->memdesc.hostptr, size * sizeof(uint32_t)); + memcpy(data, fw->memdesc->hostptr, size * sizeof(uint32_t)); return DEBUG_SECTION_SZ(size); } @@ -160,7 +160,7 @@ static size_t a5xx_snapshot_cp_pfp(struct kgsl_device *device, u8 *buf, header->type = SNAPSHOT_DEBUG_CP_PFP_RAM; header->size = size; - memcpy(data, fw->memdesc.hostptr, size * sizeof(uint32_t)); + memcpy(data, fw->memdesc->hostptr, size * sizeof(uint32_t)); return DEBUG_SECTION_SZ(size); } @@ -595,8 +595,8 @@ static struct a5xx_shader_block a5xx_shader_blocks[] = { {A5XX_TP_POWER_RESTORE_RAM, 0x40}, }; -static struct kgsl_memdesc capturescript; -static struct kgsl_memdesc registers; +static struct kgsl_memdesc *capturescript; +static struct kgsl_memdesc *registers; static bool crash_dump_valid; static size_t a5xx_snapshot_shader_memory(struct kgsl_device *device, @@ -618,7 +618,7 @@ static size_t a5xx_snapshot_shader_memory(struct kgsl_device *device, header->index = info->bank; header->size = block->sz; - memcpy(data, registers.hostptr + info->offset, + memcpy(data, registers->hostptr + info->offset, block->sz * sizeof(unsigned int)); return SHADER_SECTION_SZ(block->sz); @@ -686,7 +686,7 @@ static size_t a5xx_snapshot_registers(struct kgsl_device *device, u8 *buf, { struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf; unsigned int *data = (unsigned int *)(buf + sizeof(*header)); - unsigned int *src = (unsigned int *) registers.hostptr; + unsigned int *src = (unsigned int *) registers->hostptr; struct registers *regs = (struct registers *)priv; unsigned int j, k; unsigned int count = 0; @@ -764,7 +764,8 @@ static void _a5xx_do_crashdump(struct kgsl_device *device) if (!device->snapshot_crashdumper) return; - if (capturescript.gpuaddr == 0 || registers.gpuaddr == 0) + + if (IS_ERR_OR_NULL(capturescript) || IS_ERR_OR_NULL(registers)) return; /* IF the SMMU is stalled we cannot do a crash dump */ @@ -776,9 +777,9 @@ static void _a5xx_do_crashdump(struct kgsl_device *device) kgsl_regwrite(device, A5XX_CP_CNTL, 1); kgsl_regwrite(device, A5XX_CP_CRASH_SCRIPT_BASE_LO, - lower_32_bits(capturescript.gpuaddr)); + lower_32_bits(capturescript->gpuaddr)); kgsl_regwrite(device, A5XX_CP_CRASH_SCRIPT_BASE_HI, - upper_32_bits(capturescript.gpuaddr)); + upper_32_bits(capturescript->gpuaddr)); kgsl_regwrite(device, A5XX_CP_CRASH_DUMP_CNTL, 1); wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT); @@ -803,7 +804,7 @@ static int get_hlsq_registers(struct kgsl_device *device, const struct a5xx_hlsq_sp_tp_regs *regs, unsigned int *data) { unsigned int i; - unsigned int *src = registers.hostptr + regs->offset; + unsigned int *src = registers->hostptr + regs->offset; for (i = 0; i < regs->size; i++) { *data++ = regs->ahbaddr + i; @@ -1016,7 +1017,7 @@ static int _a5xx_crashdump_init_shader(struct a5xx_shader_block *block, (1 << 21) | 1; /* Read all the data in one chunk */ - ptr[qwords++] = registers.gpuaddr + *offset; + ptr[qwords++] = registers->gpuaddr + *offset; ptr[qwords++] = (((uint64_t) A5XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) | block->sz; @@ -1043,7 +1044,7 @@ static int _a5xx_crashdump_init_hlsq(struct a5xx_hlsq_sp_tp_regs *regs, (1 << 21) | 1; /* Read all the data in one chunk */ - ptr[qwords++] = registers.gpuaddr + *offset; + ptr[qwords++] = registers->gpuaddr + *offset; ptr[qwords++] = (((uint64_t) A5XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) | regs->size; @@ -1065,7 +1066,7 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev) uint64_t *ptr; uint64_t offset = 0; - if (capturescript.gpuaddr != 0 && registers.gpuaddr != 0) + if (!IS_ERR_OR_NULL(capturescript) && !IS_ERR_OR_NULL(registers)) return; /* @@ -1117,25 +1118,30 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev) /* Now allocate the script and data buffers */ /* The script buffers needs 2 extra qwords on the end */ - if (kgsl_allocate_global(device, &capturescript, - script_size + 16, KGSL_MEMFLAGS_GPUREADONLY, - KGSL_MEMDESC_PRIVILEGED, "capturescript")) + if (!IS_ERR_OR_NULL(capturescript)) + capturescript = kgsl_allocate_global(device, + script_size + 16, KGSL_MEMFLAGS_GPUREADONLY, + KGSL_MEMDESC_PRIVILEGED, "capturescript"); + + if (IS_ERR(capturescript)) return; - if (kgsl_allocate_global(device, ®isters, data_size, 0, - KGSL_MEMDESC_PRIVILEGED, "capturescript_regs")) { - kgsl_free_global(KGSL_DEVICE(adreno_dev), &capturescript); + if (!IS_ERR_OR_NULL(registers)) + registers = kgsl_allocate_global(device, data_size, 0, + KGSL_MEMDESC_PRIVILEGED, "capturescript_regs"); + + if (IS_ERR(registers)) return; - } + /* Build the crash script */ - ptr = (uint64_t *) capturescript.hostptr; + ptr = (uint64_t *) capturescript->hostptr; /* For the registers, program a read command for each pair */ for (j = 0; j < ARRAY_SIZE(a5xx_registers) / 2; j++) { unsigned int r = REG_PAIR_COUNT(a5xx_registers, j); - *ptr++ = registers.gpuaddr + offset; + *ptr++ = registers->gpuaddr + offset; *ptr++ = (((uint64_t) a5xx_registers[2 * j]) << 44) | r; offset += r * sizeof(unsigned int); @@ -1144,7 +1150,7 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev) if (ADRENO_FEATURE(adreno_dev, ADRENO_GPMU)) { for (j = 0; j < ARRAY_SIZE(a5xx_gpmu_registers) / 2; j++) { unsigned int r = REG_PAIR_COUNT(a5xx_gpmu_registers, j); - *ptr++ = registers.gpuaddr + offset; + *ptr++ = registers->gpuaddr + offset; *ptr++ = (((uint64_t) a5xx_gpmu_registers[2 * j]) << 44) | r; offset += r * sizeof(unsigned int); diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index befc3ebec12e..7fd3aba67596 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -3,7 +3,6 @@ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ -#include #include #include #include @@ -114,7 +113,7 @@ static void a6xx_init(struct adreno_device *adreno_dev) a6xx_crashdump_init(adreno_dev); - kgsl_allocate_global(device, &adreno_dev->pwrup_reglist, + adreno_dev->pwrup_reglist = kgsl_allocate_global(device, PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED, "powerup_register_list"); } @@ -272,7 +271,7 @@ struct a6xx_reglist_list { static void a6xx_patch_pwrup_reglist(struct adreno_device *adreno_dev) { struct a6xx_reglist_list reglist[3]; - void *ptr = adreno_dev->pwrup_reglist.hostptr; + void *ptr = adreno_dev->pwrup_reglist->hostptr; struct cpu_gpu_lock *lock = ptr; int items = 0, i, j; u32 *dest = ptr + sizeof(*lock); @@ -535,7 +534,7 @@ static void a6xx_start(struct adreno_device *adreno_dev) a6xx_protect_init(adreno_dev); - if (!patch_reglist && (adreno_dev->pwrup_reglist.gpuaddr != 0)) { + if (!patch_reglist && (adreno_dev->pwrup_reglist->gpuaddr != 0)) { a6xx_patch_pwrup_reglist(adreno_dev); patch_reglist = true; } @@ -571,7 +570,7 @@ static int a6xx_microcode_load(struct adreno_device *adreno_dev) void *zap; int ret = 0; - gpuaddr = fw->memdesc.gpuaddr; + gpuaddr = fw->memdesc->gpuaddr; kgsl_regwrite(device, A6XX_CP_SQE_INSTR_BASE_LO, lower_32_bits(gpuaddr)); kgsl_regwrite(device, A6XX_CP_SQE_INSTR_BASE_HI, @@ -664,7 +663,7 @@ static void _set_ordinals(struct adreno_device *adreno_dev, *cmds++ = 0x00000002; if (CP_INIT_MASK & CP_INIT_REGISTER_INIT_LIST_WITH_SPINLOCK) { - uint64_t gpuaddr = adreno_dev->pwrup_reglist.gpuaddr; + uint64_t gpuaddr = adreno_dev->pwrup_reglist->gpuaddr; *cmds++ = lower_32_bits(gpuaddr); *cmds++ = upper_32_bits(gpuaddr); @@ -703,7 +702,7 @@ static int a6xx_send_cp_init(struct adreno_device *adreno_dev, adreno_spin_idle_debug(adreno_dev, "CP initialization failed to idle\n"); - kgsl_sharedmem_writel(device, &device->scratch, + kgsl_sharedmem_writel(device, device->scratch, SCRATCH_RPTR_OFFSET(rb->id), 0); rb->wptr = 0; rb->_wptr = 0; @@ -729,7 +728,7 @@ static int _preemption_init(struct adreno_device *adreno_dev, *cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 6); *cmds++ = 1; cmds += cp_gpuaddr(adreno_dev, cmds, - rb->preemption_desc.gpuaddr); + rb->preemption_desc->gpuaddr); *cmds++ = 2; cmds += cp_gpuaddr(adreno_dev, cmds, @@ -816,7 +815,7 @@ static int a6xx_rb_start(struct adreno_device *adreno_dev) A6XX_CP_RB_CNTL_DEFAULT); adreno_writereg64(adreno_dev, ADRENO_REG_CP_RB_BASE, - ADRENO_REG_CP_RB_BASE_HI, rb->buffer_desc.gpuaddr); + ADRENO_REG_CP_RB_BASE_HI, rb->buffer_desc->gpuaddr); ret = a6xx_microcode_load(adreno_dev); if (ret) @@ -904,34 +903,6 @@ unsigned int a6xx_set_marker( return 2; } -static int _load_firmware(struct kgsl_device *device, const char *fwfile, - struct adreno_firmware *firmware) -{ - const struct firmware *fw = NULL; - int ret; - - ret = request_firmware(&fw, fwfile, device->dev); - - if (ret) { - dev_err(device->dev, "request_firmware(%s) failed: %d\n", - fwfile, ret); - return ret; - } - - ret = kgsl_allocate_global(device, &firmware->memdesc, fw->size - 4, - KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_UCODE, - "ucode"); - - if (!ret) { - memcpy(firmware->memdesc.hostptr, &fw->data[4], fw->size - 4); - firmware->size = (fw->size - 4) / sizeof(uint32_t); - firmware->version = *(unsigned int *)&fw->data[4]; - } - - release_firmware(fw); - return ret; -} - /* * a6xx_gpu_keepalive() - GMU reg write to request GPU stays on * @adreno_dev: Pointer to the adreno device that has the GMU @@ -966,18 +937,10 @@ static bool a6xx_hw_isidle(struct adreno_device *adreno_dev) */ static int a6xx_microcode_read(struct adreno_device *adreno_dev) { - int ret; - struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_firmware *sqe_fw = ADRENO_FW(adreno_dev, ADRENO_FW_SQE); const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev); - if (sqe_fw->memdesc.hostptr == NULL) { - ret = _load_firmware(device, a6xx_core->sqefw_name, sqe_fw); - if (ret) - return ret; - } - - return 0; + return adreno_get_firmware(adreno_dev, a6xx_core->sqefw_name, sqe_fw); } static int a6xx_soft_reset(struct adreno_device *adreno_dev) @@ -2480,7 +2443,7 @@ static void cpu_gpu_unlock(struct cpu_gpu_lock *lock) static int a6xx_perfcounter_update(struct adreno_device *adreno_dev, struct adreno_perfcount_register *reg, bool update_reg) { - void *ptr = adreno_dev->pwrup_reglist.hostptr; + void *ptr = adreno_dev->pwrup_reglist->hostptr; struct cpu_gpu_lock *lock = ptr; u32 *data = ptr + sizeof(*lock); int i, offset = 0; diff --git a/drivers/gpu/msm/adreno_a6xx_preempt.c b/drivers/gpu/msm/adreno_a6xx_preempt.c index 03921472675c..44e84d849c5d 100644 --- a/drivers/gpu/msm/adreno_a6xx_preempt.c +++ b/drivers/gpu/msm/adreno_a6xx_preempt.c @@ -280,23 +280,23 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev) * preemption_desc at init time, so no need to check if * sharedmem accesses to these memdescs succeed. */ - kgsl_sharedmem_readq(&next->pagetable_desc, &ttbr0, + kgsl_sharedmem_readq(next->pagetable_desc, &ttbr0, PT_INFO_OFFSET(ttbr0)); - kgsl_sharedmem_readl(&next->pagetable_desc, &contextidr, + kgsl_sharedmem_readl(next->pagetable_desc, &contextidr, PT_INFO_OFFSET(contextidr)); - kgsl_sharedmem_writel(device, &next->preemption_desc, + kgsl_sharedmem_writel(device, next->preemption_desc, PREEMPT_RECORD(wptr), next->wptr); spin_unlock_irqrestore(&next->preempt_lock, flags); /* And write it to the smmu info */ - kgsl_sharedmem_writeq(device, &iommu->smmu_info, + kgsl_sharedmem_writeq(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(ttbr0), ttbr0); - kgsl_sharedmem_writel(device, &iommu->smmu_info, + kgsl_sharedmem_writel(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(context_idr), contextidr); - kgsl_sharedmem_readq(&device->scratch, &gpuaddr, + kgsl_sharedmem_readq(device->scratch, &gpuaddr, SCRATCH_PREEMPTION_CTXT_RESTORE_ADDR_OFFSET(next->id)); /* @@ -321,7 +321,7 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev) */ if (adreno_gmu_fenced_write(adreno_dev, ADRENO_REG_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_LO, - lower_32_bits(next->preemption_desc.gpuaddr), + lower_32_bits(next->preemption_desc->gpuaddr), FENCE_STATUS_WRITEDROPPED1_MASK)) goto err; @@ -339,7 +339,7 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev) if (adreno_gmu_fenced_write(adreno_dev, ADRENO_REG_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_HI, - upper_32_bits(next->preemption_desc.gpuaddr), + upper_32_bits(next->preemption_desc->gpuaddr), FENCE_STATUS_WRITEDROPPED1_MASK)) goto err; @@ -494,7 +494,7 @@ unsigned int a6xx_preemption_pre_ibsubmit( cmds += cp_gpuaddr(adreno_dev, cmds, 0x0); *cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_PRIV_NON_SECURE_SAVE_ADDR; - cmds += cp_gpuaddr(adreno_dev, cmds, rb->preemption_desc.gpuaddr); + cmds += cp_gpuaddr(adreno_dev, cmds, rb->preemption_desc->gpuaddr); *cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_PRIV_SECURE_SAVE_ADDR; cmds += cp_gpuaddr(adreno_dev, cmds, @@ -515,7 +515,7 @@ unsigned int a6xx_preemption_pre_ibsubmit( */ *cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_COUNTER; cmds += cp_gpuaddr(adreno_dev, cmds, - rb->perfcounter_save_restore_desc.gpuaddr); + rb->perfcounter_save_restore_desc->gpuaddr); if (context) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); @@ -573,31 +573,31 @@ void a6xx_preemption_start(struct adreno_device *adreno_dev) adreno_set_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE); /* smmu_info is allocated and mapped in a6xx_preemption_iommu_init */ - kgsl_sharedmem_writel(device, &iommu->smmu_info, + kgsl_sharedmem_writel(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(magic), A6XX_CP_SMMU_INFO_MAGIC_REF); - kgsl_sharedmem_writeq(device, &iommu->smmu_info, + kgsl_sharedmem_writeq(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(ttbr0), MMU_DEFAULT_TTBR0(device)); /* The CP doesn't use the asid record, so poison it */ - kgsl_sharedmem_writel(device, &iommu->smmu_info, + kgsl_sharedmem_writel(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(asid), 0xDECAFBAD); - kgsl_sharedmem_writel(device, &iommu->smmu_info, + kgsl_sharedmem_writel(device, iommu->smmu_info, PREEMPT_SMMU_RECORD(context_idr), MMU_DEFAULT_CONTEXTIDR(device)); adreno_writereg64(adreno_dev, ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_LO, ADRENO_REG_CP_CONTEXT_SWITCH_SMMU_INFO_HI, - iommu->smmu_info.gpuaddr); + iommu->smmu_info->gpuaddr); FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { /* * preemption_desc is allocated and mapped at init time, * so no need to check sharedmem_writel return value */ - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(rptr), 0); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(wptr), 0); adreno_ringbuffer_set_pagetable(rb, @@ -611,11 +611,12 @@ static int a6xx_preemption_ringbuffer_init(struct adreno_device *adreno_dev, struct kgsl_device *device = KGSL_DEVICE(adreno_dev); int ret; - ret = kgsl_allocate_global(device, &rb->preemption_desc, - A6XX_CP_CTXRECORD_SIZE_IN_BYTES, 0, KGSL_MEMDESC_PRIVILEGED, - "preemption_desc"); - if (ret) - return ret; + if (IS_ERR_OR_NULL(rb->preemption_desc)) + rb->preemption_desc = kgsl_allocate_global(device, + A6XX_CP_CTXRECORD_SIZE_IN_BYTES, 0, + KGSL_MEMDESC_PRIVILEGED, "preemption_desc"); + if (IS_ERR(rb->preemption_desc)) + return PTR_ERR(rb->preemption_desc); ret = kgsl_allocate_user(device, &rb->secure_preemption_desc, A6XX_CP_CTXRECORD_SIZE_IN_BYTES, @@ -628,30 +629,33 @@ static int a6xx_preemption_ringbuffer_init(struct adreno_device *adreno_dev, if (ret) return ret; - ret = kgsl_allocate_global(device, &rb->perfcounter_save_restore_desc, - A6XX_CP_PERFCOUNTER_SAVE_RESTORE_SIZE, 0, - KGSL_MEMDESC_PRIVILEGED, "perfcounter_save_restore_desc"); - if (ret) - return ret; + if (IS_ERR_OR_NULL(rb->perfcounter_save_restore_desc)) + rb->perfcounter_save_restore_desc = kgsl_allocate_global(device, + A6XX_CP_PERFCOUNTER_SAVE_RESTORE_SIZE, 0, + KGSL_MEMDESC_PRIVILEGED, + "perfcounter_save_restore_desc"); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + if (IS_ERR(rb->perfcounter_save_restore_desc)) + return PTR_ERR(rb->perfcounter_save_restore_desc); + + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(magic), A6XX_CP_CTXRECORD_MAGIC_REF); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(info), 0); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(data), 0); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(cntl), A6XX_CP_RB_CNTL_DEFAULT); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(rptr), 0); - kgsl_sharedmem_writel(device, &rb->preemption_desc, + kgsl_sharedmem_writel(device, rb->preemption_desc, PREEMPT_RECORD(wptr), 0); - kgsl_sharedmem_writeq(device, &rb->preemption_desc, + kgsl_sharedmem_writeq(device, rb->preemption_desc, PREEMPT_RECORD(rptr_addr), SCRATCH_RPTR_GPU_ADDR(device, rb->id)); - kgsl_sharedmem_writeq(device, &rb->preemption_desc, - PREEMPT_RECORD(rbase), rb->buffer_desc.gpuaddr); - kgsl_sharedmem_writeq(device, &rb->preemption_desc, + kgsl_sharedmem_writeq(device, rb->preemption_desc, + PREEMPT_RECORD(rbase), rb->buffer_desc->gpuaddr); + kgsl_sharedmem_writeq(device, rb->preemption_desc, PREEMPT_RECORD(counter), 0); return 0; @@ -664,27 +668,18 @@ static int a6xx_preemption_iommu_init(struct adreno_device *adreno_dev) struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); /* Allocate mem for storing preemption smmu record */ - return kgsl_allocate_global(device, &iommu->smmu_info, PAGE_SIZE, - KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_PRIVILEGED, - "smmu_info"); -} + if (IS_ERR_OR_NULL(iommu->smmu_info)) + iommu->smmu_info = kgsl_allocate_global(device, PAGE_SIZE, + KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_PRIVILEGED, + "smmu_info"); -static void a6xx_preemption_iommu_close(struct adreno_device *adreno_dev) -{ - struct kgsl_device *device = KGSL_DEVICE(adreno_dev); - struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); - - kgsl_free_global(device, &iommu->smmu_info); + return PTR_ERR_OR_ZERO(iommu->smmu_info); } #else static int a6xx_preemption_iommu_init(struct adreno_device *adreno_dev) { return -ENODEV; } - -static void a6xx_preemption_iommu_close(struct adreno_device *adreno_dev) -{ -} #endif static void _preemption_close(struct adreno_device *adreno_dev) @@ -695,11 +690,8 @@ static void _preemption_close(struct adreno_device *adreno_dev) unsigned int i; del_timer(&preempt->timer); - a6xx_preemption_iommu_close(adreno_dev); FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { - kgsl_free_global(device, &rb->preemption_desc); - kgsl_free_global(device, &rb->perfcounter_save_restore_desc); kgsl_iommu_unmap_global_secure_pt_entry(device, &rb->secure_preemption_desc); kgsl_sharedmem_free(&rb->secure_preemption_desc); diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c index 2f97f7caf2a7..85eda2115e88 100644 --- a/drivers/gpu/msm/adreno_a6xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c @@ -621,8 +621,8 @@ static struct a6xx_shader_block a6xx_shader_blocks[] = { {A6XX_HLSQ_INDIRECT_META, 0x40,} }; -static struct kgsl_memdesc a6xx_capturescript; -static struct kgsl_memdesc a6xx_crashdump_registers; +static struct kgsl_memdesc *a6xx_capturescript; +static struct kgsl_memdesc *a6xx_crashdump_registers; static bool crash_dump_valid; static struct reg_list { @@ -675,7 +675,7 @@ static size_t a6xx_snapshot_registers(struct kgsl_device *device, u8 *buf, return 0; } - src = (unsigned int *)(a6xx_crashdump_registers.hostptr + regs->offset); + src = a6xx_crashdump_registers->hostptr + regs->offset; remain -= sizeof(*header); for (j = 0; j < regs->count; j++) { @@ -778,7 +778,7 @@ static size_t a6xx_snapshot_shader_memory(struct kgsl_device *device, header->index = info->bank; header->size = block->sz; - memcpy(data, a6xx_crashdump_registers.hostptr + info->offset, + memcpy(data, a6xx_crashdump_registers->hostptr + info->offset, block->sz * sizeof(unsigned int)); return SHADER_SECTION_SZ(block->sz); @@ -935,8 +935,8 @@ static size_t a6xx_snapshot_cluster_dbgahb(struct kgsl_device *device, u8 *buf, header->ctxt_id = info->ctxt_id; header->cluster_id = cluster->id; - src = (unsigned int *)(a6xx_crashdump_registers.hostptr + - (header->ctxt_id ? cluster->offset1 : cluster->offset0)); + src = a6xx_crashdump_registers->hostptr + + (header->ctxt_id ? cluster->offset1 : cluster->offset0); for (i = 0; i < cluster->num_sets; i++) { unsigned int start; @@ -1034,7 +1034,7 @@ static size_t a6xx_snapshot_non_ctx_dbgahb(struct kgsl_device *device, u8 *buf, remain -= sizeof(*header); - src = (unsigned int *)(a6xx_crashdump_registers.hostptr + regs->offset); + src = a6xx_crashdump_registers->hostptr + regs->offset; for (i = 0; i < regs->num_sets; i++) { unsigned int start; @@ -1175,8 +1175,8 @@ static size_t a6xx_snapshot_mvc(struct kgsl_device *device, u8 *buf, header->ctxt_id = info->ctxt_id; header->cluster_id = cluster->id; - src = (unsigned int *)(a6xx_crashdump_registers.hostptr + - (header->ctxt_id ? cluster->offset1 : cluster->offset0)); + src = a6xx_crashdump_registers->hostptr + + (header->ctxt_id ? cluster->offset1 : cluster->offset0); for (i = 0; i < cluster->num_sets; i++) { start = cluster->regs[2 * i]; @@ -1600,8 +1600,9 @@ static void _a6xx_do_crashdump(struct kgsl_device *device) if (!device->snapshot_crashdumper) return; - if (a6xx_capturescript.gpuaddr == 0 || - a6xx_crashdump_registers.gpuaddr == 0) + + if (IS_ERR_OR_NULL(a6xx_capturescript) || + IS_ERR_OR_NULL(a6xx_crashdump_registers)) return; /* IF the SMMU is stalled we cannot do a crash dump */ @@ -1614,9 +1615,9 @@ static void _a6xx_do_crashdump(struct kgsl_device *device) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1); kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_LO, - lower_32_bits(a6xx_capturescript.gpuaddr)); + lower_32_bits(a6xx_capturescript->gpuaddr)); kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_HI, - upper_32_bits(a6xx_capturescript.gpuaddr)); + upper_32_bits(a6xx_capturescript->gpuaddr)); kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1); wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT); @@ -1927,7 +1928,7 @@ static int _a6xx_crashdump_init_mvc(struct adreno_device *adreno_dev, for (k = 0; k < cluster->num_sets; k++) { count = REG_PAIR_COUNT(cluster->regs, k); ptr[qwords++] = - a6xx_crashdump_registers.gpuaddr + *offset; + a6xx_crashdump_registers->gpuaddr + *offset; ptr[qwords++] = (((uint64_t)cluster->regs[2 * k]) << 44) | count; @@ -1955,7 +1956,7 @@ static int _a6xx_crashdump_init_shader(struct a6xx_shader_block *block, (1 << 21) | 1; /* Read all the data in one chunk */ - ptr[qwords++] = a6xx_crashdump_registers.gpuaddr + *offset; + ptr[qwords++] = a6xx_crashdump_registers->gpuaddr + *offset; ptr[qwords++] = (((uint64_t) A6XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) | block->sz; @@ -1998,7 +1999,7 @@ static int _a6xx_crashdump_init_ctx_dbgahb(uint64_t *ptr, uint64_t *offset) count = REG_PAIR_COUNT(cluster->regs, k); ptr[qwords++] = - a6xx_crashdump_registers.gpuaddr + *offset; + a6xx_crashdump_registers->gpuaddr + *offset; ptr[qwords++] = (((uint64_t)(A6XX_HLSQ_DBG_AHB_READ_APERTURE + start - cluster->regbase / 4) << 44)) | @@ -2033,7 +2034,7 @@ static int _a6xx_crashdump_init_non_ctx_dbgahb(uint64_t *ptr, uint64_t *offset) count = REG_PAIR_COUNT(regs->regs, k); ptr[qwords++] = - a6xx_crashdump_registers.gpuaddr + *offset; + a6xx_crashdump_registers->gpuaddr + *offset; ptr[qwords++] = (((uint64_t)(A6XX_HLSQ_DBG_AHB_READ_APERTURE + start - regs->regbase / 4) << 44)) | @@ -2054,8 +2055,8 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) uint64_t *ptr; uint64_t offset = 0; - if (a6xx_capturescript.gpuaddr != 0 && - a6xx_crashdump_registers.gpuaddr != 0) + if (!IS_ERR_OR_NULL(a6xx_capturescript) && + !IS_ERR_OR_NULL(a6xx_crashdump_registers)) return; /* @@ -2163,20 +2164,25 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) /* Now allocate the script and data buffers */ /* The script buffers needs 2 extra qwords on the end */ - if (kgsl_allocate_global(device, &a6xx_capturescript, - script_size + 16, KGSL_MEMFLAGS_GPUREADONLY, - KGSL_MEMDESC_PRIVILEGED, "capturescript")) + if (IS_ERR_OR_NULL(a6xx_capturescript)) + a6xx_capturescript = kgsl_allocate_global(device, + script_size + 16, KGSL_MEMFLAGS_GPUREADONLY, + KGSL_MEMDESC_PRIVILEGED, "capturescript"); + + if (IS_ERR(a6xx_capturescript)) return; - if (kgsl_allocate_global(device, &a6xx_crashdump_registers, data_size, - 0, KGSL_MEMDESC_PRIVILEGED, "capturescript_regs")) { - kgsl_free_global(KGSL_DEVICE(adreno_dev), &a6xx_capturescript); + if (IS_ERR_OR_NULL(a6xx_crashdump_registers)) + a6xx_crashdump_registers = kgsl_allocate_global(device, + data_size, 0, KGSL_MEMDESC_PRIVILEGED, + "capturescript_regs"); + + if (IS_ERR(a6xx_crashdump_registers)) return; - } /* Build the crash script */ - ptr = (uint64_t *)a6xx_capturescript.hostptr; + ptr = (uint64_t *)a6xx_capturescript->hostptr; /* For the registers, program a read command for each pair */ for (i = 0; i < ARRAY_SIZE(a6xx_reg_list); i++) { @@ -2193,7 +2199,7 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) for (j = 0; j < regs->count; j++) { unsigned int r = REG_PAIR_COUNT(regs->regs, j); - *ptr++ = a6xx_crashdump_registers.gpuaddr + offset; + *ptr++ = a6xx_crashdump_registers->gpuaddr + offset; *ptr++ = (((uint64_t) regs->regs[2 * j]) << 44) | r; offset += r * sizeof(unsigned int); } diff --git a/drivers/gpu/msm/adreno_compat.c b/drivers/gpu/msm/adreno_compat.c index 26a6cb0c944e..1a1e157c4c66 100644 --- a/drivers/gpu/msm/adreno_compat.c +++ b/drivers/gpu/msm/adreno_compat.c @@ -50,7 +50,7 @@ int adreno_getproperty_compat(struct kgsl_device *device, break; } memset(&shadowprop, 0, sizeof(shadowprop)); - if (device->memstore.hostptr) { + if (device->memstore->hostptr) { /* * NOTE: with mmu enabled, gpuaddr doesn't mean * anything to mmap(). @@ -58,10 +58,10 @@ int adreno_getproperty_compat(struct kgsl_device *device, * (because legacy) and the memstore gpuaddr is * 64 bit. Cast the memstore gpuaddr to uint32. */ - shadowprop.gpuaddr = - (unsigned int) device->memstore.gpuaddr; + shadowprop.gpuaddr = (unsigned int) + device->memstore->gpuaddr; shadowprop.size = - (unsigned int) device->memstore.size; + (unsigned int) device->memstore->size; /* * GSL needs this to be set, even if it * appears to be meaningless diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 8eab36e4fb54..89fe47cba035 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -268,11 +268,11 @@ static void _retire_timestamp(struct kgsl_drawobj *drawobj) * Write the start and end timestamp to the memstore to keep the * accounting sane */ - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(context->id, soptimestamp), drawobj->timestamp); - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(context->id, eoptimestamp), drawobj->timestamp); @@ -2176,7 +2176,7 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev) adreno_dispatch_retire_drawqueue(adreno_dev, &(rb->dispatch_q)); /* Select the active dispatch_q */ - if (base == rb->buffer_desc.gpuaddr) { + if (base == rb->buffer_desc->gpuaddr) { dispatch_q = &(rb->dispatch_q); hung_rb = rb; if (adreno_dev->cur_rb != hung_rb) { @@ -2224,11 +2224,11 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev) */ if (hung_rb != NULL) { - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, MEMSTORE_RB_OFFSET(hung_rb, soptimestamp), hung_rb->timestamp); - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, MEMSTORE_RB_OFFSET(hung_rb, eoptimestamp), hung_rb->timestamp); @@ -2306,7 +2306,7 @@ static void _print_recovery(struct kgsl_device *device, static void cmdobj_profile_ticks(struct adreno_device *adreno_dev, struct kgsl_drawobj_cmd *cmdobj, uint64_t *start, uint64_t *retire) { - void *ptr = adreno_dev->profile_buffer.hostptr; + void *ptr = adreno_dev->profile_buffer->hostptr; struct adreno_drawobj_profile_entry *entry; entry = (struct adreno_drawobj_profile_entry *) diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c index 42191dfba372..8858c685dd13 100644 --- a/drivers/gpu/msm/adreno_drawctxt.c +++ b/drivers/gpu/msm/adreno_drawctxt.c @@ -268,11 +268,11 @@ void adreno_drawctxt_invalidate(struct kgsl_device *device, * set the timestamp to the last value since the context is invalidated * and we want the pending events for this context to go away */ - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(context->id, soptimestamp), drawctxt->timestamp); - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(context->id, eoptimestamp), drawctxt->timestamp); @@ -402,10 +402,10 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv, return ERR_PTR(ret); } - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp), 0); - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, eoptimestamp), 0); @@ -530,11 +530,11 @@ void adreno_drawctxt_detach(struct kgsl_context *context) return; } - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(context->id, soptimestamp), drawctxt->timestamp); - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(context->id, eoptimestamp), drawctxt->timestamp); diff --git a/drivers/gpu/msm/adreno_ioctl.c b/drivers/gpu/msm/adreno_ioctl.c index 2c684d513246..8633dde5e659 100644 --- a/drivers/gpu/msm/adreno_ioctl.c +++ b/drivers/gpu/msm/adreno_ioctl.c @@ -160,7 +160,7 @@ static long adreno_ioctl_preemption_counters_query( levels_to_copy = gpudev->num_prio_levels; if (copy_to_user(u64_to_user_ptr(read->counters), - adreno_dev->preempt.counters.hostptr, + adreno_dev->preempt.counters->hostptr, levels_to_copy * size_level)) return -EFAULT; diff --git a/drivers/gpu/msm/adreno_iommu.c b/drivers/gpu/msm/adreno_iommu.c index 32d68fc0ccae..9f5a50a16a66 100644 --- a/drivers/gpu/msm/adreno_iommu.c +++ b/drivers/gpu/msm/adreno_iommu.c @@ -216,7 +216,7 @@ static unsigned int _adreno_iommu_set_pt_v2_a5xx(struct kgsl_device *device, *cmds++ = contextidr; *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 4, 1); - cmds += cp_gpuaddr(adreno_dev, cmds, (rb->pagetable_desc.gpuaddr + + cmds += cp_gpuaddr(adreno_dev, cmds, (rb->pagetable_desc->gpuaddr + PT_INFO_OFFSET(ttbr0))); *cmds++ = lower_32_bits(ttbr0); *cmds++ = upper_32_bits(ttbr0); @@ -250,7 +250,7 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, *cmds++ = cb_num; *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 4, 1); - cmds += cp_gpuaddr(adreno_dev, cmds, (rb->pagetable_desc.gpuaddr + + cmds += cp_gpuaddr(adreno_dev, cmds, (rb->pagetable_desc->gpuaddr + PT_INFO_OFFSET(ttbr0))); *cmds++ = lower_32_bits(ttbr0); *cmds++ = upper_32_bits(ttbr0); @@ -296,7 +296,7 @@ unsigned int adreno_iommu_set_pt_generate_cmds( cmds += cp_wait_for_me(adreno_dev, cmds); *cmds++ = cp_mem_packet(adreno_dev, CP_INDIRECT_BUFFER_PFE, 2, 1); cmds += cp_gpuaddr(adreno_dev, cmds, - iommu->setstate.gpuaddr + KGSL_IOMMU_SETSTATE_NOP_OFFSET); + iommu->setstate->gpuaddr + KGSL_IOMMU_SETSTATE_NOP_OFFSET); *cmds++ = 2; cmds += cp_wait_for_idle(adreno_dev, cmds); @@ -445,7 +445,7 @@ void adreno_iommu_init(struct adreno_device *adreno_dev) * pagetables in-stream */ - kgsl_sharedmem_writel(device, &iommu->setstate, + kgsl_sharedmem_writel(device, iommu->setstate, KGSL_IOMMU_SETSTATE_NOP_OFFSET, cp_packet(adreno_dev, CP_NOP, 1)); diff --git a/drivers/gpu/msm/adreno_profile.c b/drivers/gpu/msm/adreno_profile.c index 424ce5999de2..6c52f75a1b12 100644 --- a/drivers/gpu/msm/adreno_profile.c +++ b/drivers/gpu/msm/adreno_profile.c @@ -111,11 +111,11 @@ static int _build_pre_ib_cmds(struct adreno_device *adreno_dev, struct adreno_profile_assigns_list *entry; unsigned int *start, *ibcmds; unsigned int count = profile->assignment_count; - uint64_t gpuaddr = profile->shared_buffer.gpuaddr; + uint64_t gpuaddr = profile->shared_buffer->gpuaddr; unsigned int ib_offset = head + SIZE_DATA(count); unsigned int data_offset = head * sizeof(unsigned int); - ibcmds = ib_offset + ((unsigned int *) profile->shared_buffer.hostptr); + ibcmds = ib_offset + ((unsigned int *) profile->shared_buffer->hostptr); start = ibcmds; ibcmds += cp_identifier(adreno_dev, ibcmds, START_PROFILE_IDENTIFIER); @@ -156,7 +156,7 @@ static int _build_pre_ib_cmds(struct adreno_device *adreno_dev, ibcmds += cp_identifier(adreno_dev, ibcmds, END_PROFILE_IDENTIFIER); - return _create_ib_ref(adreno_dev, &profile->shared_buffer, rbcmds, + return _create_ib_ref(adreno_dev, profile->shared_buffer, rbcmds, ibcmds - start, ib_offset * sizeof(unsigned int)); } @@ -167,11 +167,11 @@ static int _build_post_ib_cmds(struct adreno_device *adreno_dev, struct adreno_profile_assigns_list *entry; unsigned int *start, *ibcmds; unsigned int count = profile->assignment_count; - uint64_t gpuaddr = profile->shared_buffer.gpuaddr; + uint64_t gpuaddr = profile->shared_buffer->gpuaddr; unsigned int ib_offset = head + SIZE_DATA(count) + SIZE_PREIB(count); unsigned int data_offset = head * sizeof(unsigned int); - ibcmds = ib_offset + ((unsigned int *) profile->shared_buffer.hostptr); + ibcmds = ib_offset + ((unsigned int *) profile->shared_buffer->hostptr); start = ibcmds; /* start of profile identifier */ @@ -195,14 +195,14 @@ static int _build_post_ib_cmds(struct adreno_device *adreno_dev, /* end of profile identifier */ ibcmds += cp_identifier(adreno_dev, ibcmds, END_PROFILE_IDENTIFIER); - return _create_ib_ref(adreno_dev, &profile->shared_buffer, rbcmds, + return _create_ib_ref(adreno_dev, profile->shared_buffer, rbcmds, ibcmds - start, ib_offset * sizeof(unsigned int)); } static bool shared_buf_empty(struct adreno_profile *profile) { - if (profile->shared_buffer.hostptr == NULL || - profile->shared_buffer.size == 0) + if (profile->shared_buffer->hostptr == NULL || + profile->shared_buffer->size == 0) return true; if (profile->shared_head == profile->shared_tail) @@ -319,7 +319,7 @@ static bool results_available(struct adreno_device *adreno_dev, unsigned int global_eop; unsigned int off = profile->shared_tail; unsigned int *shared_ptr = (unsigned int *) - profile->shared_buffer.hostptr; + profile->shared_buffer->hostptr; unsigned int ts, cnt; int ts_cmp; @@ -362,7 +362,7 @@ static void transfer_results(struct adreno_profile *profile, { unsigned int buf_off; unsigned int ts, cnt, ctxt_id, pid, tid, client_type; - unsigned int *ptr = (unsigned int *) profile->shared_buffer.hostptr; + unsigned int *ptr = (unsigned int *) profile->shared_buffer->hostptr; unsigned int *log_ptr, *log_base; struct adreno_profile_assigns_list *assigns_list; int i, tmp_tail; @@ -1017,17 +1017,15 @@ void adreno_profile_init(struct adreno_device *adreno_dev) struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_profile *profile = &adreno_dev->profile; struct dentry *profile_dir; - int ret; profile->enabled = false; /* allocate shared_buffer, which includes pre_ib and post_ib */ profile->shared_size = ADRENO_PROFILE_SHARED_BUF_SIZE_DWORDS; - ret = kgsl_allocate_global(device, &profile->shared_buffer, + profile->shared_buffer = kgsl_allocate_global(device, profile->shared_size * sizeof(unsigned int), 0, 0, "profile"); - - if (ret) { + if (IS_ERR(profile->shared_buffer)) { profile->shared_size = 0; return; } @@ -1061,7 +1059,6 @@ void adreno_profile_close(struct adreno_device *adreno_dev) profile->log_tail = NULL; profile->shared_head = 0; profile->shared_tail = 0; - kgsl_free_global(KGSL_DEVICE(adreno_dev), &profile->shared_buffer); profile->shared_size = 0; profile->assignment_count = 0; @@ -1128,7 +1125,7 @@ void adreno_profile_preib_processing(struct adreno_device *adreno_dev, /* zero out the counter area of shared_buffer entry_head */ shared_ptr = entry_head + ((unsigned int *) - profile->shared_buffer.hostptr); + profile->shared_buffer->hostptr); memset(shared_ptr, 0, SIZE_SHARED_ENTRY(count) * sizeof(unsigned int)); /* reserve space for the pre ib shared buffer */ diff --git a/drivers/gpu/msm/adreno_profile.h b/drivers/gpu/msm/adreno_profile.h index 8994a4344c70..4fc26a9e3675 100644 --- a/drivers/gpu/msm/adreno_profile.h +++ b/drivers/gpu/msm/adreno_profile.h @@ -39,7 +39,7 @@ struct adreno_profile { * pre_ib entry N * post_ib entry N */ - struct kgsl_memdesc shared_buffer; + struct kgsl_memdesc *shared_buffer; unsigned int shared_head; unsigned int shared_tail; unsigned int shared_size; diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index 31d251831b56..0fd11395c50b 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -17,11 +17,11 @@ #define RB_HOSTPTR(_rb, _pos) \ - ((unsigned int *) ((_rb)->buffer_desc.hostptr + \ + ((unsigned int *) ((_rb)->buffer_desc->hostptr + \ ((_pos) * sizeof(unsigned int)))) #define RB_GPUADDR(_rb, _pos) \ - ((_rb)->buffer_desc.gpuaddr + ((_pos) * sizeof(unsigned int))) + ((_rb)->buffer_desc->gpuaddr + ((_pos) * sizeof(unsigned int))) static inline bool is_internal_cmds(unsigned int flags) { @@ -224,10 +224,10 @@ int adreno_ringbuffer_start(struct adreno_device *adreno_dev) /* Setup the ringbuffers state before we start */ FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { - kgsl_sharedmem_set(device, &(rb->buffer_desc), + kgsl_sharedmem_set(device, rb->buffer_desc, 0, 0xAA, KGSL_RB_SIZE); if (!adreno_is_a3xx(adreno_dev)) - kgsl_sharedmem_writel(device, &device->scratch, + kgsl_sharedmem_writel(device, device->scratch, SCRATCH_RPTR_OFFSET(rb->id), 0); rb->wptr = 0; rb->_wptr = 0; @@ -258,8 +258,8 @@ static int _rb_readtimestamp(struct kgsl_device *device, static int _adreno_ringbuffer_probe(struct adreno_device *adreno_dev, int id) { + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_ringbuffer *rb = &adreno_dev->ringbuffers[id]; - int ret; unsigned int priv = 0; rb->id = id; @@ -275,21 +275,22 @@ static int _adreno_ringbuffer_probe(struct adreno_device *adreno_dev, * Allocate mem for storing RB pagetables and commands to * switch pagetable */ - ret = kgsl_allocate_global(KGSL_DEVICE(adreno_dev), &rb->pagetable_desc, - PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED, "pagetable_desc"); - if (ret) - return ret; + rb->pagetable_desc = kgsl_allocate_global(device, PAGE_SIZE, + 0, KGSL_MEMDESC_PRIVILEGED, "pagetable_desc"); + if (IS_ERR(rb->pagetable_desc)) + return PTR_ERR(rb->pagetable_desc); /* allocate a chunk of memory to create user profiling IB1s */ - kgsl_allocate_global(KGSL_DEVICE(adreno_dev), &rb->profile_desc, - PAGE_SIZE, KGSL_MEMFLAGS_GPUREADONLY, 0, "profile_desc"); + rb->profile_desc = kgsl_allocate_global(device, PAGE_SIZE, + KGSL_MEMFLAGS_GPUREADONLY, 0, "profile_desc"); - /* For targets that support it, make the ringbuffer privileged */ if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV)) priv |= KGSL_MEMDESC_PRIVILEGED; - return kgsl_allocate_global(KGSL_DEVICE(adreno_dev), &rb->buffer_desc, - KGSL_RB_SIZE, KGSL_MEMFLAGS_GPUREADONLY, priv, "ringbuffer"); + rb->buffer_desc = kgsl_allocate_global(device, KGSL_RB_SIZE, + KGSL_MEMFLAGS_GPUREADONLY, priv, "ringbuffer"); + + return PTR_ERR_OR_ZERO(rb->buffer_desc); } int adreno_ringbuffer_probe(struct adreno_device *adreno_dev) @@ -306,10 +307,11 @@ int adreno_ringbuffer_probe(struct adreno_device *adreno_dev) if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV)) priv |= KGSL_MEMDESC_PRIVILEGED; - status = kgsl_allocate_global(device, &device->scratch, - PAGE_SIZE, 0, priv, "scratch"); - if (status != 0) - return status; + device->scratch = kgsl_allocate_global(device, + PAGE_SIZE, 0, KGSL_MEMDESC_RANDOM, "scratch"); + + if (IS_ERR(device->scratch)) + return PTR_ERR(device->scratch); } if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) @@ -341,30 +343,16 @@ int adreno_ringbuffer_probe(struct adreno_device *adreno_dev) return status; } -static void _adreno_ringbuffer_close(struct adreno_device *adreno_dev, - struct adreno_ringbuffer *rb) -{ - struct kgsl_device *device = KGSL_DEVICE(adreno_dev); - - kgsl_free_global(device, &rb->pagetable_desc); - kgsl_free_global(device, &rb->profile_desc); - kgsl_free_global(device, &rb->buffer_desc); - kgsl_del_event_group(&rb->events); - memset(rb, 0, sizeof(struct adreno_ringbuffer)); -} - void adreno_ringbuffer_close(struct adreno_device *adreno_dev) { - struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); struct adreno_ringbuffer *rb; int i; - if (!adreno_is_a3xx(adreno_dev)) - kgsl_free_global(device, &device->scratch); - - FOR_EACH_RINGBUFFER(adreno_dev, rb, i) - _adreno_ringbuffer_close(adreno_dev, rb); + FOR_EACH_RINGBUFFER(adreno_dev, rb, i) { + kgsl_del_event_group(&rb->events); + memset(rb, 0, sizeof(*rb)); + } if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) if (gpudev->preemption_close) @@ -577,7 +565,7 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, *ringcmds++ = cp_mem_packet(adreno_dev, CP_INDIRECT_BUFFER_PFE, 2, 1); ringcmds += cp_gpuaddr(adreno_dev, ringcmds, - adreno_dev->pwron_fixup.gpuaddr); + adreno_dev->pwron_fixup->gpuaddr); *ringcmds++ = adreno_dev->pwron_fixup_dwords; /* Re-enable protected mode */ @@ -842,12 +830,12 @@ static int set_user_profiling(struct adreno_device *adreno_dev, u64 ib_gpuaddr; u32 *ib; - if (!rb->profile_desc.hostptr) + if (!rb->profile_desc->hostptr) return 0; - ib = ((u32 *) rb->profile_desc.hostptr) + + ib = ((u32 *) rb->profile_desc->hostptr) + (rb->profile_index * PROFILE_IB_DWORDS); - ib_gpuaddr = rb->profile_desc.gpuaddr + + ib_gpuaddr = rb->profile_desc->gpuaddr + (rb->profile_index * (PROFILE_IB_DWORDS << 2)); dwords = _get_alwayson_counter(adreno_dev, ib, gpuaddr); @@ -1012,7 +1000,7 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, if (kernel_profiling) { cmds += _get_alwayson_counter(adreno_dev, cmds, - adreno_dev->profile_buffer.gpuaddr + + adreno_dev->profile_buffer->gpuaddr + ADRENO_DRAWOBJ_PROFILE_OFFSET(cmdobj->profile_index, started)); } @@ -1068,7 +1056,7 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, if (kernel_profiling) { cmds += _get_alwayson_counter(adreno_dev, cmds, - adreno_dev->profile_buffer.gpuaddr + + adreno_dev->profile_buffer->gpuaddr + ADRENO_DRAWOBJ_PROFILE_OFFSET(cmdobj->profile_index, retired)); } diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h index 5c68d4d7781c..ff9b818d5e2d 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.h +++ b/drivers/gpu/msm/adreno_ringbuffer.h @@ -101,7 +101,7 @@ struct adreno_ringbuffer_pagetable_info { */ struct adreno_ringbuffer { uint32_t flags; - struct kgsl_memdesc buffer_desc; + struct kgsl_memdesc *buffer_desc; unsigned int _wptr; unsigned int wptr; unsigned int last_wptr; @@ -110,10 +110,10 @@ struct adreno_ringbuffer { unsigned int timestamp; struct kgsl_event_group events; struct adreno_context *drawctxt_active; - struct kgsl_memdesc preemption_desc; + struct kgsl_memdesc *preemption_desc; struct kgsl_memdesc secure_preemption_desc; - struct kgsl_memdesc perfcounter_save_restore_desc; - struct kgsl_memdesc pagetable_desc; + struct kgsl_memdesc *perfcounter_save_restore_desc; + struct kgsl_memdesc *pagetable_desc; struct adreno_dispatcher_drawqueue dispatch_q; wait_queue_head_t ts_expire_waitq; unsigned int wptr_preempt_end; @@ -125,7 +125,7 @@ struct adreno_ringbuffer { * @profile_desc: global memory to construct IB1s to do user side * profiling */ - struct kgsl_memdesc profile_desc; + struct kgsl_memdesc *profile_desc; /** * @profile_index: Pointer to the next "slot" in profile_desc for a user * profiling IB1. This allows for PAGE_SIZE / 16 = 256 simultaneous diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index 73703f3c62d1..d0f1c06bbd67 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -216,7 +216,7 @@ static inline bool iommu_is_setstate_addr(struct kgsl_device *device, if (kgsl_mmu_get_mmutype(device) != KGSL_MMU_TYPE_IOMMU) return false; - return kgsl_gpuaddr_in_memdesc(&iommu->setstate, gpuaddr, + return kgsl_gpuaddr_in_memdesc(iommu->setstate, gpuaddr, size); } @@ -228,7 +228,7 @@ static void dump_all_ibs(struct kgsl_device *device, unsigned int *rbptr; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); - rbptr = rb->buffer_desc.hostptr; + rbptr = rb->buffer_desc->hostptr; for (index = 0; index < KGSL_RB_DWORDS;) { @@ -251,7 +251,7 @@ static void dump_all_ibs(struct kgsl_device *device, if (iommu_is_setstate_addr(device, ibaddr, ibsize)) continue; - if (kgsl_gpuaddr_in_memdesc(&adreno_dev->pwron_fixup, + if (kgsl_gpuaddr_in_memdesc(adreno_dev->pwron_fixup, ibaddr, ibsize)) continue; @@ -284,7 +284,7 @@ static void snapshot_rb_ibs(struct kgsl_device *device, * from the rptr */ index = rptr; - rbptr = rb->buffer_desc.hostptr; + rbptr = rb->buffer_desc->hostptr; do { index--; @@ -402,7 +402,7 @@ static void snapshot_rb_ibs(struct kgsl_device *device, if (iommu_is_setstate_addr(device, ibaddr, ibsize)) continue; - if (kgsl_gpuaddr_in_memdesc(&adreno_dev->pwron_fixup, + if (kgsl_gpuaddr_in_memdesc(adreno_dev->pwron_fixup, ibaddr, ibsize)) continue; @@ -447,14 +447,14 @@ static size_t snapshot_rb(struct kgsl_device *device, u8 *buf, &header->timestamp_queued); adreno_rb_readtimestamp(adreno_dev, rb, KGSL_TIMESTAMP_RETIRED, &header->timestamp_retired); - header->gpuaddr = rb->buffer_desc.gpuaddr; + header->gpuaddr = rb->buffer_desc->gpuaddr; header->id = rb->id; if (rb == adreno_dev->cur_rb) snapshot_rb_ibs(device, rb, snapshot); /* Just copy the ringbuffer, there are no active IBs */ - memcpy(data, rb->buffer_desc.hostptr, KGSL_RB_SIZE); + memcpy(data, rb->buffer_desc->hostptr, KGSL_RB_SIZE); /* Return the size of the section */ return KGSL_RB_SIZE + sizeof(*header); @@ -760,7 +760,7 @@ static size_t snapshot_global(struct kgsl_device *device, u8 *buf, u8 *ptr = buf + sizeof(*header); - if (memdesc->size == 0) + if (!memdesc || memdesc->size == 0) return 0; if (remain < (memdesc->size + sizeof(*header))) { @@ -794,12 +794,12 @@ static void adreno_snapshot_iommu(struct kgsl_device *device, struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2, - snapshot, snapshot_global, &iommu->setstate); + snapshot, snapshot_global, iommu->setstate); if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2, - snapshot, snapshot_global, &iommu->smmu_info); + snapshot, snapshot_global, iommu->smmu_info); } static void adreno_snapshot_ringbuffer(struct kgsl_device *device, @@ -873,11 +873,11 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot, /* Dump selected global buffers */ kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2, - snapshot, snapshot_global, &device->memstore); + snapshot, snapshot_global, device->memstore); kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2, snapshot, snapshot_global, - &adreno_dev->pwron_fixup); + adreno_dev->pwron_fixup); if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_IOMMU) adreno_snapshot_iommu(device, snapshot); diff --git a/drivers/gpu/msm/adreno_trace.h b/drivers/gpu/msm/adreno_trace.h index 0da2aa1e5f67..5af5f397af60 100644 --- a/drivers/gpu/msm/adreno_trace.h +++ b/drivers/gpu/msm/adreno_trace.h @@ -518,8 +518,8 @@ DECLARE_EVENT_CLASS(adreno_hw_preempt_template, __entry->new_rptr = new_rptr; __entry->cur_wptr = cur_rb->wptr; __entry->new_wptr = new_rb->wptr; - __entry->cur_rbbase = cur_rb->buffer_desc.gpuaddr; - __entry->new_rbbase = new_rb->buffer_desc.gpuaddr; + __entry->cur_rbbase = cur_rb->buffer_desc->gpuaddr; + __entry->new_rbbase = new_rb->buffer_desc->gpuaddr; ), TP_printk( "cur_rb_lvl=%d rptr=%x wptr=%x rbbase=%x new_rb_lvl=%d rptr=%x wptr=%x rbbase=%x", @@ -573,8 +573,8 @@ TRACE_EVENT(adreno_hw_preempt_comp_to_clear, __entry->cur_wptr = cur_rb->wptr; __entry->new_wptr_end = new_rb->wptr_preempt_end; __entry->new_wptr = new_rb->wptr; - __entry->cur_rbbase = cur_rb->buffer_desc.gpuaddr; - __entry->new_rbbase = new_rb->buffer_desc.gpuaddr; + __entry->cur_rbbase = cur_rb->buffer_desc->gpuaddr; + __entry->new_rbbase = new_rb->buffer_desc->gpuaddr; ), TP_printk( "cur_rb_lvl=%d rptr=%x wptr=%x rbbase=%x prev_rb_lvl=%d rptr=%x wptr_preempt_end=%x wptr=%x rbbase=%x", @@ -607,8 +607,8 @@ TRACE_EVENT(adreno_hw_preempt_token_submit, __entry->cur_wptr = cur_rb->wptr; __entry->cur_wptr_end = cur_rb->wptr_preempt_end; __entry->new_wptr = new_rb->wptr; - __entry->cur_rbbase = cur_rb->buffer_desc.gpuaddr; - __entry->new_rbbase = new_rb->buffer_desc.gpuaddr; + __entry->cur_rbbase = cur_rb->buffer_desc->gpuaddr; + __entry->new_rbbase = new_rb->buffer_desc->gpuaddr; ), TP_printk( "cur_rb_lvl=%d rptr=%x wptr_preempt_end=%x wptr=%x rbbase=%x new_rb_lvl=%d rptr=%x wptr=%x rbbase=%x", diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 27f5e224eed0..c0d30706053a 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -716,9 +716,9 @@ kgsl_context_destroy(struct kref *kref) if (context->id != KGSL_CONTEXT_INVALID) { /* Clear the timestamps in the memstore during destroy */ - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(context->id, soptimestamp), 0); - kgsl_sharedmem_writel(device, &device->memstore, + kgsl_sharedmem_writel(device, device->memstore, KGSL_MEMSTORE_OFFSET(context->id, eoptimestamp), 0); /* clear device power constraint */ @@ -1181,8 +1181,8 @@ static int kgsl_open_device(struct kgsl_device *device) * which will be called by kgsl_active_count_get(). */ atomic_inc(&device->active_cnt); - kgsl_sharedmem_set(device, &device->memstore, 0, 0, - device->memstore.size); + kgsl_sharedmem_set(device, device->memstore, 0, 0, + device->memstore->size); result = device->ftbl->init(device); if (result) @@ -4397,7 +4397,7 @@ static int kgsl_mmap_memstore(struct file *file, struct kgsl_device *device, struct vm_area_struct *vma) { - struct kgsl_memdesc *memdesc = &device->memstore; + struct kgsl_memdesc *memdesc = device->memstore; unsigned int vma_size = vma->vm_end - vma->vm_start; /* The memstore can only be mapped as read only */ @@ -4728,7 +4728,7 @@ kgsl_get_unmapped_area(struct file *file, unsigned long addr, struct kgsl_device *device = dev_priv->device; struct kgsl_mem_entry *entry = NULL; - if (vma_offset == (unsigned long) device->memstore.gpuaddr) + if (vma_offset == (unsigned long) device->memstore->gpuaddr) return get_unmapped_area(NULL, addr, len, pgoff, flags); val = get_mmap_entry(private, &entry, pgoff, len); @@ -4774,7 +4774,7 @@ static int kgsl_mmap(struct file *file, struct vm_area_struct *vma) /* Handle leagacy behavior for memstore */ - if (vma_offset == (unsigned long) device->memstore.gpuaddr) + if (vma_offset == (unsigned long) device->memstore->gpuaddr) return kgsl_mmap_memstore(file, device, vma); /* @@ -5061,6 +5061,7 @@ int kgsl_device_platform_probe(struct kgsl_device *device) error_close_mmu: kgsl_mmu_close(device); + kgsl_free_globals(device); error_pwrctrl_close: kgsl_pwrctrl_close(device); error: @@ -5083,6 +5084,12 @@ void kgsl_device_platform_remove(struct kgsl_device *device) kgsl_mmu_close(device); + /* + * This needs to come after the MMU close so we can be sure all the + * pagetables have been freed + */ + kgsl_free_globals(device); + kgsl_pwrctrl_close(device); kgsl_device_debugfs_close(device); diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index 49ef509423da..7b9874a2c3ac 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -50,10 +50,10 @@ KGSL_MEMSTORE_OFFSET(((rb)->id + KGSL_MEMSTORE_MAX), field) #define MEMSTORE_ID_GPU_ADDR(dev, iter, field) \ - ((dev)->memstore.gpuaddr + KGSL_MEMSTORE_OFFSET(iter, field)) + ((dev)->memstore->gpuaddr + KGSL_MEMSTORE_OFFSET(iter, field)) #define MEMSTORE_RB_GPU_ADDR(dev, rb, field) \ - ((dev)->memstore.gpuaddr + \ + ((dev)->memstore->gpuaddr + \ KGSL_MEMSTORE_OFFSET(((rb)->id + KGSL_MEMSTORE_MAX), field)) /* @@ -71,13 +71,13 @@ /* Shadow global helpers */ #define SCRATCH_RPTR_OFFSET(id) ((id) * sizeof(unsigned int)) #define SCRATCH_RPTR_GPU_ADDR(dev, id) \ - ((dev)->scratch.gpuaddr + SCRATCH_RPTR_OFFSET(id)) + ((dev)->scratch->gpuaddr + SCRATCH_RPTR_OFFSET(id)) #define SCRATCH_PREEMPTION_CTXT_RESTORE_ADDR_OFFSET(id) \ (SCRATCH_RPTR_OFFSET(KGSL_PRIORITY_MAX_RB_LEVELS) + \ ((id) * sizeof(uint64_t))) #define SCRATCH_PREEMPTION_CTXT_RESTORE_GPU_ADDR(dev, id) \ - ((dev)->scratch.gpuaddr + \ + ((dev)->scratch->gpuaddr + \ SCRATCH_PREEMPTION_CTXT_RESTORE_ADDR_OFFSET(id)) /* Timestamp window used to detect rollovers (half of integer range) */ @@ -227,6 +227,18 @@ struct kgsl_memdesc { unsigned int cur_bindings; }; +/** + * struct kgsl_global_memdesc - wrapper for global memory objects + */ +struct kgsl_global_memdesc { + /** @memdesc: Container for the GPU memory descriptor for the object */ + struct kgsl_memdesc memdesc; + /** @name: Name of the object for the debugfs list */ + const char *name; + /** @node: List node for the list of global objects */ + struct list_head node; +}; + /* * List of different memory entry types. The usermem enum * starts at 0, which we use for allocated memory, so 1 is @@ -449,22 +461,22 @@ int kgsl_request_irq(struct platform_device *pdev, const char *name, int __init kgsl_core_init(void); void kgsl_core_exit(void); -static inline int kgsl_gpuaddr_in_memdesc(const struct kgsl_memdesc *memdesc, +static inline bool kgsl_gpuaddr_in_memdesc(const struct kgsl_memdesc *memdesc, uint64_t gpuaddr, uint64_t size) { + if (!memdesc) + return false; + /* set a minimum size to search for */ if (!size) size = 1; /* don't overflow */ if (size > U64_MAX - gpuaddr) - return 0; + return false; - if (gpuaddr >= memdesc->gpuaddr && - ((gpuaddr + size) <= (memdesc->gpuaddr + memdesc->size))) { - return 1; - } - return 0; + return (gpuaddr >= memdesc->gpuaddr && + ((gpuaddr + size) <= (memdesc->gpuaddr + memdesc->size))); } static inline void *kgsl_memdesc_map(struct kgsl_memdesc *memdesc) diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c index f5f0fd0507e3..5803bfdaaf34 100644 --- a/drivers/gpu/msm/kgsl_debugfs.c +++ b/drivers/gpu/msm/kgsl_debugfs.c @@ -67,13 +67,25 @@ DEFINE_DEBUGFS_ATTRIBUTE(_isdb_fops, _isdb_get, _isdb_set, "%llu\n"); static int globals_print(struct seq_file *s, void *unused) { - kgsl_print_global_pt_entries(s); + struct kgsl_device *device = s->private; + struct kgsl_global_memdesc *md; + + list_for_each_entry(md, &device->globals, node) { + struct kgsl_memdesc *memdesc = &md->memdesc; + + seq_printf(s, "0x%pK-0x%pK %16llu %s\n", + (u64 *)(uintptr_t) memdesc->gpuaddr, + (u64 *)(uintptr_t) (memdesc->gpuaddr + + memdesc->size - 1), memdesc->size, + md->name); + } + return 0; } static int globals_open(struct inode *inode, struct file *file) { - return single_open(file, globals_print, NULL); + return single_open(file, globals_print, inode->i_private); } static int globals_release(struct inode *inode, struct file *file) diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 48a7c0047dab..9d14751fb74f 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -238,8 +238,8 @@ struct kgsl_device { /* Starting kernel virtual address for QDSS GFX DBG register block */ void __iomem *qdss_gfx_virt; - struct kgsl_memdesc memstore; - struct kgsl_memdesc scratch; + struct kgsl_memdesc *memstore; + struct kgsl_memdesc *scratch; const char *iomemname; struct kgsl_mmu mmu; @@ -307,6 +307,16 @@ struct kgsl_device { unsigned int num_l3_pwrlevels; /* store current L3 vote to determine if we should change our vote */ unsigned int cur_l3_pwrlevel; + /** @globals: List of global memory objects */ + struct list_head globals; + /** @globlal_map: bitmap for global memory allocations */ + unsigned long *global_map; + /** @global_pages: Number of pages available in the global_map */ + unsigned int global_pages; + /* @qdss_desc: Memory descriptor for the QDSS region if applicable */ + struct kgsl_memdesc *qdss_desc; + /* @qtimer_desc: Memory descriptor for the QDSS region if applicable */ + struct kgsl_memdesc *qtimer_desc; }; #define KGSL_MMU_DEVICE(_mmu) \ @@ -321,7 +331,8 @@ struct kgsl_device { .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\ .active_cnt_wq = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).active_cnt_wq),\ .mutex = __MUTEX_INITIALIZER((_dev).mutex),\ - .state = KGSL_STATE_NONE + .state = KGSL_STATE_NONE, \ + .globals = LIST_HEAD_INIT((_dev).globals) /** diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 815a88e77a99..a302f3e0ec97 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -66,80 +66,31 @@ struct kgsl_iommu_addr_entry { static struct kmem_cache *addr_entry_cache; -/* - * There are certain memory allocations (ringbuffer, memstore, etc) that need to - * be present at the same address in every pagetable. We call these "global" - * pagetable entries. There are relatively few of these and they are mostly - * stable (defined at init time) but the actual number of globals can differ - * slight depending on the target and implementation. - * - * Here we define an array and a simple allocator to keep track of the currently - * active global entries. Each entry is assigned a unique address inside of a - * MMU implementation specific "global" region. We use a simple bitmap based - * allocator for the region to allow for both fixed and dynamic addressing. - */ - -#define GLOBAL_PT_ENTRIES 32 - -struct global_pt_entry { - struct kgsl_memdesc *memdesc; - char name[32]; -}; - -#define GLOBAL_MAP_PAGES (KGSL_IOMMU_GLOBAL_MEM_SIZE >> PAGE_SHIFT) - -static struct global_pt_entry global_pt_entries[GLOBAL_PT_ENTRIES]; -static DECLARE_BITMAP(global_map, GLOBAL_MAP_PAGES); - static int secure_global_size; -static int global_pt_count; -static struct kgsl_memdesc gpu_qdss_desc; -static struct kgsl_memdesc gpu_qtimer_desc; -void kgsl_print_global_pt_entries(struct seq_file *s) +static void kgsl_iommu_unmap_globals(struct kgsl_mmu *mmu, + struct kgsl_pagetable *pagetable) { - int i; + struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); + struct kgsl_global_memdesc *md; - for (i = 0; i < global_pt_count; i++) { - struct kgsl_memdesc *memdesc = global_pt_entries[i].memdesc; - - if (memdesc == NULL) - continue; - - seq_printf(s, "0x%pK-0x%pK %16llu %s\n", - (uint64_t *)(uintptr_t) memdesc->gpuaddr, - (uint64_t *)(uintptr_t) (memdesc->gpuaddr + - memdesc->size - 1), memdesc->size, - global_pt_entries[i].name); - } + list_for_each_entry(md, &device->globals, node) + kgsl_mmu_unmap(pagetable, &md->memdesc); } -static void kgsl_iommu_unmap_globals(struct kgsl_pagetable *pagetable) +static void kgsl_iommu_map_globals(struct kgsl_mmu *mmu, + struct kgsl_pagetable *pagetable) { - unsigned int i; + struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); + struct kgsl_global_memdesc *md; - for (i = 0; i < global_pt_count; i++) { - if (global_pt_entries[i].memdesc != NULL) - kgsl_mmu_unmap(pagetable, - global_pt_entries[i].memdesc); - } + list_for_each_entry(md, &device->globals, node) + kgsl_mmu_map(pagetable, &md->memdesc); } -static int kgsl_iommu_map_globals(struct kgsl_pagetable *pagetable) +static u64 kgsl_iommu_get_global_base(struct kgsl_mmu *mmu) { - unsigned int i; - - for (i = 0; i < global_pt_count; i++) { - if (global_pt_entries[i].memdesc != NULL) { - int ret = kgsl_mmu_map(pagetable, - global_pt_entries[i].memdesc); - - if (ret) - return ret; - } - } - - return 0; + return KGSL_IOMMU_GLOBAL_MEM_BASE(mmu); } void kgsl_iommu_unmap_global_secure_pt_entry(struct kgsl_device *device, @@ -180,165 +131,6 @@ int kgsl_iommu_map_global_secure_pt_entry(struct kgsl_device *device, return ret; } -static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu, - struct kgsl_memdesc *memdesc) -{ - int i; - - if (memdesc->gpuaddr == 0 || !(memdesc->priv & KGSL_MEMDESC_GLOBAL)) - return; - - for (i = 0; i < global_pt_count; i++) { - if (global_pt_entries[i].memdesc == memdesc) { - u64 offset = memdesc->gpuaddr - - KGSL_IOMMU_GLOBAL_MEM_BASE(mmu); - - bitmap_clear(global_map, offset >> PAGE_SHIFT, - kgsl_memdesc_footprint(memdesc) >> PAGE_SHIFT); - - memdesc->gpuaddr = 0; - memdesc->priv &= ~KGSL_MEMDESC_GLOBAL; - global_pt_entries[i].memdesc = NULL; - return; - } - } -} - -static void kgsl_iommu_add_global(struct kgsl_mmu *mmu, - struct kgsl_memdesc *memdesc, const char *name) -{ - u32 bit, start = 0; - u64 size = kgsl_memdesc_footprint(memdesc); - - if (memdesc->gpuaddr != 0) - return; - - if (WARN_ON(global_pt_count >= GLOBAL_PT_ENTRIES)) - return; - - if (WARN_ON(size > KGSL_IOMMU_GLOBAL_MEM_SIZE)) - return; - - if (memdesc->priv & KGSL_MEMDESC_RANDOM) { - u32 range = GLOBAL_MAP_PAGES - (size >> PAGE_SHIFT); - - start = get_random_int() % range; - } - - for (;;) { - bit = bitmap_find_next_zero_area(global_map, GLOBAL_MAP_PAGES, - start, size >> PAGE_SHIFT, 0); - - if (bit < GLOBAL_MAP_PAGES) - break; - - if (WARN_ON(start == 0)) - return; - - start--; - } - - memdesc->gpuaddr = - KGSL_IOMMU_GLOBAL_MEM_BASE(mmu) + (bit << PAGE_SHIFT); - - bitmap_set(global_map, bit, size >> PAGE_SHIFT); - - memdesc->priv |= KGSL_MEMDESC_GLOBAL; - - global_pt_entries[global_pt_count].memdesc = memdesc; - strlcpy(global_pt_entries[global_pt_count].name, name, - sizeof(global_pt_entries[global_pt_count].name)); - global_pt_count++; -} - -struct kgsl_memdesc *kgsl_iommu_get_qdss_global_entry(void) -{ - return &gpu_qdss_desc; -} - -static void kgsl_setup_qdss_desc(struct kgsl_device *device) -{ - int result = 0; - uint32_t gpu_qdss_entry[2]; - - if (!of_find_property(device->pdev->dev.of_node, - "qcom,gpu-qdss-stm", NULL)) - return; - - if (of_property_read_u32_array(device->pdev->dev.of_node, - "qcom,gpu-qdss-stm", gpu_qdss_entry, 2)) { - dev_err(device->dev, "Failed to read gpu qdss dts entry\n"); - return; - } - - kgsl_memdesc_init(device, &gpu_qdss_desc, 0); - gpu_qdss_desc.priv = 0; - gpu_qdss_desc.physaddr = gpu_qdss_entry[0]; - gpu_qdss_desc.size = gpu_qdss_entry[1]; - gpu_qdss_desc.pagetable = NULL; - gpu_qdss_desc.ops = NULL; - gpu_qdss_desc.hostptr = NULL; - - result = kgsl_memdesc_sg_dma(&gpu_qdss_desc, gpu_qdss_desc.physaddr, - gpu_qdss_desc.size); - if (result) { - dev_err(device->dev, "memdesc_sg_dma failed: %d\n", result); - return; - } - - kgsl_mmu_add_global(device, &gpu_qdss_desc, "gpu-qdss"); -} - -static inline void kgsl_cleanup_qdss_desc(struct kgsl_mmu *mmu) -{ - kgsl_iommu_remove_global(mmu, &gpu_qdss_desc); - kgsl_sharedmem_free(&gpu_qdss_desc); -} - -struct kgsl_memdesc *kgsl_iommu_get_qtimer_global_entry(void) -{ - return &gpu_qtimer_desc; -} - -static void kgsl_setup_qtimer_desc(struct kgsl_device *device) -{ - int result = 0; - uint32_t gpu_qtimer_entry[2]; - - if (!of_find_property(device->pdev->dev.of_node, - "qcom,gpu-qtimer", NULL)) - return; - - if (of_property_read_u32_array(device->pdev->dev.of_node, - "qcom,gpu-qtimer", gpu_qtimer_entry, 2)) { - dev_err(device->dev, "Failed to read gpu qtimer dts entry\n"); - return; - } - - kgsl_memdesc_init(device, &gpu_qtimer_desc, 0); - gpu_qtimer_desc.priv = 0; - gpu_qtimer_desc.physaddr = gpu_qtimer_entry[0]; - gpu_qtimer_desc.size = gpu_qtimer_entry[1]; - gpu_qtimer_desc.pagetable = NULL; - gpu_qtimer_desc.ops = NULL; - gpu_qtimer_desc.hostptr = NULL; - - result = kgsl_memdesc_sg_dma(&gpu_qtimer_desc, gpu_qtimer_desc.physaddr, - gpu_qtimer_desc.size); - if (result) { - dev_err(device->dev, "memdesc_sg_dma failed: %d\n", result); - return; - } - - kgsl_mmu_add_global(device, &gpu_qtimer_desc, "gpu-qtimer"); -} - -static inline void kgsl_cleanup_qtimer_desc(struct kgsl_mmu *mmu) -{ - kgsl_iommu_remove_global(mmu, &gpu_qtimer_desc); - kgsl_sharedmem_free(&gpu_qtimer_desc); -} - static void _detach_pt(struct kgsl_iommu_pt *iommu_pt, struct kgsl_iommu_context *ctx) { @@ -528,49 +320,45 @@ struct _mem_entry { char name[32]; }; -static void _get_global_entries(uint64_t faultaddr, +static void _get_global_entries(struct kgsl_mmu *mmu, uint64_t faultaddr, struct _mem_entry *prev, struct _mem_entry *next) { - int i; + struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); + struct kgsl_global_memdesc *p = NULL, *n = NULL, *md; uint64_t prevaddr = 0; - struct global_pt_entry *p = NULL; - uint64_t nextaddr = (uint64_t) -1; - struct global_pt_entry *n = NULL; - for (i = 0; i < global_pt_count; i++) { - uint64_t addr; + list_for_each_entry(md, &device->globals, node) { + struct kgsl_memdesc *memdesc = &md->memdesc; + u64 addr; - if (global_pt_entries[i].memdesc == NULL) - continue; - - addr = global_pt_entries[i].memdesc->gpuaddr; + addr = memdesc->gpuaddr; if ((addr < faultaddr) && (addr > prevaddr)) { prevaddr = addr; - p = &global_pt_entries[i]; + p = md; } if ((addr > faultaddr) && (addr < nextaddr)) { nextaddr = addr; - n = &global_pt_entries[i]; + n = md; } } if (p != NULL) { - prev->gpuaddr = p->memdesc->gpuaddr; - prev->size = p->memdesc->size; - prev->flags = p->memdesc->flags; - prev->priv = p->memdesc->priv; + prev->gpuaddr = p->memdesc.gpuaddr; + prev->size = p->memdesc.size; + prev->flags = p->memdesc.flags; + prev->priv = p->memdesc.priv; prev->pid = 0; strlcpy(prev->name, p->name, sizeof(prev->name)); } if (n != NULL) { - next->gpuaddr = n->memdesc->gpuaddr; - next->size = n->memdesc->size; - next->flags = n->memdesc->flags; - next->priv = n->memdesc->priv; + next->gpuaddr = n->memdesc.gpuaddr; + next->size = n->memdesc.size; + next->flags = n->memdesc.flags; + next->priv = n->memdesc.priv; next->pid = 0; strlcpy(next->name, n->name, sizeof(next->name)); } @@ -637,7 +425,7 @@ static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr, nextentry->gpuaddr = (uint64_t) -1; if (ADDR_IN_GLOBAL(mmu, faultaddr)) { - _get_global_entries(faultaddr, preventry, nextentry); + _get_global_entries(mmu, faultaddr, preventry, nextentry); } else if (private) { spin_lock(&private->mem_lock); _get_entries(private, faultaddr, preventry, nextentry); @@ -975,7 +763,7 @@ static void kgsl_iommu_destroy_pagetable(struct kgsl_pagetable *pt) ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; } else { ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; - kgsl_iommu_unmap_globals(pt); + kgsl_iommu_unmap_globals(mmu, pt); } if (iommu_pt->domain) { @@ -1206,7 +994,7 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) goto done; } - ret = kgsl_iommu_map_globals(pt); + kgsl_iommu_map_globals(mmu, pt); done: if (ret) @@ -1326,7 +1114,7 @@ static int _init_per_process_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) goto done; } - ret = kgsl_iommu_map_globals(pt); + kgsl_iommu_map_globals(mmu, pt); done: if (ret) @@ -1414,11 +1202,6 @@ static void kgsl_iommu_close(struct kgsl_mmu *mmu) __free_page(kgsl_dummy_page); kgsl_dummy_page = NULL; } - - kgsl_iommu_remove_global(mmu, &iommu->setstate); - kgsl_sharedmem_free(&iommu->setstate); - kgsl_cleanup_qdss_desc(mmu); - kgsl_cleanup_qtimer_desc(mmu); } static int kgsl_iommu_init(struct kgsl_mmu *mmu) @@ -1436,9 +1219,6 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu) return -EINVAL; } - status = kgsl_allocate_kernel(device, &iommu->setstate, PAGE_SIZE, - KGSL_MEMFLAGS_GPUREADONLY, 0); - iommu->regbase = ioremap(iommu->regstart, iommu->regsize); if (iommu->regbase == NULL) { dev_err(device->dev, @@ -1456,9 +1236,18 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu) } } - kgsl_iommu_add_global(mmu, &iommu->setstate, "setstate"); - kgsl_setup_qdss_desc(device); - kgsl_setup_qtimer_desc(device); + iommu->setstate = kgsl_allocate_global(device, PAGE_SIZE, + KGSL_MEMFLAGS_GPUREADONLY, 0, "setstate"); + + status = PTR_ERR_OR_ZERO(iommu->setstate); + if (status) + goto done; + + device->qdss_desc = kgsl_allocate_global_fixed(device, + "qcom,gpu-qdss-stm", "gpu-qdss"); + + device->qtimer_desc = kgsl_allocate_global_fixed(device, + "qcom,gpu-timer", "gpu-qtimer"); if (!mmu->secured) goto done; @@ -2631,11 +2420,8 @@ struct kgsl_mmu_ops kgsl_iommu_ops = { .mmu_set_pf_policy = kgsl_iommu_set_pf_policy, .mmu_pagefault_resume = kgsl_iommu_pagefault_resume, .mmu_init_pt = kgsl_iommu_init_pt, - .mmu_add_global = kgsl_iommu_add_global, - .mmu_remove_global = kgsl_iommu_remove_global, .mmu_getpagetable = kgsl_iommu_getpagetable, - .mmu_get_qdss_global_entry = kgsl_iommu_get_qdss_global_entry, - .mmu_get_qtimer_global_entry = kgsl_iommu_get_qtimer_global_entry, + .mmu_get_global_base = kgsl_iommu_get_global_base, .probe = kgsl_iommu_probe, }; diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h index 5e8bb24fc0c3..1fea16929b95 100644 --- a/drivers/gpu/msm/kgsl_iommu.h +++ b/drivers/gpu/msm/kgsl_iommu.h @@ -118,10 +118,10 @@ struct kgsl_iommu { void __iomem *regbase; unsigned long regstart; unsigned int regsize; - struct kgsl_memdesc setstate; + struct kgsl_memdesc *setstate; atomic_t clk_enable_count; struct clk *clks[KGSL_IOMMU_MAX_CLKS]; - struct kgsl_memdesc smmu_info; + struct kgsl_memdesc *smmu_info; }; /* diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index bf56982b6ea1..e3dcdb629d6c 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -527,22 +527,14 @@ int kgsl_mmu_sparse_dummy_map(struct kgsl_pagetable *pagetable, return 0; } -void kgsl_mmu_remove_global(struct kgsl_device *device, - struct kgsl_memdesc *memdesc) +u64 kgsl_mmu_get_global_base(struct kgsl_device *device) { - struct kgsl_mmu *mmu = &device->mmu; + struct kgsl_mmu *mmu = &(device->mmu); - if (MMU_OP_VALID(mmu, mmu_remove_global)) - mmu->mmu_ops->mmu_remove_global(mmu, memdesc); -} + if (MMU_OP_VALID(mmu, mmu_get_global_base)) + return mmu->mmu_ops->mmu_get_global_base(mmu); -void kgsl_mmu_add_global(struct kgsl_device *device, - struct kgsl_memdesc *memdesc, const char *name) -{ - struct kgsl_mmu *mmu = &device->mmu; - - if (MMU_OP_VALID(mmu, mmu_add_global)) - mmu->mmu_ops->mmu_add_global(mmu, memdesc, name); + return 0; } void kgsl_mmu_close(struct kgsl_device *device) @@ -567,27 +559,6 @@ bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pagetable, return false; } -struct kgsl_memdesc *kgsl_mmu_get_qdss_global_entry(struct kgsl_device *device) -{ - struct kgsl_mmu *mmu = &device->mmu; - - if (MMU_OP_VALID(mmu, mmu_get_qdss_global_entry)) - return mmu->mmu_ops->mmu_get_qdss_global_entry(); - - return NULL; -} - -struct kgsl_memdesc *kgsl_mmu_get_qtimer_global_entry( - struct kgsl_device *device) -{ - struct kgsl_mmu *mmu = &device->mmu; - - if (MMU_OP_VALID(mmu, mmu_get_qtimer_global_entry)) - return mmu->mmu_ops->mmu_get_qtimer_global_entry(); - - return NULL; -} - /* * NOMMU definitions - NOMMU really just means that the MMU is kept in pass * through and the GPU directly accesses physical memory. Used in debug mode @@ -622,24 +593,20 @@ static struct kgsl_mmu_pt_ops nommu_pt_ops = { .addr_in_range = nommu_gpuaddr_in_range, }; -static void nommu_add_global(struct kgsl_mmu *mmu, - struct kgsl_memdesc *memdesc, const char *name) -{ - memdesc->gpuaddr = (uint64_t) sg_phys(memdesc->sgt->sgl); -} - -static void nommu_remove_global(struct kgsl_mmu *mmu, - struct kgsl_memdesc *memdesc) -{ - memdesc->gpuaddr = 0; -} - static int nommu_init_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) { + struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); + struct kgsl_global_memdesc *md; + if (pt == NULL) return -EINVAL; pt->pt_ops = &nommu_pt_ops; + + list_for_each_entry(md, &device->globals, node) + md->memdesc.gpuaddr = + (uint64_t) sg_phys(md->memdesc.sgt->sgl); + return 0; } @@ -671,8 +638,6 @@ static int nommu_probe(struct kgsl_device *device) static struct kgsl_mmu_ops kgsl_nommu_ops = { .mmu_init = nommu_init, - .mmu_add_global = nommu_add_global, - .mmu_remove_global = nommu_remove_global, .mmu_init_pt = nommu_init_pt, .mmu_getpagetable = nommu_getpagetable, .probe = nommu_probe, diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index d8f8b353a3f7..827b28d9b095 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -68,14 +68,9 @@ struct kgsl_mmu_ops { struct kgsl_pagetable *pt, u64 ttbr0); int (*mmu_set_pf_policy)(struct kgsl_mmu *mmu, unsigned long pf_policy); int (*mmu_init_pt)(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt); - void (*mmu_add_global)(struct kgsl_mmu *mmu, - struct kgsl_memdesc *memdesc, const char *name); - void (*mmu_remove_global)(struct kgsl_mmu *mmu, - struct kgsl_memdesc *memdesc); struct kgsl_pagetable * (*mmu_getpagetable)(struct kgsl_mmu *mmu, unsigned long name); - struct kgsl_memdesc* (*mmu_get_qdss_global_entry)(void); - struct kgsl_memdesc* (*mmu_get_qtimer_global_entry)(void); + u64 (*mmu_get_global_base)(struct kgsl_mmu *mmu); }; struct kgsl_mmu_pt_ops { @@ -221,11 +216,6 @@ int kgsl_mmu_unmap_offset(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc, uint64_t addr, uint64_t offset, uint64_t size); -struct kgsl_memdesc *kgsl_mmu_get_qdss_global_entry(struct kgsl_device *device); - -struct kgsl_memdesc *kgsl_mmu_get_qtimer_global_entry( - struct kgsl_device *device); - int kgsl_mmu_sparse_dummy_map(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc, uint64_t offset, uint64_t size); @@ -346,6 +336,14 @@ kgsl_mmu_pagetable_get_contextidr(struct kgsl_pagetable *pagetable) return 0; } +/** + * kgsl_mmu_get_global_base - Return the base GPU address of the global region + * @device: A KGSL GPU device handle + * + * Return: The virtual address of the base of the global object region + */ +u64 kgsl_mmu_get_global_base(struct kgsl_device *device); + static inline struct device *kgsl_mmu_get_ctx(const char *name) { return ERR_PTR(-ENODEV); diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 818004db767c..ea39e39b66c1 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -4,8 +4,10 @@ */ #include +#include #include #include +#include #include #include "kgsl_device.h" @@ -1265,11 +1267,104 @@ int kgsl_allocate_kernel(struct kgsl_device *device, return 0; } -int kgsl_allocate_global(struct kgsl_device *device, - struct kgsl_memdesc *memdesc, u64 size, u64 flags, u32 priv, - const char *name) +#define KGSL_GLOBAL_MEM_SIZE (20 * SZ_1M) +#define KGSL_GLOBAL_MEM_PAGES (KGSL_GLOBAL_MEM_SIZE >> PAGE_SHIFT) + +static u64 global_get_offset(struct kgsl_device *device, u64 size, + unsigned long priv) +{ + int start = 0, bit; + + if (!device->global_map) { + device->global_map = + kcalloc(BITS_TO_LONGS(KGSL_GLOBAL_MEM_PAGES), + sizeof(unsigned long), GFP_KERNEL); + if (!device->global_map) + return (unsigned long) -ENOMEM; + + device->global_pages = KGSL_GLOBAL_MEM_PAGES; + } + + if (priv & KGSL_MEMDESC_RANDOM) { + u32 offset = device->global_pages - (size >> PAGE_SHIFT); + + start = get_random_int() % offset; + } + + while (start >= 0) { + bit = bitmap_find_next_zero_area(device->global_map, + device->global_pages, start, size >> PAGE_SHIFT, 0); + + if (bit < device->global_pages) + break; + + /* FIXME: We should randomize this */ + start--; + } + + if (WARN_ON(start < 0)) + return (unsigned long) -ENOMEM; + + bitmap_set(device->global_map, bit, size >> PAGE_SHIFT); + + return bit << PAGE_SHIFT; +} + +struct kgsl_memdesc *kgsl_allocate_global_fixed(struct kgsl_device *device, + const char *resource, const char *name) +{ + struct kgsl_global_memdesc *md; + u32 entry[2]; + int ret; + u64 offset; + + if (of_property_read_u32_array(device->pdev->dev.of_node, + resource, entry, 2)) + return ERR_PTR(-ENODEV); + + md = kzalloc(sizeof(*md), GFP_KERNEL); + if (!md) + return ERR_PTR(-ENOMEM); + + kgsl_memdesc_init(device, &md->memdesc, 0); + md->memdesc.priv = KGSL_MEMDESC_GLOBAL; + md->memdesc.physaddr = entry[0]; + md->memdesc.size = entry[1]; + + ret = kgsl_memdesc_sg_dma(&md->memdesc, entry[0], entry[1]); + if (ret) { + kfree(md); + return ERR_PTR(ret); + } + + offset = global_get_offset(device, + kgsl_memdesc_footprint(&md->memdesc), 0); + if (IS_ERR_VALUE(offset)) { + kgsl_sharedmem_free(&md->memdesc); + kfree(md); + return (void *) offset; + } + + if (!md->memdesc.gpuaddr) + md->memdesc.gpuaddr = kgsl_mmu_get_global_base(device) + offset; + + md->name = name; + + /* + * No lock here, because this function is only called during probe/init + * while the caller is holding the mutex + */ + list_add_tail(&md->node, &device->globals); + + return &md->memdesc; +} + +struct kgsl_memdesc *kgsl_allocate_global(struct kgsl_device *device, + u64 size, u64 flags, u32 priv, const char *name) { int ret; + struct kgsl_global_memdesc *md; + u64 offset; /* * For the moment, don't allow secure to be allocated through this @@ -1277,21 +1372,51 @@ int kgsl_allocate_global(struct kgsl_device *device, */ if (flags & KGSL_MEMFLAGS_SECURE) - return -EINVAL; + return ERR_PTR(-EINVAL); - ret = kgsl_allocate_kernel(device, memdesc, size, flags, priv); - if (ret) - return ret; + md = kzalloc(sizeof(*md), GFP_KERNEL); + if (!md) + return ERR_PTR(-ENOMEM); - kgsl_mmu_add_global(device, memdesc, name); - return 0; + priv |= KGSL_MEMDESC_GLOBAL; + + ret = kgsl_allocate_kernel(device, &md->memdesc, size, flags, priv); + if (ret) { + kfree(md); + return ERR_PTR(ret); + } + + offset = global_get_offset(device, + kgsl_memdesc_footprint(&md->memdesc), priv); + if (IS_ERR_VALUE(offset)) { + kgsl_sharedmem_free(&md->memdesc); + kfree(md); + return (void *) offset; + } + + if (!md->memdesc.gpuaddr) + md->memdesc.gpuaddr = kgsl_mmu_get_global_base(device) + offset; + + md->name = name; + + /* + * No lock here, because this function is only called during probe/init + * while the caller is holding the mute + */ + list_add_tail(&md->node, &device->globals); + + return &md->memdesc; } -void kgsl_free_global(struct kgsl_device *device, - struct kgsl_memdesc *memdesc) +void kgsl_free_globals(struct kgsl_device *device) { - kgsl_mmu_remove_global(device, memdesc); - kgsl_sharedmem_free(memdesc); + struct kgsl_global_memdesc *md, *tmp; + + list_for_each_entry_safe(md, tmp, &device->globals, node) { + kgsl_sharedmem_free(&md->memdesc); + list_del(&md->node); + kfree(md); + } } void kgsl_sharedmem_set_noretry(bool val) diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h index 294d1285d482..3f609b0d537b 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.h +++ b/drivers/gpu/msm/kgsl_sharedmem.h @@ -96,7 +96,6 @@ int kgsl_allocate_kernel(struct kgsl_device *device, /** * kgsl_allocate_global - Allocate a global GPU memory object * @device: A GPU device handle - * @memdesc: Memory descriptor for the object * @size: Size of the allocation in bytes * @flags: Control flags for the allocation * @priv: Internal flags for the allocation @@ -105,11 +104,38 @@ int kgsl_allocate_kernel(struct kgsl_device *device, * Allocate a global GPU object for use by all processes. The buffer is * automatically mapped into the kernel address space and added to the list of * global buffers that get mapped into each newly created pagetable. - * Return: 0 on success or negative on failure. + * Return: The memory descriptor on success or a ERR_PTR encoded error on + * failure. */ -int kgsl_allocate_global(struct kgsl_device *device, - struct kgsl_memdesc *memdesc, u64 size, u64 flags, u32 priv, - const char *name); +struct kgsl_memdesc *kgsl_allocate_global(struct kgsl_device *device, + u64 size, u64 flags, u32 priv, const char *name); + +/** + * kgsl_allocate_global_fixed - Allocate a global GPU memory object from a fixed + * region defined in the device tree + * @device: A GPU device handle + * @size: Size of the allocation in bytes + * @flags: Control flags for the allocation + * @priv: Internal flags for the allocation + * + * Allocate a global GPU object for use by all processes. The buffer is + * added to the list of global buffers that get mapped into each newly created + * pagetable. + * + * Return: The memory descriptor on success or a ERR_PTR encoded error on + * failure. + */ +struct kgsl_memdesc *kgsl_allocate_global_fixed(struct kgsl_device *device, + const char *resource, const char *name); + +/** + * kgsl_free_globals - Free all global objects + * @device: A GPU device handle + * + * Free all the global buffer objects. Should only be called during shutdown + * after the pagetables have been freed + */ +void kgsl_free_globals(struct kgsl_device *device); #define MEMFLAGS(_flags, _mask, _shift) \ ((unsigned int) (((_flags) & (_mask)) >> (_shift))) @@ -278,18 +304,6 @@ kgsl_memdesc_footprint(const struct kgsl_memdesc *memdesc) PAGE_SIZE); } -/** - * kgsl_free_global() - Free a device wide GPU allocation and remove it from the - * global pagetable entry list - * - * @device: Pointer to the device - * @memdesc: Pointer to the GPU memory descriptor to free - * - * Remove the specific memory descriptor from the global pagetable entry list - * and free it - */ -void kgsl_free_global(struct kgsl_device *device, struct kgsl_memdesc *memdesc); - void kgsl_sharedmem_set_noretry(bool val); bool kgsl_sharedmem_get_noretry(void); diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index 5ef09944112b..77faab94563f 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -124,7 +124,7 @@ static size_t snapshot_os(struct kgsl_device *device, * Save the last active context from global index since its more * reliable than currrent RB index */ - kgsl_sharedmem_readl(&device->memstore, &header->current_context, + kgsl_sharedmem_readl(device->memstore, &header->current_context, KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context)); context = kgsl_context_get(device, header->current_context);