Loading drivers/gpu/msm/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -40,3 +40,7 @@ config MSM_ADRENO_DEFAULT_GOVERNOR default "msm-adreno-tz" if DEVFREQ_GOV_MSM_ADRENO_TZ default "simple_ondemand" depends on MSM_KGSL config MSM_KGSL_IOMMU bool default y if MSM_KGSL && (MSM_IOMMU || ARM_SMMU) drivers/gpu/msm/Makefile +2 −2 Original line number Diff line number Diff line Loading @@ -9,10 +9,10 @@ msm_kgsl_core-y = \ kgsl_pwrctrl.o \ kgsl_pwrscale.o \ kgsl_mmu.o \ kgsl_iommu.o \ kgsl_snapshot.o \ kgsl_events.o msm_kgsl_core-$(CONFIG_MSM_KGSL_IOMMU) += kgsl_iommu.o msm_kgsl_core-$(CONFIG_DEBUG_FS) += kgsl_debugfs.o msm_kgsl_core-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o msm_kgsl_core-$(CONFIG_SYNC) += kgsl_sync.o Loading @@ -35,9 +35,9 @@ msm_adreno-y += \ adreno_sysfs.o \ adreno.o \ adreno_cp_parser.o \ adreno_iommu.o \ adreno_perfcounter.o msm_adreno-$(CONFIG_MSM_KGSL_IOMMU) += adreno_iommu.o msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o adreno_profile.o msm_adreno-$(CONFIG_COMPAT) += adreno_compat.o Loading drivers/gpu/msm/adreno.c +8 −200 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include "kgsl_trace.h" #include "adreno.h" #include "adreno_iommu.h" #include "adreno_compat.h" #include "adreno_pm4types.h" #include "adreno_trace.h" Loading Loading @@ -69,8 +70,6 @@ static struct devfreq_msm_adreno_tz_data adreno_tz_data = { static const struct kgsl_functable adreno_functable; static struct kgsl_iommu device_3d0_iommu; static struct adreno_device device_3d0 = { .dev = { KGSL_DEVICE_COMMON_INIT(device_3d0.dev), Loading Loading @@ -236,164 +235,6 @@ int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset, return 0; } /* * adreno_iommu_cb_probe() - Adreno iommu context bank probe * * Iommu context bank probe function. */ static int adreno_iommu_cb_probe(struct platform_device *pdev) { struct kgsl_iommu_context *ctx = NULL; struct device_node *node = pdev->dev.of_node; struct kgsl_iommu *iommu = &device_3d0_iommu; int ret = 0; /* Map context names from dt to id's */ if (!strcmp("gfx3d_user", node->name)) { ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; ctx->id = KGSL_IOMMU_CONTEXT_USER; ctx->cb_num = -1; } else if (!strcmp("gfx3d_secure", node->name)) { ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; ctx->id = KGSL_IOMMU_CONTEXT_SECURE; ctx->cb_num = -1; device_3d0.dev.mmu.secured = true; } else { KGSL_CORE_ERR("dt: Unknown context label %s\n", node->name); return -EINVAL; } if (ctx->name != NULL) { KGSL_CORE_ERR("dt: %s appears multiple times\n", node->name); return -EINVAL; } ctx->name = node->name; /* this property won't be found for all context banks */ if (of_property_read_u32(node, "qcom,gpu-offset", &ctx->gpu_offset)) ctx->gpu_offset = UINT_MAX; ctx->kgsldev = &device_3d0.dev; /* arm-smmu driver we'll have the right device pointer here. */ if (of_find_property(node, "iommus", NULL)) { ctx->dev = &pdev->dev; } else { /* * old iommu driver requires that we query the context bank * device rather than getting it from dt. */ ctx->dev = kgsl_mmu_get_ctx(ctx->name); if (IS_ERR_OR_NULL(ctx->dev)) { ret = (ctx->dev == NULL) ? -ENODEV : PTR_ERR(ctx->dev); KGSL_CORE_ERR("ctx %s: kgsl_mmu_get_ctx err: %d\n", ctx->name, ret); return ret; } } kgsl_mmu_set_mmutype(KGSL_MMU_TYPE_IOMMU); return ret; } static struct of_device_id iommu_match_table[] = { { .compatible = "qcom,kgsl-smmu-v1", }, { .compatible = "qcom,kgsl-smmu-v2", }, { .compatible = "qcom,smmu-kgsl-cb", }, {} }; /** * adreno_iommu_pdev_probe() - Adreno iommu context bank probe * @pdev: Platform device * * Iommu probe function. */ static int adreno_iommu_pdev_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const char *cname; struct property *prop; u32 reg_val[2]; int i = 0; struct kgsl_iommu *iommu = &device_3d0_iommu; if (of_device_is_compatible(dev->of_node, "qcom,smmu-kgsl-cb")) return adreno_iommu_cb_probe(pdev); else if (of_device_is_compatible(dev->of_node, "qcom,kgsl-smmu-v1")) iommu->version = 1; else iommu->version = 2; if (of_property_read_u32_array(pdev->dev.of_node, "reg", reg_val, 2)) { KGSL_CORE_ERR("dt: Unable to read KGSL IOMMU register range\n"); return -EINVAL; } iommu->regstart = reg_val[0]; iommu->regsize = reg_val[1]; /* Protecting the SMMU registers is mandatory */ if (of_property_read_u32_array(pdev->dev.of_node, "qcom,protect", reg_val, 2)) { KGSL_CORE_ERR("dt: no iommu protection range specified\n"); return -EINVAL; } iommu->protect.base = reg_val[0] / sizeof(u32); iommu->protect.range = ilog2(reg_val[1] / sizeof(u32)); of_property_for_each_string(dev->of_node, "clock-names", prop, cname) { struct clk *c = devm_clk_get(dev, cname); if (IS_ERR(c)) { KGSL_CORE_ERR("dt: Couldn't get clock: %s\n", cname); return -ENODEV; } if (i >= KGSL_IOMMU_MAX_CLKS) { KGSL_CORE_ERR("dt: too many clocks defined.\n"); return -EINVAL; } iommu->clks[i] = c; ++i; } if (of_property_read_bool(pdev->dev.of_node, "qcom,retention")) device_3d0.dev.mmu.features |= KGSL_MMU_RETENTION; if (of_property_read_bool(pdev->dev.of_node, "qcom,global_pt")) device_3d0.dev.mmu.features |= KGSL_MMU_GLOBAL_PAGETABLE; if (of_property_read_bool(pdev->dev.of_node, "qcom,hyp_secure_alloc")) device_3d0.dev.mmu.features |= KGSL_MMU_HYP_SECURE_ALLOC; if (of_property_read_bool(pdev->dev.of_node, "qcom,force-32bit")) device_3d0.dev.mmu.features |= KGSL_MMU_FORCE_32BIT; if (of_property_read_u32(pdev->dev.of_node, "qcom,micro-mmu-control", &iommu->micro_mmu_ctrl)) iommu->micro_mmu_ctrl = UINT_MAX; if (of_property_read_bool(pdev->dev.of_node, "qcom,coherent-htw")) device_3d0.dev.mmu.features |= KGSL_MMU_COHERENT_HTW; if (of_property_read_u32(pdev->dev.of_node, "qcom,secure_align_mask", &device_3d0.dev.mmu.secure_align_mask)) device_3d0.dev.mmu.secure_align_mask = 0xfff; return of_platform_populate(pdev->dev.of_node, iommu_match_table, NULL, &pdev->dev); } static struct platform_driver kgsl_iommu_platform_driver = { .probe = adreno_iommu_pdev_probe, .driver = { .owner = THIS_MODULE, .name = "kgsl-iommu", .of_match_table = iommu_match_table, } }; static int _get_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) Loading Loading @@ -1038,10 +879,6 @@ static int adreno_probe(struct platform_device *pdev) struct adreno_device *adreno_dev; int status; /* Defer adreno probe if IOMMU is not already probed */ if (device_3d0_iommu.regstart == 0) return -EPROBE_DEFER; adreno_dev = adreno_get_dev(pdev); if (adreno_dev == NULL) { Loading @@ -1051,7 +888,6 @@ static int adreno_probe(struct platform_device *pdev) device = KGSL_DEVICE(adreno_dev); device->pdev = pdev; device->mmu.priv = &device_3d0_iommu; /* Get the chip ID from the DT and set up target specific parameters */ adreno_identify_gpu(adreno_dev); Loading Loading @@ -1830,7 +1666,8 @@ static int adreno_getproperty(struct kgsl_device *device, memset(&devinfo, 0, sizeof(devinfo)); devinfo.device_id = device->id+1; devinfo.chip_id = adreno_dev->chipid; devinfo.mmu_enabled = kgsl_mmu_enabled(); devinfo.mmu_enabled = MMU_FEATURE(&device->mmu, KGSL_MMU_PAGED); devinfo.gmem_gpubaseaddr = adreno_dev->gmem_base; devinfo.gmem_sizebytes = adreno_dev->gmem_size; Loading Loading @@ -1873,9 +1710,11 @@ static int adreno_getproperty(struct kgsl_device *device, break; case KGSL_PROP_MMU_ENABLE: { int mmu_prop = kgsl_mmu_enabled(); /* Report MMU only if we can handle paged memory */ int mmu_prop = MMU_FEATURE(&device->mmu, KGSL_MMU_PAGED); if (sizebytes != sizeof(int)) { if (sizebytes < sizeof(mmu_prop)) { status = -EINVAL; break; } Loading Loading @@ -2919,27 +2758,6 @@ static struct platform_driver kgsl_bus_platform_driver = { } }; #if defined(CONFIG_ARM_SMMU) || defined(CONFIG_MSM_IOMMU) static int kgsl_iommu_driver_register(void) { return platform_driver_register(&kgsl_iommu_platform_driver); } static void kgsl_iommu_driver_unregister(void) { platform_driver_unregister(&kgsl_iommu_platform_driver); } #else static inline int kgsl_iommu_driver_register(void) { return 0; } static inline void kgsl_iommu_driver_unregister(void) { } #endif static int __init kgsl_3d_init(void) { int ret; Loading @@ -2948,17 +2766,9 @@ static int __init kgsl_3d_init(void) if (ret) return ret; ret = kgsl_iommu_driver_register(); if (ret) { platform_driver_unregister(&kgsl_bus_platform_driver); return ret; } ret = platform_driver_register(&adreno_platform_driver); if (ret) { kgsl_iommu_driver_unregister(); if (ret) platform_driver_unregister(&kgsl_bus_platform_driver); } return ret; } Loading @@ -2966,9 +2776,7 @@ static int __init kgsl_3d_init(void) static void __exit kgsl_3d_exit(void) { platform_driver_unregister(&adreno_platform_driver); kgsl_iommu_driver_unregister(); platform_driver_unregister(&kgsl_bus_platform_driver); } module_init(kgsl_3d_init); Loading drivers/gpu/msm/adreno.h +0 −21 Original line number Diff line number Diff line Loading @@ -855,30 +855,12 @@ void adreno_coresight_remove(struct adreno_device *adreno_dev); bool adreno_hw_isidle(struct adreno_device *adreno_dev); int adreno_iommu_set_pt_ctx(struct adreno_ringbuffer *rb, struct kgsl_pagetable *new_pt, struct adreno_context *drawctxt); int adreno_iommu_init(struct adreno_device *adreno_dev); void adreno_iommu_set_pt_generate_rb_cmds(struct adreno_ringbuffer *rb, struct kgsl_pagetable *pt); void adreno_fault_detect_start(struct adreno_device *adreno_dev); void adreno_fault_detect_stop(struct adreno_device *adreno_dev); void adreno_hang_int_callback(struct adreno_device *adreno_dev, int bit); void adreno_cp_callback(struct adreno_device *adreno_dev, int bit); unsigned int adreno_iommu_set_pt_ib(struct adreno_ringbuffer *rb, unsigned int *cmds, struct kgsl_pagetable *pt); unsigned int adreno_iommu_set_pt_generate_cmds( struct adreno_ringbuffer *rb, unsigned int *cmds, struct kgsl_pagetable *pt); int adreno_sysfs_init(struct adreno_device *adreno_dev); void adreno_sysfs_close(struct adreno_device *adreno_dev); Loading Loading @@ -1407,9 +1389,6 @@ void adreno_readreg64(struct adreno_device *adreno_dev, void adreno_writereg64(struct adreno_device *adreno_dev, enum adreno_regs lo, enum adreno_regs hi, uint64_t val); unsigned int adreno_iommu_set_apriv(struct adreno_device *adreno_dev, unsigned int *cmds, int set); static inline bool adreno_soft_fault_detect(struct adreno_device *adreno_dev) { return adreno_dev->fast_hang_detect && Loading drivers/gpu/msm/adreno_a4xx.c +86 −2 Original line number Diff line number Diff line Loading @@ -1798,6 +1798,90 @@ static struct adreno_snapshot_data a4xx_snapshot_data = { .sect_sizes = &a4xx_snap_sizes, }; #define ADRENO_RB_PREEMPT_TOKEN_DWORDS 125 static int a4xx_submit_preempt_token(struct adreno_ringbuffer *rb, struct adreno_ringbuffer *incoming_rb) { struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb); struct kgsl_device *device = KGSL_DEVICE(adreno_dev); unsigned int *ringcmds, *start; struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); int ptname; struct kgsl_pagetable *pt; int pt_switch_sizedwords = 0, total_sizedwords = 20; unsigned link[ADRENO_RB_PREEMPT_TOKEN_DWORDS]; uint i; if (incoming_rb->preempted_midway) { kgsl_sharedmem_readl(&incoming_rb->pagetable_desc, &ptname, offsetof( struct adreno_ringbuffer_pagetable_info, current_rb_ptname)); pt = kgsl_mmu_get_pt_from_ptname(&(device->mmu), ptname); /* * always expect a valid pt, else pt refcounting is * messed up or current pt tracking has a bug which * could lead to eventual disaster */ BUG_ON(!pt); /* set the ringbuffer for incoming RB */ pt_switch_sizedwords = adreno_iommu_set_pt_generate_cmds(incoming_rb, &link[0], pt); total_sizedwords += pt_switch_sizedwords; } /* * Allocate total_sizedwords space in RB, this is the max space * required. */ ringcmds = adreno_ringbuffer_allocspace(rb, total_sizedwords); if (IS_ERR(ringcmds)) return PTR_ERR(ringcmds); start = ringcmds; *ringcmds++ = cp_packet(adreno_dev, CP_SET_PROTECTED_MODE, 1); *ringcmds++ = 0; if (incoming_rb->preempted_midway) { for (i = 0; i < pt_switch_sizedwords; i++) *ringcmds++ = link[i]; } *ringcmds++ = cp_register(adreno_dev, adreno_getreg(adreno_dev, ADRENO_REG_CP_PREEMPT_DISABLE), 1); *ringcmds++ = 0; *ringcmds++ = cp_packet(adreno_dev, CP_SET_PROTECTED_MODE, 1); *ringcmds++ = 1; ringcmds += gpudev->preemption_token(adreno_dev, rb, ringcmds, device->memstore.gpuaddr + KGSL_MEMSTORE_RB_OFFSET(rb, preempted)); if ((uint)(ringcmds - start) > total_sizedwords) { KGSL_DRV_ERR(device, "Insufficient rb size allocated\n"); BUG(); } /* * If we have commands less than the space reserved in RB * adjust the wptr accordingly */ rb->wptr = rb->wptr - (total_sizedwords - (uint)(ringcmds - start)); /* submit just the preempt token */ mb(); kgsl_pwrscale_busy(device); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_WPTR, rb->wptr); return 0; } /** * a4xx_preempt_trig_state() - Schedule preemption in TRIGGERRED * state Loading Loading @@ -1886,7 +1970,7 @@ static void a4xx_preempt_trig_state( /* Submit preempt token to make preemption happen */ if (adreno_drawctxt_switch(adreno_dev, adreno_dev->cur_rb, NULL, 0)) BUG(); if (adreno_ringbuffer_submit_preempt_token(adreno_dev->cur_rb, if (a4xx_submit_preempt_token(adreno_dev->cur_rb, adreno_dev->next_rb)) BUG(); dispatcher->preempt_token_submit = 1; Loading Loading @@ -1997,7 +2081,7 @@ static void a4xx_preempt_clear_state( adreno_dev->next_rb, adreno_dev->next_rb->timestamp); /* submit preempt token packet to ensure preemption */ if (switch_low_to_high < 0) { ret = adreno_ringbuffer_submit_preempt_token( ret = a4xx_submit_preempt_token( adreno_dev->cur_rb, adreno_dev->next_rb); /* * unexpected since we are submitting this when rptr = wptr, Loading Loading
drivers/gpu/msm/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -40,3 +40,7 @@ config MSM_ADRENO_DEFAULT_GOVERNOR default "msm-adreno-tz" if DEVFREQ_GOV_MSM_ADRENO_TZ default "simple_ondemand" depends on MSM_KGSL config MSM_KGSL_IOMMU bool default y if MSM_KGSL && (MSM_IOMMU || ARM_SMMU)
drivers/gpu/msm/Makefile +2 −2 Original line number Diff line number Diff line Loading @@ -9,10 +9,10 @@ msm_kgsl_core-y = \ kgsl_pwrctrl.o \ kgsl_pwrscale.o \ kgsl_mmu.o \ kgsl_iommu.o \ kgsl_snapshot.o \ kgsl_events.o msm_kgsl_core-$(CONFIG_MSM_KGSL_IOMMU) += kgsl_iommu.o msm_kgsl_core-$(CONFIG_DEBUG_FS) += kgsl_debugfs.o msm_kgsl_core-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o msm_kgsl_core-$(CONFIG_SYNC) += kgsl_sync.o Loading @@ -35,9 +35,9 @@ msm_adreno-y += \ adreno_sysfs.o \ adreno.o \ adreno_cp_parser.o \ adreno_iommu.o \ adreno_perfcounter.o msm_adreno-$(CONFIG_MSM_KGSL_IOMMU) += adreno_iommu.o msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o adreno_profile.o msm_adreno-$(CONFIG_COMPAT) += adreno_compat.o Loading
drivers/gpu/msm/adreno.c +8 −200 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include "kgsl_trace.h" #include "adreno.h" #include "adreno_iommu.h" #include "adreno_compat.h" #include "adreno_pm4types.h" #include "adreno_trace.h" Loading Loading @@ -69,8 +70,6 @@ static struct devfreq_msm_adreno_tz_data adreno_tz_data = { static const struct kgsl_functable adreno_functable; static struct kgsl_iommu device_3d0_iommu; static struct adreno_device device_3d0 = { .dev = { KGSL_DEVICE_COMMON_INIT(device_3d0.dev), Loading Loading @@ -236,164 +235,6 @@ int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset, return 0; } /* * adreno_iommu_cb_probe() - Adreno iommu context bank probe * * Iommu context bank probe function. */ static int adreno_iommu_cb_probe(struct platform_device *pdev) { struct kgsl_iommu_context *ctx = NULL; struct device_node *node = pdev->dev.of_node; struct kgsl_iommu *iommu = &device_3d0_iommu; int ret = 0; /* Map context names from dt to id's */ if (!strcmp("gfx3d_user", node->name)) { ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; ctx->id = KGSL_IOMMU_CONTEXT_USER; ctx->cb_num = -1; } else if (!strcmp("gfx3d_secure", node->name)) { ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; ctx->id = KGSL_IOMMU_CONTEXT_SECURE; ctx->cb_num = -1; device_3d0.dev.mmu.secured = true; } else { KGSL_CORE_ERR("dt: Unknown context label %s\n", node->name); return -EINVAL; } if (ctx->name != NULL) { KGSL_CORE_ERR("dt: %s appears multiple times\n", node->name); return -EINVAL; } ctx->name = node->name; /* this property won't be found for all context banks */ if (of_property_read_u32(node, "qcom,gpu-offset", &ctx->gpu_offset)) ctx->gpu_offset = UINT_MAX; ctx->kgsldev = &device_3d0.dev; /* arm-smmu driver we'll have the right device pointer here. */ if (of_find_property(node, "iommus", NULL)) { ctx->dev = &pdev->dev; } else { /* * old iommu driver requires that we query the context bank * device rather than getting it from dt. */ ctx->dev = kgsl_mmu_get_ctx(ctx->name); if (IS_ERR_OR_NULL(ctx->dev)) { ret = (ctx->dev == NULL) ? -ENODEV : PTR_ERR(ctx->dev); KGSL_CORE_ERR("ctx %s: kgsl_mmu_get_ctx err: %d\n", ctx->name, ret); return ret; } } kgsl_mmu_set_mmutype(KGSL_MMU_TYPE_IOMMU); return ret; } static struct of_device_id iommu_match_table[] = { { .compatible = "qcom,kgsl-smmu-v1", }, { .compatible = "qcom,kgsl-smmu-v2", }, { .compatible = "qcom,smmu-kgsl-cb", }, {} }; /** * adreno_iommu_pdev_probe() - Adreno iommu context bank probe * @pdev: Platform device * * Iommu probe function. */ static int adreno_iommu_pdev_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const char *cname; struct property *prop; u32 reg_val[2]; int i = 0; struct kgsl_iommu *iommu = &device_3d0_iommu; if (of_device_is_compatible(dev->of_node, "qcom,smmu-kgsl-cb")) return adreno_iommu_cb_probe(pdev); else if (of_device_is_compatible(dev->of_node, "qcom,kgsl-smmu-v1")) iommu->version = 1; else iommu->version = 2; if (of_property_read_u32_array(pdev->dev.of_node, "reg", reg_val, 2)) { KGSL_CORE_ERR("dt: Unable to read KGSL IOMMU register range\n"); return -EINVAL; } iommu->regstart = reg_val[0]; iommu->regsize = reg_val[1]; /* Protecting the SMMU registers is mandatory */ if (of_property_read_u32_array(pdev->dev.of_node, "qcom,protect", reg_val, 2)) { KGSL_CORE_ERR("dt: no iommu protection range specified\n"); return -EINVAL; } iommu->protect.base = reg_val[0] / sizeof(u32); iommu->protect.range = ilog2(reg_val[1] / sizeof(u32)); of_property_for_each_string(dev->of_node, "clock-names", prop, cname) { struct clk *c = devm_clk_get(dev, cname); if (IS_ERR(c)) { KGSL_CORE_ERR("dt: Couldn't get clock: %s\n", cname); return -ENODEV; } if (i >= KGSL_IOMMU_MAX_CLKS) { KGSL_CORE_ERR("dt: too many clocks defined.\n"); return -EINVAL; } iommu->clks[i] = c; ++i; } if (of_property_read_bool(pdev->dev.of_node, "qcom,retention")) device_3d0.dev.mmu.features |= KGSL_MMU_RETENTION; if (of_property_read_bool(pdev->dev.of_node, "qcom,global_pt")) device_3d0.dev.mmu.features |= KGSL_MMU_GLOBAL_PAGETABLE; if (of_property_read_bool(pdev->dev.of_node, "qcom,hyp_secure_alloc")) device_3d0.dev.mmu.features |= KGSL_MMU_HYP_SECURE_ALLOC; if (of_property_read_bool(pdev->dev.of_node, "qcom,force-32bit")) device_3d0.dev.mmu.features |= KGSL_MMU_FORCE_32BIT; if (of_property_read_u32(pdev->dev.of_node, "qcom,micro-mmu-control", &iommu->micro_mmu_ctrl)) iommu->micro_mmu_ctrl = UINT_MAX; if (of_property_read_bool(pdev->dev.of_node, "qcom,coherent-htw")) device_3d0.dev.mmu.features |= KGSL_MMU_COHERENT_HTW; if (of_property_read_u32(pdev->dev.of_node, "qcom,secure_align_mask", &device_3d0.dev.mmu.secure_align_mask)) device_3d0.dev.mmu.secure_align_mask = 0xfff; return of_platform_populate(pdev->dev.of_node, iommu_match_table, NULL, &pdev->dev); } static struct platform_driver kgsl_iommu_platform_driver = { .probe = adreno_iommu_pdev_probe, .driver = { .owner = THIS_MODULE, .name = "kgsl-iommu", .of_match_table = iommu_match_table, } }; static int _get_counter(struct adreno_device *adreno_dev, int group, int countable, unsigned int *lo, unsigned int *hi) Loading Loading @@ -1038,10 +879,6 @@ static int adreno_probe(struct platform_device *pdev) struct adreno_device *adreno_dev; int status; /* Defer adreno probe if IOMMU is not already probed */ if (device_3d0_iommu.regstart == 0) return -EPROBE_DEFER; adreno_dev = adreno_get_dev(pdev); if (adreno_dev == NULL) { Loading @@ -1051,7 +888,6 @@ static int adreno_probe(struct platform_device *pdev) device = KGSL_DEVICE(adreno_dev); device->pdev = pdev; device->mmu.priv = &device_3d0_iommu; /* Get the chip ID from the DT and set up target specific parameters */ adreno_identify_gpu(adreno_dev); Loading Loading @@ -1830,7 +1666,8 @@ static int adreno_getproperty(struct kgsl_device *device, memset(&devinfo, 0, sizeof(devinfo)); devinfo.device_id = device->id+1; devinfo.chip_id = adreno_dev->chipid; devinfo.mmu_enabled = kgsl_mmu_enabled(); devinfo.mmu_enabled = MMU_FEATURE(&device->mmu, KGSL_MMU_PAGED); devinfo.gmem_gpubaseaddr = adreno_dev->gmem_base; devinfo.gmem_sizebytes = adreno_dev->gmem_size; Loading Loading @@ -1873,9 +1710,11 @@ static int adreno_getproperty(struct kgsl_device *device, break; case KGSL_PROP_MMU_ENABLE: { int mmu_prop = kgsl_mmu_enabled(); /* Report MMU only if we can handle paged memory */ int mmu_prop = MMU_FEATURE(&device->mmu, KGSL_MMU_PAGED); if (sizebytes != sizeof(int)) { if (sizebytes < sizeof(mmu_prop)) { status = -EINVAL; break; } Loading Loading @@ -2919,27 +2758,6 @@ static struct platform_driver kgsl_bus_platform_driver = { } }; #if defined(CONFIG_ARM_SMMU) || defined(CONFIG_MSM_IOMMU) static int kgsl_iommu_driver_register(void) { return platform_driver_register(&kgsl_iommu_platform_driver); } static void kgsl_iommu_driver_unregister(void) { platform_driver_unregister(&kgsl_iommu_platform_driver); } #else static inline int kgsl_iommu_driver_register(void) { return 0; } static inline void kgsl_iommu_driver_unregister(void) { } #endif static int __init kgsl_3d_init(void) { int ret; Loading @@ -2948,17 +2766,9 @@ static int __init kgsl_3d_init(void) if (ret) return ret; ret = kgsl_iommu_driver_register(); if (ret) { platform_driver_unregister(&kgsl_bus_platform_driver); return ret; } ret = platform_driver_register(&adreno_platform_driver); if (ret) { kgsl_iommu_driver_unregister(); if (ret) platform_driver_unregister(&kgsl_bus_platform_driver); } return ret; } Loading @@ -2966,9 +2776,7 @@ static int __init kgsl_3d_init(void) static void __exit kgsl_3d_exit(void) { platform_driver_unregister(&adreno_platform_driver); kgsl_iommu_driver_unregister(); platform_driver_unregister(&kgsl_bus_platform_driver); } module_init(kgsl_3d_init); Loading
drivers/gpu/msm/adreno.h +0 −21 Original line number Diff line number Diff line Loading @@ -855,30 +855,12 @@ void adreno_coresight_remove(struct adreno_device *adreno_dev); bool adreno_hw_isidle(struct adreno_device *adreno_dev); int adreno_iommu_set_pt_ctx(struct adreno_ringbuffer *rb, struct kgsl_pagetable *new_pt, struct adreno_context *drawctxt); int adreno_iommu_init(struct adreno_device *adreno_dev); void adreno_iommu_set_pt_generate_rb_cmds(struct adreno_ringbuffer *rb, struct kgsl_pagetable *pt); void adreno_fault_detect_start(struct adreno_device *adreno_dev); void adreno_fault_detect_stop(struct adreno_device *adreno_dev); void adreno_hang_int_callback(struct adreno_device *adreno_dev, int bit); void adreno_cp_callback(struct adreno_device *adreno_dev, int bit); unsigned int adreno_iommu_set_pt_ib(struct adreno_ringbuffer *rb, unsigned int *cmds, struct kgsl_pagetable *pt); unsigned int adreno_iommu_set_pt_generate_cmds( struct adreno_ringbuffer *rb, unsigned int *cmds, struct kgsl_pagetable *pt); int adreno_sysfs_init(struct adreno_device *adreno_dev); void adreno_sysfs_close(struct adreno_device *adreno_dev); Loading Loading @@ -1407,9 +1389,6 @@ void adreno_readreg64(struct adreno_device *adreno_dev, void adreno_writereg64(struct adreno_device *adreno_dev, enum adreno_regs lo, enum adreno_regs hi, uint64_t val); unsigned int adreno_iommu_set_apriv(struct adreno_device *adreno_dev, unsigned int *cmds, int set); static inline bool adreno_soft_fault_detect(struct adreno_device *adreno_dev) { return adreno_dev->fast_hang_detect && Loading
drivers/gpu/msm/adreno_a4xx.c +86 −2 Original line number Diff line number Diff line Loading @@ -1798,6 +1798,90 @@ static struct adreno_snapshot_data a4xx_snapshot_data = { .sect_sizes = &a4xx_snap_sizes, }; #define ADRENO_RB_PREEMPT_TOKEN_DWORDS 125 static int a4xx_submit_preempt_token(struct adreno_ringbuffer *rb, struct adreno_ringbuffer *incoming_rb) { struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb); struct kgsl_device *device = KGSL_DEVICE(adreno_dev); unsigned int *ringcmds, *start; struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); int ptname; struct kgsl_pagetable *pt; int pt_switch_sizedwords = 0, total_sizedwords = 20; unsigned link[ADRENO_RB_PREEMPT_TOKEN_DWORDS]; uint i; if (incoming_rb->preempted_midway) { kgsl_sharedmem_readl(&incoming_rb->pagetable_desc, &ptname, offsetof( struct adreno_ringbuffer_pagetable_info, current_rb_ptname)); pt = kgsl_mmu_get_pt_from_ptname(&(device->mmu), ptname); /* * always expect a valid pt, else pt refcounting is * messed up or current pt tracking has a bug which * could lead to eventual disaster */ BUG_ON(!pt); /* set the ringbuffer for incoming RB */ pt_switch_sizedwords = adreno_iommu_set_pt_generate_cmds(incoming_rb, &link[0], pt); total_sizedwords += pt_switch_sizedwords; } /* * Allocate total_sizedwords space in RB, this is the max space * required. */ ringcmds = adreno_ringbuffer_allocspace(rb, total_sizedwords); if (IS_ERR(ringcmds)) return PTR_ERR(ringcmds); start = ringcmds; *ringcmds++ = cp_packet(adreno_dev, CP_SET_PROTECTED_MODE, 1); *ringcmds++ = 0; if (incoming_rb->preempted_midway) { for (i = 0; i < pt_switch_sizedwords; i++) *ringcmds++ = link[i]; } *ringcmds++ = cp_register(adreno_dev, adreno_getreg(adreno_dev, ADRENO_REG_CP_PREEMPT_DISABLE), 1); *ringcmds++ = 0; *ringcmds++ = cp_packet(adreno_dev, CP_SET_PROTECTED_MODE, 1); *ringcmds++ = 1; ringcmds += gpudev->preemption_token(adreno_dev, rb, ringcmds, device->memstore.gpuaddr + KGSL_MEMSTORE_RB_OFFSET(rb, preempted)); if ((uint)(ringcmds - start) > total_sizedwords) { KGSL_DRV_ERR(device, "Insufficient rb size allocated\n"); BUG(); } /* * If we have commands less than the space reserved in RB * adjust the wptr accordingly */ rb->wptr = rb->wptr - (total_sizedwords - (uint)(ringcmds - start)); /* submit just the preempt token */ mb(); kgsl_pwrscale_busy(device); adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_WPTR, rb->wptr); return 0; } /** * a4xx_preempt_trig_state() - Schedule preemption in TRIGGERRED * state Loading Loading @@ -1886,7 +1970,7 @@ static void a4xx_preempt_trig_state( /* Submit preempt token to make preemption happen */ if (adreno_drawctxt_switch(adreno_dev, adreno_dev->cur_rb, NULL, 0)) BUG(); if (adreno_ringbuffer_submit_preempt_token(adreno_dev->cur_rb, if (a4xx_submit_preempt_token(adreno_dev->cur_rb, adreno_dev->next_rb)) BUG(); dispatcher->preempt_token_submit = 1; Loading Loading @@ -1997,7 +2081,7 @@ static void a4xx_preempt_clear_state( adreno_dev->next_rb, adreno_dev->next_rb->timestamp); /* submit preempt token packet to ensure preemption */ if (switch_low_to_high < 0) { ret = adreno_ringbuffer_submit_preempt_token( ret = a4xx_submit_preempt_token( adreno_dev->cur_rb, adreno_dev->next_rb); /* * unexpected since we are submitting this when rptr = wptr, Loading