diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index e72a85b5985f..4f866925e423 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -885,6 +885,40 @@ static void adreno_of_get_ca_aware_properties(struct adreno_device *adreno_dev, } } +/* Dynamically build the OPP table for the GPU device */ +static void adreno_build_opp_table(struct device *dev, struct kgsl_pwrctrl *pwr) +{ + unsigned long freq = 0; + int i; + + /* + * First an annoying step: Some targets have clock drivers that + * "helpfully" builds a OPP table for us but usually it is wrong. + * Go through and filter out unsupported frequencies + */ + + for (;;) { + struct dev_pm_opp *opp = dev_pm_opp_find_freq_ceil(dev, &freq); + + if (IS_ERR(opp)) + break; + + for (i = 0; i < pwr->num_pwrlevels; i++) { + if (freq == pwr->pwrlevels[i].gpu_freq) + break; + } + + if (i == pwr->num_pwrlevels) + dev_pm_opp_remove(dev, freq); + + freq++; + } + + /* Now add all of our supported frequencies into the tree */ + for (i = 0; i < pwr->num_pwrlevels; i++) + dev_pm_opp_add(dev, pwr->pwrlevels[i].gpu_freq, 0); +} + static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev, struct device_node *node) { @@ -893,45 +927,49 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev, struct device_node *child; int ret; - /* ADD the GPU OPP table if we define it */ - if (of_find_property(device->pdev->dev.of_node, - "operating-points-v2", NULL)) { - ret = dev_pm_opp_of_add_table(&device->pdev->dev); - if (ret) { - dev_err(device->dev, - "Unable to set the GPU OPP table: %d\n", ret); - return ret; - } - } - pwr->num_pwrlevels = 0; for_each_child_of_node(node, child) { - unsigned int index, freq = 0; + u32 index, freq = 0, voltage, bus; struct kgsl_pwrlevel *level; - if (of_property_read_u32(child, "reg", &index)) { - dev_err(device->dev, - "%pOF: powerlevel index not found\n", child); - of_node_put(child); - return -EINVAL; + ret = of_property_read_u32(child, "reg", &index); + if (ret) { + dev_err(device->dev, "%pOF: powerlevel index not found\n", + child); + goto out; } - if (of_property_read_u32(child, "qcom,gpu-freq", &freq)) { - dev_err(device->dev, - "%pOF: Unable to read qcom,gpu-freq\n", child); - of_node_put(child); - return -EINVAL; + ret = of_property_read_u32(child, "qcom,gpu-freq", &freq); + if (ret) { + dev_err(device->dev, "%pOF: Unable to read qcom,gpu-freq\n", + child); + goto out; } /* Ignore "zero" powerlevels */ if (!freq) continue; + ret = of_property_read_u32(child, "qcom,level", &voltage); + if (ret) { + dev_err(device->dev, "%pOF: Unable to read qcom,level\n", + child); + goto out; + } + + ret = kgsl_of_property_read_ddrtype(child, "qcom,bus-freq", + &bus); + if (ret) { + dev_err(device->dev, "%pOF:Unable to read qcom,bus-freq\n", + child); + goto out; + } + + if (index >= KGSL_MAX_PWRLEVELS) { - dev_err(device->dev, - "%pOF: Pwrlevel index %d is out of range\n", - child, index); + dev_err(device->dev, "%pOF: Pwrlevel index %d is out of range\n", + child, index); continue; } @@ -941,20 +979,12 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev, level = &pwr->pwrlevels[index]; level->gpu_freq = freq; + level->bus_freq = bus; + level->voltage_level = voltage; of_property_read_u32(child, "qcom,acd-level", &level->acd_level); - ret = kgsl_of_property_read_ddrtype(child, - "qcom,bus-freq", &level->bus_freq); - if (ret) { - dev_err(device->dev, - "%pOF: Couldn't read the bus frequency for power level %d\n", - child, index); - of_node_put(child); - return ret; - } - level->bus_min = level->bus_freq; kgsl_of_property_read_ddrtype(child, "qcom,bus-min", &level->bus_min); @@ -964,7 +994,11 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev, "qcom,bus-max", &level->bus_max); } + adreno_build_opp_table(&device->pdev->dev, pwr); return 0; +out: + of_node_put(child); + return ret; } static void adreno_of_get_initial_pwrlevel(struct adreno_device *adreno_dev, diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index bed378f56666..f396224fc2a5 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -2858,8 +2858,8 @@ int adreno_dispatcher_idle(struct adreno_device *adreno_dev) * Ensure that this function is not called when dispatcher * mutex is held and device is started */ - if (mutex_is_locked(&dispatcher->mutex) && - (__mutex_owner(&dispatcher->mutex) == current)) + + if (WARN_ON(mutex_is_locked(&dispatcher->mutex))) return -EDEADLK; adreno_get_gpu_halt(adreno_dev); diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 794ec014e809..9975e1cef2f4 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -4346,7 +4346,7 @@ static vm_fault_t kgsl_gpumem_vm_fault(struct vm_fault *vmf) { struct kgsl_mem_entry *entry = vmf->vma->vm_private_data; - int ret; + vm_fault_t ret; if (!entry) return VM_FAULT_SIGBUS; @@ -4354,7 +4354,7 @@ kgsl_gpumem_vm_fault(struct vm_fault *vmf) return VM_FAULT_SIGBUS; ret = entry->memdesc.ops->vmfault(&entry->memdesc, vmf->vma, vmf); - if ((ret == 0) || (ret == VM_FAULT_NOPAGE)) + if (!ret || ret == VM_FAULT_NOPAGE) entry->priv->gpumem_mapped += PAGE_SIZE; return ret; @@ -4776,7 +4776,7 @@ static int _register_device(struct kgsl_device *device) } device->dev->dma_mask = &dma_mask; - arch_setup_dma_ops(device->dev, 0, 0, NULL, false); + set_dma_ops(device->dev, NULL); dev_set_drvdata(&device->pdev->dev, device); return 0; diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index 5ad61fc969bc..43b5a4c5c54a 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -163,8 +163,8 @@ struct kgsl_memdesc; struct kgsl_memdesc_ops { unsigned int vmflags; - int (*vmfault)(struct kgsl_memdesc *memdesc, struct vm_area_struct *vma, - struct vm_fault *vmf); + vm_fault_t (*vmfault)(struct kgsl_memdesc *memdesc, + struct vm_area_struct *vma, struct vm_fault *vmf); void (*free)(struct kgsl_memdesc *memdesc); int (*map_kernel)(struct kgsl_memdesc *memdesc); void (*unmap_kernel)(struct kgsl_memdesc *memdesc); diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c index f2914236fb21..c6d9536b947c 100644 --- a/drivers/gpu/msm/kgsl_gmu.c +++ b/drivers/gpu/msm/kgsl_gmu.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -559,7 +560,7 @@ static int gmu_dcvs_set(struct kgsl_device *device, struct rpmh_arc_vals { unsigned int num; - uint16_t val[MAX_GX_LEVELS]; + const u16 *val; }; static const char gfx_res_id[] = "gfx.lvl"; @@ -584,22 +585,9 @@ enum rpmh_vote_type { static int rpmh_arc_cmds(struct gmu_device *gmu, struct rpmh_arc_vals *arc, const char *res_id) { - unsigned int len; + size_t len = 0; - memset(arc, 0, sizeof(*arc)); - - len = cmd_db_read_aux_data_len(res_id); - if (len == 0) - return -EINVAL; - - if (len > (MAX_GX_LEVELS << 1)) { - dev_err(&gmu->pdev->dev, - "gfx cmddb size %d larger than alloc buf %d of %s\n", - len, (MAX_GX_LEVELS << 1), res_id); - return -EINVAL; - } - - cmd_db_read_aux_data(res_id, (uint8_t *)arc->val, len); + arc->val = cmd_db_read_aux_data(res_id, &len); /* * cmd_db_read_aux_data() gives us a zero-padded table of @@ -703,45 +691,22 @@ static int rpmh_arc_votes_init(struct kgsl_device *device, { unsigned int num_freqs; u16 vlvl_tbl[MAX_GX_LEVELS]; - unsigned int *freq_tbl; int i; - struct dev_pm_opp *opp; if (type == GMU_ARC_VOTE) return rpmh_gmu_arc_votes_init(gmu, pri_rail, sec_rail); num_freqs = gmu->num_gpupwrlevels; - freq_tbl = gmu->gpu_freqs; - if (num_freqs > pri_rail->num || num_freqs > MAX_GX_LEVELS) { + if (num_freqs > pri_rail->num) { dev_err(&gmu->pdev->dev, "Defined more GPU DCVS levels than RPMh can support\n"); return -EINVAL; } memset(vlvl_tbl, 0, sizeof(vlvl_tbl)); - - /* Get the values from OPP API */ - for (i = 0; i < num_freqs; i++) { - /* Hardcode VLVL 0 because it is not present in OPP */ - if (freq_tbl[i] == 0) { - vlvl_tbl[i] = 0; - continue; - } - - opp = dev_pm_opp_find_freq_exact(&device->pdev->dev, - freq_tbl[i], true); - - if (IS_ERR(opp)) { - dev_err(&gmu->pdev->dev, - "Failed to find opp freq %d for GPU\n", - freq_tbl[i]); - return PTR_ERR(opp); - } - - vlvl_tbl[i] = dev_pm_opp_get_voltage(opp); - dev_pm_opp_put(opp); - } + for (i = 0; i < num_freqs; i++) + vlvl_tbl[i] = gmu->pwrlevels[i].level; return setup_volt_dependency_tbl(gmu->rpmh_votes.gx_votes, pri_rail, sec_rail, vlvl_tbl, num_freqs); @@ -978,34 +943,6 @@ static int gmu_reg_probe(struct kgsl_device *device) return 0; } -static int gmu_clocks_probe(struct gmu_device *gmu, struct device_node *node) -{ - const char *cname; - struct property *prop; - struct clk *c; - int i = 0; - - of_property_for_each_string(node, "clock-names", prop, cname) { - c = devm_clk_get(&gmu->pdev->dev, cname); - - if (IS_ERR(c)) { - dev_err(&gmu->pdev->dev, - "dt: Couldn't get GMU clock: %s\n", cname); - return PTR_ERR(c); - } - - if (i >= MAX_GMU_CLKS) { - dev_err(&gmu->pdev->dev, - "dt: too many GMU clocks defined\n"); - return -EINVAL; - } - - gmu->clks[i++] = c; - } - - return 0; -} - static int gmu_regulators_probe(struct gmu_device *gmu, struct device_node *node) { @@ -1218,7 +1155,7 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) struct kgsl_hfi *hfi; struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); - int i = 0, ret = -ENXIO, index = 0; + int i = 0, ret = -ENXIO, index; gmu = kzalloc(sizeof(struct gmu_device), GFP_KERNEL); @@ -1242,11 +1179,20 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) if (ret) goto error; - /* Set up GMU clocks */ - ret = gmu_clocks_probe(gmu, node); - if (ret) + ret = devm_clk_bulk_get_all(&gmu->pdev->dev, &gmu->clks); + if (ret < 0) goto error; + gmu->num_clks = ret; + + /* Get a pointer to the GMU clock */ + gmu->gmu_clk = kgsl_of_clk_by_name(gmu->clks, gmu->num_clks, "gmu_clk"); + if (!gmu->gmu_clk) { + dev_err(&gmu->pdev->dev, "Couldn't get gmu_clk\n"); + ret = -ENODEV; + goto error; + } + /* Set up GMU IOMMU and shared memory with GMU */ ret = gmu_iommu_init(gmu, node); if (ret) @@ -1288,12 +1234,21 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) tasklet_init(&hfi->tasklet, hfi_receiver, (unsigned long) gmu); hfi->kgsldev = device; - /* Add a dummy level for "off" that the GMU expects */ - gmu->gpu_freqs[index++] = 0; + if (WARN(pwr->num_pwrlevels + 1 > ARRAY_SIZE(gmu->pwrlevels), + "Too many GPU powerlevels for the GMU HFI\n")) { + ret = -EINVAL; + goto error; + } + + /* Add a dummy level for "off" because the GMU expects it */ + gmu->pwrlevels[0].freq = 0; + gmu->pwrlevels[0].level = 0; /* GMU power levels are in ascending order */ - for (i = pwr->num_pwrlevels - 1; i >= 0; i--) - gmu->gpu_freqs[index++] = pwr->pwrlevels[i].gpu_freq; + for (index = 1, i = pwr->num_pwrlevels - 1; i >= 0; i--, index++) { + gmu->pwrlevels[index].freq = pwr->pwrlevels[i].gpu_freq; + gmu->pwrlevels[index].level = pwr->pwrlevels[i].voltage_level; + } gmu->num_gpupwrlevels = pwr->num_pwrlevels + 1; @@ -1331,48 +1286,30 @@ error: static int gmu_enable_clks(struct kgsl_device *device) { struct gmu_device *gmu = KGSL_GMU_DEVICE(device); - int ret, j = 0; + int ret; - if (IS_ERR_OR_NULL(gmu->clks[0])) - return -EINVAL; - - ret = clk_set_rate(gmu->clks[0], GMU_FREQUENCY); + ret = clk_set_rate(gmu->gmu_clk, GMU_FREQUENCY); if (ret) { - dev_err(&gmu->pdev->dev, "fail to set default GMU clk freq %d\n", - GMU_FREQUENCY); + dev_err(&gmu->pdev->dev, "Unable to set GMU clock\n"); return ret; } - while ((j < MAX_GMU_CLKS) && gmu->clks[j]) { - ret = clk_prepare_enable(gmu->clks[j]); - if (ret) { - dev_err(&gmu->pdev->dev, - "fail to enable gpucc clk idx %d\n", - j); - return ret; - } - j++; + ret = clk_bulk_prepare_enable(gmu->num_clks, gmu->clks); + if (ret) { + dev_err(&gmu->pdev->dev, "Cannot enable GMU clocks\n"); + return ret; } set_bit(GMU_CLK_ON, &device->gmu_core.flags); return 0; } -static int gmu_disable_clks(struct kgsl_device *device) +static void gmu_disable_clks(struct kgsl_device *device) { struct gmu_device *gmu = KGSL_GMU_DEVICE(device); - int j = 0; - - if (IS_ERR_OR_NULL(gmu->clks[0])) - return 0; - - while ((j < MAX_GMU_CLKS) && gmu->clks[j]) { - clk_disable_unprepare(gmu->clks[j]); - j++; - } + clk_bulk_disable_unprepare(gmu->num_clks, gmu->clks); clear_bit(GMU_CLK_ON, &device->gmu_core.flags); - return 0; } @@ -1619,7 +1556,6 @@ static void gmu_remove(struct kgsl_device *device) struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct gmu_device *gmu = KGSL_GMU_DEVICE(device); struct kgsl_hfi *hfi; - int i = 0; if (gmu == NULL || gmu->pdev == NULL) return; @@ -1635,11 +1571,6 @@ static void gmu_remove(struct kgsl_device *device) clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag); - while ((i < MAX_GMU_CLKS) && gmu->clks[i]) { - gmu->clks[i] = NULL; - i++; - } - icc_put(gmu->icc_path); if (gmu->fw_image) { @@ -1649,13 +1580,6 @@ static void gmu_remove(struct kgsl_device *device) gmu_memory_close(gmu); - for (i = 0; i < MAX_GMU_CLKS; i++) { - if (gmu->clks[i]) { - devm_clk_put(&gmu->pdev->dev, gmu->clks[i]); - gmu->clks[i] = NULL; - } - } - if (gmu->gx_gdsc) { devm_regulator_put(gmu->gx_gdsc); gmu->gx_gdsc = NULL; diff --git a/drivers/gpu/msm/kgsl_gmu.h b/drivers/gpu/msm/kgsl_gmu.h index 1db0bbef5463..3e539c02039e 100644 --- a/drivers/gpu/msm/kgsl_gmu.h +++ b/drivers/gpu/msm/kgsl_gmu.h @@ -158,7 +158,6 @@ struct icc_path; * @dump_mem: pointer to GMU debug dump memory * @gmu_log: gmu event log memory * @hfi: HFI controller - * @gpu_freqs: GPU frequency table with lowest freq at index 0 * @num_gpupwrlevels: number GPU frequencies in GPU freq table * @num_bwlevel: number of GPU BW levels * @num_cnocbwlevel: number CNOC BW levels @@ -194,14 +193,24 @@ struct gmu_device { struct gmu_memdesc *dump_mem; struct gmu_memdesc *gmu_log; struct kgsl_hfi hfi; - unsigned int gpu_freqs[MAX_GX_LEVELS]; + /** @pwrlevels: Array of GMU power levels */ + struct { + /** @freq: GPU frequency */ + unsigned long freq; + /** @level: Voltage level */ + u32 level; + } pwrlevels[MAX_GX_LEVELS]; unsigned int num_gpupwrlevels; unsigned int num_bwlevels; unsigned int num_cnocbwlevels; struct rpmh_votes_t rpmh_votes; struct regulator *cx_gdsc; struct regulator *gx_gdsc; - struct clk *clks[MAX_GMU_CLKS]; + struct clk_bulk_data *clks; + /** @num_clks: Number of entries in the @clks array */ + int num_clks; + /** @gmu_clk: Pointer to the core GMU clock */ + struct clk *gmu_clk; enum gmu_load_mode load_mode; unsigned int wakeup_pwrlevel; unsigned int pcl; diff --git a/drivers/gpu/msm/kgsl_gmu_core.h b/drivers/gpu/msm/kgsl_gmu_core.h index cf1225a2c2e6..eb2c26bad1d5 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.h +++ b/drivers/gpu/msm/kgsl_gmu_core.h @@ -21,8 +21,6 @@ #error "CNOC levels cannot exceed GX levels" #endif -#define MAX_GMU_CLKS 6 - /* * These are the different ways the GMU can boot. GMU_WARM_BOOT is waking up * from slumber. GMU_COLD_BOOT is booting for the first time. GMU_RESET diff --git a/drivers/gpu/msm/kgsl_hfi.c b/drivers/gpu/msm/kgsl_hfi.c index 864d1033248c..0ef1ec54e6ee 100644 --- a/drivers/gpu/msm/kgsl_hfi.c +++ b/drivers/gpu/msm/kgsl_hfi.c @@ -437,7 +437,7 @@ static int hfi_send_dcvstbl_v1(struct gmu_device *gmu) for (i = 0; i < gmu->num_gpupwrlevels; i++) { cmd.gx_votes[i].vote = gmu->rpmh_votes.gx_votes[i]; /* Divide by 1000 to convert to kHz */ - cmd.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000; + cmd.gx_votes[i].freq = gmu->pwrlevels[i].freq / 1000; } cmd.cx_votes[0].vote = gmu->rpmh_votes.cx_votes[0]; @@ -483,7 +483,7 @@ static int hfi_send_dcvstbl(struct gmu_device *gmu) /* Hardcode this to the max threshold since it is not used */ cmd.gx_votes[i].acd = 0xFFFFFFFF; /* Divide by 1000 to convert to kHz */ - cmd.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000; + cmd.gx_votes[i].freq = gmu->pwrlevels[i].freq / 1000; } cmd.cx_votes[0].vote = gmu->rpmh_votes.cx_votes[0]; diff --git a/drivers/gpu/msm/kgsl_pool.c b/drivers/gpu/msm/kgsl_pool.c index 00a6466704c5..c7b440f0f342 100644 --- a/drivers/gpu/msm/kgsl_pool.c +++ b/drivers/gpu/msm/kgsl_pool.c @@ -100,7 +100,7 @@ _kgsl_pool_add_page(struct kgsl_page_pool *pool, struct page *p) list_add_tail(&p->lru, &pool->page_list); pool->page_count++; spin_unlock(&pool->list_lock); - mod_node_page_state(page_pgdat(p), NR_INDIRECTLY_RECLAIMABLE_BYTES, + mod_node_page_state(page_pgdat(p), NR_KERNEL_MISC_RECLAIMABLE, (PAGE_SIZE << pool->pool_order)); } @@ -117,7 +117,7 @@ _kgsl_pool_get_page(struct kgsl_page_pool *pool) list_del(&p->lru); } spin_unlock(&pool->list_lock); - mod_node_page_state(page_pgdat(p), NR_INDIRECTLY_RECLAIMABLE_BYTES, + mod_node_page_state(page_pgdat(p), NR_KERNEL_MISC_RECLAIMABLE, -(PAGE_SIZE << pool->pool_order)); return p; } @@ -256,20 +256,12 @@ void kgsl_pool_free_pages(struct page **pages, unsigned int pcount) if (!pages) return; - if (WARN(!kern_addr_valid((unsigned long)pages), - "Address of pages=%pK is not valid\n", pages)) - return; - for (i = 0; i < pcount;) { /* * Free each page or compound page group individually. */ struct page *p = pages[i]; - if (WARN(!kern_addr_valid((unsigned long)p), - "Address of page=%pK is not valid\n", p)) - return; - i += 1 << compound_order(p); kgsl_pool_free_page(p); } diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index b35b9c49d0aa..1468bbabc570 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -1584,43 +1584,6 @@ static int kgsl_pwrctrl_clk_set_rate(struct clk *grp_clk, unsigned int freq, return ret; } -static bool _gpu_freq_supported(struct kgsl_pwrctrl *pwr, unsigned int freq) -{ - int i; - - for (i = pwr->num_pwrlevels - 1; i >= 0; i--) { - if (pwr->pwrlevels[i].gpu_freq == freq) - return true; - } - - return false; -} - -void kgsl_pwrctrl_disable_unused_opp(struct kgsl_device *device, - struct device *dev) -{ - struct dev_pm_opp *opp; - unsigned long freq = 0; - int ret; - - ret = dev_pm_opp_get_opp_count(dev); - /* Return early, If no OPP table or OPP count is zero */ - if (ret <= 0) - return; - - while (1) { - opp = dev_pm_opp_find_freq_ceil(dev, &freq); - if (IS_ERR(opp)) - break; - - if (!_gpu_freq_supported(&device->pwrctrl, freq)) - dev_pm_opp_disable(dev, freq); - - dev_pm_opp_put(opp); - freq++; - } -} - static u32 *kgsl_bus_get_table(struct platform_device *pdev, int *count) { u32 *levels; @@ -1702,8 +1665,6 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) pwr->pwrlevels[i].gpu_freq = freq; } - kgsl_pwrctrl_disable_unused_opp(device, &pdev->dev); - kgsl_clk_set_rate(device, pwr->num_pwrlevels - 1); freq = clk_round_rate(pwr->grp_clks[6], KGSL_RBBMTIMER_CLK_FREQ); diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h index 894b4de212b5..7d2ca5d45195 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.h +++ b/drivers/gpu/msm/kgsl_pwrctrl.h @@ -69,6 +69,8 @@ struct kgsl_pwrlevel { unsigned int bus_min; unsigned int bus_max; unsigned int acd_level; + /** @voltage_level: Voltage level used by the GMU to vote RPMh */ + u32 voltage_level; }; /** @@ -196,7 +198,5 @@ void kgsl_pwrctrl_busy_time(struct kgsl_device *device, u64 time, u64 busy); void kgsl_pwrctrl_set_constraint(struct kgsl_device *device, struct kgsl_pwr_constraint *pwrc, uint32_t id); int kgsl_pwrctrl_set_default_gpu_pwrlevel(struct kgsl_device *device); -void kgsl_pwrctrl_disable_unused_opp(struct kgsl_device *device, - struct device *dev); #endif /* __KGSL_PWRCTRL_H */ diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 35b635260c10..bebdda88ef3f 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -357,32 +357,15 @@ kgsl_sharedmem_init_sysfs(void) return sysfs_create_files(&kgsl_driver.virtdev.kobj, drv_attr_list); } -static int kgsl_paged_vmfault(struct kgsl_memdesc *memdesc, +static vm_fault_t kgsl_paged_vmfault(struct kgsl_memdesc *memdesc, struct vm_area_struct *vma, struct vm_fault *vmf) { int pgoff; - unsigned int offset; - offset = vmf->address - vma->vm_start; + pgoff = (vmf->address - vma->vm_start) >> PAGE_SHIFT; - if (offset >= memdesc->size) - return VM_FAULT_SIGBUS; - - pgoff = offset >> PAGE_SHIFT; - - if (pgoff < memdesc->page_count) { - struct page *page = memdesc->pages[pgoff]; - - get_page(page); - vmf->page = page; - - memdesc->mapsize += PAGE_SIZE; - - return 0; - } - - return VM_FAULT_SIGBUS; + return vmf_insert_page(vma, vmf->address, memdesc->pages[pgoff]); } static void kgsl_paged_unmap_kernel(struct kgsl_memdesc *memdesc) @@ -495,27 +478,17 @@ static int kgsl_paged_map_kernel(struct kgsl_memdesc *memdesc) return ret; } -static int kgsl_contiguous_vmfault(struct kgsl_memdesc *memdesc, +static vm_fault_t kgsl_contiguous_vmfault(struct kgsl_memdesc *memdesc, struct vm_area_struct *vma, struct vm_fault *vmf) { unsigned long offset, pfn; - int ret; offset = ((unsigned long) vmf->address - vma->vm_start) >> PAGE_SHIFT; pfn = (memdesc->physaddr >> PAGE_SHIFT) + offset; - ret = vm_insert_pfn(vma, (unsigned long) vmf->address, pfn); - - if (ret == -ENOMEM || ret == -EAGAIN) - return VM_FAULT_OOM; - else if (ret == -EFAULT) - return VM_FAULT_SIGBUS; - - memdesc->mapsize += PAGE_SIZE; - - return VM_FAULT_NOPAGE; + return vmf_insert_pfn(vma, vmf->address, pfn); } #ifdef CONFIG_ARM64 @@ -1054,7 +1027,7 @@ static struct kgsl_memdesc_ops kgsl_secure_pool_ops = { static struct kgsl_memdesc_ops kgsl_pool_ops = { .free = kgsl_free_pool_pages, - .vmflags = VM_DONTDUMP | VM_DONTEXPAND | VM_DONTCOPY, + .vmflags = VM_DONTDUMP | VM_DONTEXPAND | VM_DONTCOPY | VM_MIXEDMAP, .vmfault = kgsl_paged_vmfault, .map_kernel = kgsl_paged_map_kernel, .unmap_kernel = kgsl_paged_unmap_kernel, diff --git a/drivers/gpu/msm/kgsl_util.c b/drivers/gpu/msm/kgsl_util.c index 5a0b4a1baa8e..fbee7a5ace33 100644 --- a/drivers/gpu/msm/kgsl_util.c +++ b/drivers/gpu/msm/kgsl_util.c @@ -3,9 +3,13 @@ * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ + +#include +#include #include #include #include +#include #include "kgsl_util.h" @@ -25,3 +29,15 @@ bool kgsl_regulator_disable_wait(struct regulator *reg, u32 timeout) usleep_range((100 >> 2) + 1, 100); } } + +struct clk *kgsl_of_clk_by_name(struct clk_bulk_data *clks, int count, + const char *id) +{ + int i; + + for (i = 0; clks && i < count; i++) + if (!strcmp(clks[i].id, id)) + return clks[i].clk; + + return NULL; +} diff --git a/drivers/gpu/msm/kgsl_util.h b/drivers/gpu/msm/kgsl_util.h index 403481cbdf26..839c04ffc44d 100644 --- a/drivers/gpu/msm/kgsl_util.h +++ b/drivers/gpu/msm/kgsl_util.h @@ -7,6 +7,7 @@ #define _KGSL_UTIL_H_ struct regulator; +struct clk_bulk_data; /** * kgsl_regulator_disable_wait - Disable a regulator and wait for it @@ -20,4 +21,15 @@ struct regulator; */ bool kgsl_regulator_disable_wait(struct regulator *reg, u32 timeout); +/** + * kgsl_of_clk_by_name - Return a clock device for a given name + * @clks: Pointer to an array of bulk clk data + * @count: Number of entries in the array + * @id: Name of the clock to search for + * + * Returns: A pointer to the clock device for the given name or NULL if not + * found + */ +struct clk *kgsl_of_clk_by_name(struct clk_bulk_data *clks, int count, + const char *id); #endif