Loading drivers/gpu/msm/adreno.c +81 −21 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ /* * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. */ #include <linux/component.h> #include <linux/delay.h> #include <linux/firmware.h> #include <linux/input.h> Loading Loading @@ -1415,8 +1416,9 @@ static void adreno_setup_device(struct adreno_device *adreno_dev) } } static int adreno_probe(struct platform_device *pdev) static int adreno_bind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); const struct of_device_id *of_id; struct adreno_device *adreno_dev; struct kgsl_device *device; Loading @@ -1435,6 +1437,8 @@ static int adreno_probe(struct platform_device *pdev) device = KGSL_DEVICE(adreno_dev); dev_set_drvdata(dev, device); device->pdev = pdev; if (adreno_is_gpu_disabled(adreno_dev)) { Loading Loading @@ -1462,19 +1466,16 @@ static int adreno_probe(struct platform_device *pdev) } status = kgsl_bus_init(device, pdev); if (status) { device->pdev = NULL; return status; } if (status) goto err; /* * Probe/init GMU after initial gpu power probe * Another part of GPU power probe in platform_probe * needs GMU initialized. * Bind the GMU components (if applicable) before doing the KGSL * platform probe */ status = gmu_core_probe(device); status = component_bind_all(dev, NULL); if (status) { device->pdev = NULL; kgsl_bus_close(device); return status; } Loading @@ -1492,10 +1493,8 @@ static int adreno_probe(struct platform_device *pdev) ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)); status = kgsl_device_platform_probe(device); if (status) { device->pdev = NULL; return status; } if (status) goto err; /* Probe for the optional CX_DBGC block */ adreno_cx_dbgc_probe(device); Loading @@ -1521,8 +1520,7 @@ static int adreno_probe(struct platform_device *pdev) status = PTR_ERR_OR_ZERO(device->memstore); if (status) { kgsl_device_platform_remove(device); device->pdev = NULL; return status; goto err; } /* Initialize the snapshot engine */ Loading Loading @@ -1580,6 +1578,13 @@ static int adreno_probe(struct platform_device *pdev) #endif return 0; err: device->pdev = NULL; component_unbind_all(dev, NULL); kgsl_bus_close(device); return status; } static void _adreno_free_memories(struct adreno_device *adreno_dev) Loading @@ -1598,8 +1603,9 @@ static void _adreno_free_memories(struct adreno_device *adreno_dev) adreno_dev->gpmu_cmds = NULL; } static int adreno_remove(struct platform_device *pdev) static void adreno_unbind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); const struct of_device_id *of_id; struct adreno_device *adreno_dev; struct kgsl_device *device; Loading @@ -1607,7 +1613,7 @@ static int adreno_remove(struct platform_device *pdev) of_id = of_match_device(adreno_match_table, &pdev->dev); if (!of_id) return -EINVAL; return; adreno_dev = (struct adreno_device *) of_id->data; device = KGSL_DEVICE(adreno_dev); Loading Loading @@ -1653,12 +1659,10 @@ static int adreno_remove(struct platform_device *pdev) kgsl_device_platform_remove(device); gmu_core_remove(device); component_unbind_all(dev, NULL); clear_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv); clear_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv); return 0; } static int adreno_pm_resume(struct device *dev) Loading Loading @@ -3882,6 +3886,60 @@ static const struct kgsl_functable adreno_functable = { .is_hwcg_on = adreno_is_hwcg_on, }; static const struct component_master_ops adreno_ops = { .bind = adreno_bind, .unbind = adreno_unbind, }; static const struct of_device_id adreno_gmu_match[] = { { .compatible = "qcom,gpu-gmu" }, { .compatible = "qcom,gpu-rgmu" }, {}, }; static int _compare_of(struct device *dev, void *data) { return (dev->of_node == data); } static void _release_of(struct device *dev, void *data) { of_node_put(data); } static void adreno_add_gmu_components(struct device *dev, struct component_match **match) { struct device_node *node; node = of_find_matching_node(NULL, adreno_gmu_match); if (!node) return; if (!of_device_is_available(node)) { of_node_put(node); return; } component_match_add_release(dev, match, _release_of, _compare_of, node); } static int adreno_probe(struct platform_device *pdev) { struct component_match *match = NULL; adreno_add_gmu_components(&pdev->dev, &match); return component_master_add_with_match(&pdev->dev, &adreno_ops, match); } static int adreno_remove(struct platform_device *pdev) { component_master_del(&pdev->dev, &adreno_ops); return 0; } static const struct dev_pm_ops adreno_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(adreno_pm_suspend, adreno_pm_resume) }; Loading @@ -3905,6 +3963,7 @@ static int __init kgsl_3d_init(void) if (ret) return ret; gmu_core_register(); ret = platform_driver_register(&adreno_platform_driver); if (ret) kgsl_core_exit(); Loading @@ -3915,6 +3974,7 @@ static int __init kgsl_3d_init(void) static void __exit kgsl_3d_exit(void) { platform_driver_unregister(&adreno_platform_driver); gmu_core_unregister(); kgsl_core_exit(); } Loading drivers/gpu/msm/kgsl.c +0 −2 Original line number Diff line number Diff line Loading @@ -4776,8 +4776,6 @@ static int _register_device(struct kgsl_device *device) device->dev->dma_mask = &dma_mask; set_dma_ops(device->dev, NULL); dev_set_drvdata(&device->pdev->dev, device); return 0; } Loading drivers/gpu/msm/kgsl_bus.c +2 −7 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ u32 *kgsl_bus_get_table(struct platform_device *pdev, if (num <= 0) return ERR_PTR(-EINVAL); levels = kcalloc(num, sizeof(*levels), GFP_KERNEL); levels = devm_kcalloc(&pdev->dev, num, sizeof(*levels), GFP_KERNEL); if (!levels) return ERR_PTR(-ENOMEM); Loading Loading @@ -172,10 +172,5 @@ int kgsl_bus_init(struct kgsl_device *device, struct platform_device *pdev) void kgsl_bus_close(struct kgsl_device *device) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; kfree(pwr->ddr_table); /* FIXME: Make sure icc put can handle NULL or IS_ERR */ icc_put(pwr->icc_path); icc_put(device->pwrctrl.icc_path); } drivers/gpu/msm/kgsl_gmu.c +64 −40 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #include <dt-bindings/regulator/qcom,rpmh-regulator-levels.h> #include <linux/clk.h> #include <linux/component.h> #include <linux/delay.h> #include <linux/firmware.h> #include <linux/interconnect.h> Loading Loading @@ -945,7 +946,7 @@ static int gmu_bus_vote_init(struct kgsl_device *device) if (count > 0) cnoc = build_rpmh_bw_votes(a660_cnoc_bcms, ARRAY_SIZE(a660_cnoc_bcms), cnoc_table, count); kfree(cnoc_table); devm_kfree(&device->pdev->dev, cnoc_table); if (IS_ERR(cnoc)) { free_rpmh_bw_votes(ddr); Loading Loading @@ -1296,8 +1297,9 @@ static int gmu_bus_set(struct kgsl_device *device, int buslevel, return ret; } /* Do not access any GMU registers in GMU probe function */ static int gmu_probe(struct kgsl_device *device, struct device_node *node) static struct gmu_core_ops gmu_ops; static int gmu_probe(struct kgsl_device *device, struct platform_device *pdev) { struct gmu_device *gmu; struct kgsl_hfi *hfi; Loading @@ -1305,35 +1307,28 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int i = 0, ret = -ENXIO, index; gmu = kzalloc(sizeof(struct gmu_device), GFP_KERNEL); if (gmu == NULL) gmu = devm_kzalloc(&pdev->dev, sizeof(*gmu), GFP_KERNEL); if (!gmu) return -ENOMEM; gmu->pdev = of_find_device_by_node(node); if (!gmu->pdev) { kfree(gmu); return -EINVAL; } gmu->pdev = pdev; device->gmu_core.ptr = (void *)gmu; hfi = &gmu->hfi; gmu->load_mode = TCM_BOOT; of_dma_configure(&gmu->pdev->dev, node, true); dma_set_coherent_mask(&gmu->pdev->dev, DMA_BIT_MASK(64)); gmu->pdev->dev.dma_mask = &gmu->pdev->dev.coherent_dma_mask; set_dma_ops(&gmu->pdev->dev, NULL); /* Set up GMU regulators */ ret = gmu_regulators_probe(gmu, node); ret = gmu_regulators_probe(gmu, pdev->dev.of_node); if (ret) goto error; return ret; ret = devm_clk_bulk_get_all(&gmu->pdev->dev, &gmu->clks); if (ret < 0) goto error; return ret; gmu->num_clks = ret; Loading @@ -1341,12 +1336,11 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) 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; return -ENODEV; } /* Set up GMU IOMMU and shared memory with GMU */ ret = gmu_iommu_init(gmu, node); ret = gmu_iommu_init(gmu, pdev->dev.of_node); if (ret) goto error; Loading Loading @@ -1421,12 +1415,14 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) else gmu->idle_level = GPU_HW_ACTIVE; gmu_acd_probe(device, gmu, node); gmu_acd_probe(device, gmu, pdev->dev.of_node); if (gmu_core_scales_bandwidth(device)) pwr->bus_set = gmu_bus_set; set_bit(GMU_ENABLED, &device->gmu_core.flags); device->gmu_core.core_ops = &gmu_ops; device->gmu_core.dev_ops = &adreno_a6xx_gmudev; return 0; Loading Loading @@ -1729,27 +1725,12 @@ static void gmu_remove(struct kgsl_device *device) clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag); if (gmu->fw_image) { if (gmu->fw_image) release_firmware(gmu->fw_image); gmu->fw_image = NULL; } gmu_memory_close(gmu); if (gmu->gx_gdsc) { devm_regulator_put(gmu->gx_gdsc); gmu->gx_gdsc = NULL; } if (gmu->cx_gdsc) { devm_regulator_put(gmu->cx_gdsc); gmu->cx_gdsc = NULL; } device->gmu_core.flags = 0; device->gmu_core.ptr = NULL; gmu->pdev = NULL; kfree(gmu); memset(&device->gmu_core, 0, sizeof(device->gmu_core)); } static bool gmu_regulator_isenabled(struct kgsl_device *device) Loading @@ -1759,9 +1740,7 @@ static bool gmu_regulator_isenabled(struct kgsl_device *device) return (gmu->gx_gdsc && regulator_is_enabled(gmu->gx_gdsc)); } struct gmu_core_ops gmu_ops = { .probe = gmu_probe, .remove = gmu_remove, static struct gmu_core_ops gmu_ops = { .init = gmu_init, .start = gmu_start, .stop = gmu_stop, Loading @@ -1771,3 +1750,48 @@ struct gmu_core_ops gmu_ops = { .suspend = gmu_suspend, .acd_set = gmu_acd_set, }; static int kgsl_gmu_bind(struct device *dev, struct device *master, void *data) { struct kgsl_device *device = dev_get_drvdata(master); return gmu_probe(device, to_platform_device(dev)); } static void kgsl_gmu_unbind(struct device *dev, struct device *master, void *data) { struct kgsl_device *device = dev_get_drvdata(master); gmu_remove(device); } static const struct component_ops kgsl_gmu_ops = { .bind = kgsl_gmu_bind, .unbind = kgsl_gmu_unbind, }; static int kgsl_gmu_probe(struct platform_device *pdev) { return component_add(&pdev->dev, &kgsl_gmu_ops); } static int kgsl_gmu_remove(struct platform_device *pdev) { component_del(&pdev->dev, &kgsl_gmu_ops); return 0; } static const struct of_device_id kgsl_gmu_match_table[] = { { .compatible = "qcom,gpu-gmu" }, { }, }; struct platform_driver kgsl_gmu_driver = { .probe = kgsl_gmu_probe, .remove = kgsl_gmu_remove, .driver = { .name = "kgsl-gmu", .of_match_table = kgsl_gmu_match_table, }, }; drivers/gpu/msm/kgsl_gmu_core.c +25 −46 Original line number Diff line number Diff line Loading @@ -10,13 +10,10 @@ #include "kgsl_gmu_core.h" #include "kgsl_trace.h" static const struct { char *compat; struct gmu_core_ops *core_ops; enum gmu_coretype type; } gmu_subtypes[] = { {"qcom,gpu-gmu", &gmu_ops, GMU_CORE_TYPE_CM3}, {"qcom,gpu-rgmu", &rgmu_ops, GMU_CORE_TYPE_PCC}, static const struct of_device_id gmu_match_table[] = { { .compatible = "qcom,gpu-gmu", .data = &kgsl_gmu_driver }, { .compatible = "qcom,gpu-rgmu", .data = &kgsl_rgmu_driver }, {}, }; struct oob_entry { Loading @@ -40,50 +37,32 @@ const char *gmu_core_oob_type_str(enum oob_request req) return "UNKNOWN"; } int gmu_core_probe(struct kgsl_device *device) void __init gmu_core_register(void) { const struct of_device_id *match; struct device_node *node; struct gmu_core_ops *gmu_core_ops; int i = 0, ret = -ENXIO; device->gmu_core.flags = ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_GPMU) ? BIT(GMU_GPMU) : 0; for (i = 0; i < ARRAY_SIZE(gmu_subtypes); i++) { node = of_find_compatible_node(device->pdev->dev.of_node, NULL, gmu_subtypes[i].compat); if (node != NULL) { gmu_core_ops = gmu_subtypes[i].core_ops; device->gmu_core.type = gmu_subtypes[i].type; break; } } /* No GMU in dt, no worries...hopefully */ if (node == NULL) { /* If we are trying to use GPMU and no GMU, that's bad */ if (device->gmu_core.flags & BIT(GMU_GPMU)) return ret; /* Otherwise it's ok and nothing to do */ return 0; } if (gmu_core_ops && gmu_core_ops->probe) { ret = gmu_core_ops->probe(device, node); if (ret == 0) device->gmu_core.core_ops = gmu_core_ops; } node = of_find_matching_node_and_match(NULL, gmu_match_table, &match); if (!node) return; return ret; platform_driver_register((struct platform_driver *) match->data); of_node_put(node); } void gmu_core_remove(struct kgsl_device *device) void __exit gmu_core_unregister(void) { struct gmu_core_ops *gmu_core_ops = GMU_CORE_OPS(device); const struct of_device_id *match; struct device_node *node; node = of_find_matching_node_and_match(NULL, gmu_match_table, &match); if (!node) return; if (gmu_core_ops && gmu_core_ops->remove) gmu_core_ops->remove(device); platform_driver_unregister((struct platform_driver *) match->data); of_node_put(node); } bool gmu_core_isenabled(struct kgsl_device *device) Loading @@ -93,7 +72,7 @@ bool gmu_core_isenabled(struct kgsl_device *device) bool gmu_core_gpmu_isenabled(struct kgsl_device *device) { return test_bit(GMU_GPMU, &device->gmu_core.flags); return (device->gmu_core.core_ops != NULL); } bool gmu_core_scales_bandwidth(struct kgsl_device *device) Loading Loading
drivers/gpu/msm/adreno.c +81 −21 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ /* * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. */ #include <linux/component.h> #include <linux/delay.h> #include <linux/firmware.h> #include <linux/input.h> Loading Loading @@ -1415,8 +1416,9 @@ static void adreno_setup_device(struct adreno_device *adreno_dev) } } static int adreno_probe(struct platform_device *pdev) static int adreno_bind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); const struct of_device_id *of_id; struct adreno_device *adreno_dev; struct kgsl_device *device; Loading @@ -1435,6 +1437,8 @@ static int adreno_probe(struct platform_device *pdev) device = KGSL_DEVICE(adreno_dev); dev_set_drvdata(dev, device); device->pdev = pdev; if (adreno_is_gpu_disabled(adreno_dev)) { Loading Loading @@ -1462,19 +1466,16 @@ static int adreno_probe(struct platform_device *pdev) } status = kgsl_bus_init(device, pdev); if (status) { device->pdev = NULL; return status; } if (status) goto err; /* * Probe/init GMU after initial gpu power probe * Another part of GPU power probe in platform_probe * needs GMU initialized. * Bind the GMU components (if applicable) before doing the KGSL * platform probe */ status = gmu_core_probe(device); status = component_bind_all(dev, NULL); if (status) { device->pdev = NULL; kgsl_bus_close(device); return status; } Loading @@ -1492,10 +1493,8 @@ static int adreno_probe(struct platform_device *pdev) ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)); status = kgsl_device_platform_probe(device); if (status) { device->pdev = NULL; return status; } if (status) goto err; /* Probe for the optional CX_DBGC block */ adreno_cx_dbgc_probe(device); Loading @@ -1521,8 +1520,7 @@ static int adreno_probe(struct platform_device *pdev) status = PTR_ERR_OR_ZERO(device->memstore); if (status) { kgsl_device_platform_remove(device); device->pdev = NULL; return status; goto err; } /* Initialize the snapshot engine */ Loading Loading @@ -1580,6 +1578,13 @@ static int adreno_probe(struct platform_device *pdev) #endif return 0; err: device->pdev = NULL; component_unbind_all(dev, NULL); kgsl_bus_close(device); return status; } static void _adreno_free_memories(struct adreno_device *adreno_dev) Loading @@ -1598,8 +1603,9 @@ static void _adreno_free_memories(struct adreno_device *adreno_dev) adreno_dev->gpmu_cmds = NULL; } static int adreno_remove(struct platform_device *pdev) static void adreno_unbind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); const struct of_device_id *of_id; struct adreno_device *adreno_dev; struct kgsl_device *device; Loading @@ -1607,7 +1613,7 @@ static int adreno_remove(struct platform_device *pdev) of_id = of_match_device(adreno_match_table, &pdev->dev); if (!of_id) return -EINVAL; return; adreno_dev = (struct adreno_device *) of_id->data; device = KGSL_DEVICE(adreno_dev); Loading Loading @@ -1653,12 +1659,10 @@ static int adreno_remove(struct platform_device *pdev) kgsl_device_platform_remove(device); gmu_core_remove(device); component_unbind_all(dev, NULL); clear_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv); clear_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv); return 0; } static int adreno_pm_resume(struct device *dev) Loading Loading @@ -3882,6 +3886,60 @@ static const struct kgsl_functable adreno_functable = { .is_hwcg_on = adreno_is_hwcg_on, }; static const struct component_master_ops adreno_ops = { .bind = adreno_bind, .unbind = adreno_unbind, }; static const struct of_device_id adreno_gmu_match[] = { { .compatible = "qcom,gpu-gmu" }, { .compatible = "qcom,gpu-rgmu" }, {}, }; static int _compare_of(struct device *dev, void *data) { return (dev->of_node == data); } static void _release_of(struct device *dev, void *data) { of_node_put(data); } static void adreno_add_gmu_components(struct device *dev, struct component_match **match) { struct device_node *node; node = of_find_matching_node(NULL, adreno_gmu_match); if (!node) return; if (!of_device_is_available(node)) { of_node_put(node); return; } component_match_add_release(dev, match, _release_of, _compare_of, node); } static int adreno_probe(struct platform_device *pdev) { struct component_match *match = NULL; adreno_add_gmu_components(&pdev->dev, &match); return component_master_add_with_match(&pdev->dev, &adreno_ops, match); } static int adreno_remove(struct platform_device *pdev) { component_master_del(&pdev->dev, &adreno_ops); return 0; } static const struct dev_pm_ops adreno_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(adreno_pm_suspend, adreno_pm_resume) }; Loading @@ -3905,6 +3963,7 @@ static int __init kgsl_3d_init(void) if (ret) return ret; gmu_core_register(); ret = platform_driver_register(&adreno_platform_driver); if (ret) kgsl_core_exit(); Loading @@ -3915,6 +3974,7 @@ static int __init kgsl_3d_init(void) static void __exit kgsl_3d_exit(void) { platform_driver_unregister(&adreno_platform_driver); gmu_core_unregister(); kgsl_core_exit(); } Loading
drivers/gpu/msm/kgsl.c +0 −2 Original line number Diff line number Diff line Loading @@ -4776,8 +4776,6 @@ static int _register_device(struct kgsl_device *device) device->dev->dma_mask = &dma_mask; set_dma_ops(device->dev, NULL); dev_set_drvdata(&device->pdev->dev, device); return 0; } Loading
drivers/gpu/msm/kgsl_bus.c +2 −7 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ u32 *kgsl_bus_get_table(struct platform_device *pdev, if (num <= 0) return ERR_PTR(-EINVAL); levels = kcalloc(num, sizeof(*levels), GFP_KERNEL); levels = devm_kcalloc(&pdev->dev, num, sizeof(*levels), GFP_KERNEL); if (!levels) return ERR_PTR(-ENOMEM); Loading Loading @@ -172,10 +172,5 @@ int kgsl_bus_init(struct kgsl_device *device, struct platform_device *pdev) void kgsl_bus_close(struct kgsl_device *device) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; kfree(pwr->ddr_table); /* FIXME: Make sure icc put can handle NULL or IS_ERR */ icc_put(pwr->icc_path); icc_put(device->pwrctrl.icc_path); }
drivers/gpu/msm/kgsl_gmu.c +64 −40 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #include <dt-bindings/regulator/qcom,rpmh-regulator-levels.h> #include <linux/clk.h> #include <linux/component.h> #include <linux/delay.h> #include <linux/firmware.h> #include <linux/interconnect.h> Loading Loading @@ -945,7 +946,7 @@ static int gmu_bus_vote_init(struct kgsl_device *device) if (count > 0) cnoc = build_rpmh_bw_votes(a660_cnoc_bcms, ARRAY_SIZE(a660_cnoc_bcms), cnoc_table, count); kfree(cnoc_table); devm_kfree(&device->pdev->dev, cnoc_table); if (IS_ERR(cnoc)) { free_rpmh_bw_votes(ddr); Loading Loading @@ -1296,8 +1297,9 @@ static int gmu_bus_set(struct kgsl_device *device, int buslevel, return ret; } /* Do not access any GMU registers in GMU probe function */ static int gmu_probe(struct kgsl_device *device, struct device_node *node) static struct gmu_core_ops gmu_ops; static int gmu_probe(struct kgsl_device *device, struct platform_device *pdev) { struct gmu_device *gmu; struct kgsl_hfi *hfi; Loading @@ -1305,35 +1307,28 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int i = 0, ret = -ENXIO, index; gmu = kzalloc(sizeof(struct gmu_device), GFP_KERNEL); if (gmu == NULL) gmu = devm_kzalloc(&pdev->dev, sizeof(*gmu), GFP_KERNEL); if (!gmu) return -ENOMEM; gmu->pdev = of_find_device_by_node(node); if (!gmu->pdev) { kfree(gmu); return -EINVAL; } gmu->pdev = pdev; device->gmu_core.ptr = (void *)gmu; hfi = &gmu->hfi; gmu->load_mode = TCM_BOOT; of_dma_configure(&gmu->pdev->dev, node, true); dma_set_coherent_mask(&gmu->pdev->dev, DMA_BIT_MASK(64)); gmu->pdev->dev.dma_mask = &gmu->pdev->dev.coherent_dma_mask; set_dma_ops(&gmu->pdev->dev, NULL); /* Set up GMU regulators */ ret = gmu_regulators_probe(gmu, node); ret = gmu_regulators_probe(gmu, pdev->dev.of_node); if (ret) goto error; return ret; ret = devm_clk_bulk_get_all(&gmu->pdev->dev, &gmu->clks); if (ret < 0) goto error; return ret; gmu->num_clks = ret; Loading @@ -1341,12 +1336,11 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) 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; return -ENODEV; } /* Set up GMU IOMMU and shared memory with GMU */ ret = gmu_iommu_init(gmu, node); ret = gmu_iommu_init(gmu, pdev->dev.of_node); if (ret) goto error; Loading Loading @@ -1421,12 +1415,14 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node) else gmu->idle_level = GPU_HW_ACTIVE; gmu_acd_probe(device, gmu, node); gmu_acd_probe(device, gmu, pdev->dev.of_node); if (gmu_core_scales_bandwidth(device)) pwr->bus_set = gmu_bus_set; set_bit(GMU_ENABLED, &device->gmu_core.flags); device->gmu_core.core_ops = &gmu_ops; device->gmu_core.dev_ops = &adreno_a6xx_gmudev; return 0; Loading Loading @@ -1729,27 +1725,12 @@ static void gmu_remove(struct kgsl_device *device) clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag); if (gmu->fw_image) { if (gmu->fw_image) release_firmware(gmu->fw_image); gmu->fw_image = NULL; } gmu_memory_close(gmu); if (gmu->gx_gdsc) { devm_regulator_put(gmu->gx_gdsc); gmu->gx_gdsc = NULL; } if (gmu->cx_gdsc) { devm_regulator_put(gmu->cx_gdsc); gmu->cx_gdsc = NULL; } device->gmu_core.flags = 0; device->gmu_core.ptr = NULL; gmu->pdev = NULL; kfree(gmu); memset(&device->gmu_core, 0, sizeof(device->gmu_core)); } static bool gmu_regulator_isenabled(struct kgsl_device *device) Loading @@ -1759,9 +1740,7 @@ static bool gmu_regulator_isenabled(struct kgsl_device *device) return (gmu->gx_gdsc && regulator_is_enabled(gmu->gx_gdsc)); } struct gmu_core_ops gmu_ops = { .probe = gmu_probe, .remove = gmu_remove, static struct gmu_core_ops gmu_ops = { .init = gmu_init, .start = gmu_start, .stop = gmu_stop, Loading @@ -1771,3 +1750,48 @@ struct gmu_core_ops gmu_ops = { .suspend = gmu_suspend, .acd_set = gmu_acd_set, }; static int kgsl_gmu_bind(struct device *dev, struct device *master, void *data) { struct kgsl_device *device = dev_get_drvdata(master); return gmu_probe(device, to_platform_device(dev)); } static void kgsl_gmu_unbind(struct device *dev, struct device *master, void *data) { struct kgsl_device *device = dev_get_drvdata(master); gmu_remove(device); } static const struct component_ops kgsl_gmu_ops = { .bind = kgsl_gmu_bind, .unbind = kgsl_gmu_unbind, }; static int kgsl_gmu_probe(struct platform_device *pdev) { return component_add(&pdev->dev, &kgsl_gmu_ops); } static int kgsl_gmu_remove(struct platform_device *pdev) { component_del(&pdev->dev, &kgsl_gmu_ops); return 0; } static const struct of_device_id kgsl_gmu_match_table[] = { { .compatible = "qcom,gpu-gmu" }, { }, }; struct platform_driver kgsl_gmu_driver = { .probe = kgsl_gmu_probe, .remove = kgsl_gmu_remove, .driver = { .name = "kgsl-gmu", .of_match_table = kgsl_gmu_match_table, }, };
drivers/gpu/msm/kgsl_gmu_core.c +25 −46 Original line number Diff line number Diff line Loading @@ -10,13 +10,10 @@ #include "kgsl_gmu_core.h" #include "kgsl_trace.h" static const struct { char *compat; struct gmu_core_ops *core_ops; enum gmu_coretype type; } gmu_subtypes[] = { {"qcom,gpu-gmu", &gmu_ops, GMU_CORE_TYPE_CM3}, {"qcom,gpu-rgmu", &rgmu_ops, GMU_CORE_TYPE_PCC}, static const struct of_device_id gmu_match_table[] = { { .compatible = "qcom,gpu-gmu", .data = &kgsl_gmu_driver }, { .compatible = "qcom,gpu-rgmu", .data = &kgsl_rgmu_driver }, {}, }; struct oob_entry { Loading @@ -40,50 +37,32 @@ const char *gmu_core_oob_type_str(enum oob_request req) return "UNKNOWN"; } int gmu_core_probe(struct kgsl_device *device) void __init gmu_core_register(void) { const struct of_device_id *match; struct device_node *node; struct gmu_core_ops *gmu_core_ops; int i = 0, ret = -ENXIO; device->gmu_core.flags = ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_GPMU) ? BIT(GMU_GPMU) : 0; for (i = 0; i < ARRAY_SIZE(gmu_subtypes); i++) { node = of_find_compatible_node(device->pdev->dev.of_node, NULL, gmu_subtypes[i].compat); if (node != NULL) { gmu_core_ops = gmu_subtypes[i].core_ops; device->gmu_core.type = gmu_subtypes[i].type; break; } } /* No GMU in dt, no worries...hopefully */ if (node == NULL) { /* If we are trying to use GPMU and no GMU, that's bad */ if (device->gmu_core.flags & BIT(GMU_GPMU)) return ret; /* Otherwise it's ok and nothing to do */ return 0; } if (gmu_core_ops && gmu_core_ops->probe) { ret = gmu_core_ops->probe(device, node); if (ret == 0) device->gmu_core.core_ops = gmu_core_ops; } node = of_find_matching_node_and_match(NULL, gmu_match_table, &match); if (!node) return; return ret; platform_driver_register((struct platform_driver *) match->data); of_node_put(node); } void gmu_core_remove(struct kgsl_device *device) void __exit gmu_core_unregister(void) { struct gmu_core_ops *gmu_core_ops = GMU_CORE_OPS(device); const struct of_device_id *match; struct device_node *node; node = of_find_matching_node_and_match(NULL, gmu_match_table, &match); if (!node) return; if (gmu_core_ops && gmu_core_ops->remove) gmu_core_ops->remove(device); platform_driver_unregister((struct platform_driver *) match->data); of_node_put(node); } bool gmu_core_isenabled(struct kgsl_device *device) Loading @@ -93,7 +72,7 @@ bool gmu_core_isenabled(struct kgsl_device *device) bool gmu_core_gpmu_isenabled(struct kgsl_device *device) { return test_bit(GMU_GPMU, &device->gmu_core.flags); return (device->gmu_core.core_ops != NULL); } bool gmu_core_scales_bandwidth(struct kgsl_device *device) Loading