mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
Merge "msm: kgsl: Move GMU to a component device"
This commit is contained in:
commit
f265cc530d
7 changed files with 238 additions and 139 deletions
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
|
|
@ -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)) {
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
};
|
||||
|
|
@ -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();
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -172,10 +172,5 @@ done:
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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)
|
||||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -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;
|
||||
node = of_find_matching_node_and_match(NULL, gmu_match_table,
|
||||
&match);
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (gmu_core_ops && gmu_core_ops->remove)
|
||||
gmu_core_ops->remove(device);
|
||||
node = of_find_matching_node_and_match(NULL, gmu_match_table,
|
||||
&match);
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
platform_driver_unregister((struct platform_driver *) match->data);
|
||||
of_node_put(node);
|
||||
}
|
||||
|
||||
bool gmu_core_isenabled(struct kgsl_device *device)
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -39,18 +39,10 @@ enum gmu_core_flags {
|
|||
GMU_HFI_ON,
|
||||
GMU_FAULT,
|
||||
GMU_DCVS_REPLAY,
|
||||
GMU_GPMU,
|
||||
GMU_ENABLED,
|
||||
GMU_RSCC_SLEEP_SEQ_DONE,
|
||||
};
|
||||
|
||||
/* GMU Types */
|
||||
enum gmu_coretype {
|
||||
GMU_CORE_TYPE_CM3 = 1, /* Cortex M3 core */
|
||||
GMU_CORE_TYPE_PCC = 2, /* Power collapsible controller */
|
||||
GMU_CORE_TYPE_NONE, /* No GMU */
|
||||
};
|
||||
|
||||
/*
|
||||
* OOB requests values. These range from 0 to 7 and then
|
||||
* the BIT() offset into the actual value is calculated
|
||||
|
|
@ -109,8 +101,6 @@ struct kgsl_device;
|
|||
struct kgsl_snapshot;
|
||||
|
||||
struct gmu_core_ops {
|
||||
int (*probe)(struct kgsl_device *device, struct device_node *node);
|
||||
void (*remove)(struct kgsl_device *device);
|
||||
int (*dcvs_set)(struct kgsl_device *device,
|
||||
int gpu_pwrlevel, int bus_level);
|
||||
int (*init)(struct kgsl_device *device);
|
||||
|
|
@ -169,15 +159,16 @@ struct gmu_core_device {
|
|||
struct gmu_core_ops *core_ops;
|
||||
struct gmu_dev_ops *dev_ops;
|
||||
unsigned long flags;
|
||||
enum gmu_coretype type;
|
||||
};
|
||||
|
||||
extern struct gmu_core_ops gmu_ops;
|
||||
extern struct gmu_core_ops rgmu_ops;
|
||||
extern struct platform_driver kgsl_gmu_driver;
|
||||
extern struct platform_driver kgsl_rgmu_driver;
|
||||
|
||||
/* GMU core functions */
|
||||
int gmu_core_probe(struct kgsl_device *device);
|
||||
void gmu_core_remove(struct kgsl_device *device);
|
||||
|
||||
void __init gmu_core_register(void);
|
||||
void __exit gmu_core_unregister(void);
|
||||
|
||||
int gmu_core_init(struct kgsl_device *device);
|
||||
int gmu_core_start(struct kgsl_device *device);
|
||||
void gmu_core_stop(struct kgsl_device *device);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
|
@ -271,11 +272,12 @@ error:
|
|||
rgmu_snapshot(device);
|
||||
}
|
||||
|
||||
static struct gmu_core_ops rgmu_ops;
|
||||
|
||||
/* Do not access any RGMU registers in RGMU probe function */
|
||||
static int rgmu_probe(struct kgsl_device *device, struct device_node *node)
|
||||
static int rgmu_probe(struct kgsl_device *device, struct platform_device *pdev)
|
||||
{
|
||||
struct rgmu_device *rgmu;
|
||||
struct platform_device *pdev = of_find_device_by_node(node);
|
||||
struct resource *res;
|
||||
int ret = -ENXIO;
|
||||
|
||||
|
|
@ -287,12 +289,11 @@ static int rgmu_probe(struct kgsl_device *device, struct device_node *node)
|
|||
rgmu->pdev = pdev;
|
||||
|
||||
/* Set up RGMU regulators */
|
||||
ret = rgmu_regulators_probe(rgmu, node);
|
||||
ret = rgmu_regulators_probe(rgmu, pdev->dev.of_node);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set up RGMU clocks */
|
||||
ret = rgmu_clocks_probe(rgmu, node);
|
||||
ret = rgmu_clocks_probe(rgmu, pdev->dev.of_node);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -343,6 +344,7 @@ static int rgmu_probe(struct kgsl_device *device, struct device_node *node)
|
|||
rgmu->idle_level = GPU_HW_ACTIVE;
|
||||
|
||||
set_bit(GMU_ENABLED, &device->gmu_core.flags);
|
||||
device->gmu_core.core_ops = &rgmu_ops;
|
||||
device->gmu_core.dev_ops = &adreno_a6xx_rgmudev;
|
||||
|
||||
return 0;
|
||||
|
|
@ -447,9 +449,14 @@ static bool rgmu_regulator_isenabled(struct kgsl_device *device)
|
|||
return (rgmu->gx_gdsc && regulator_is_enabled(rgmu->gx_gdsc));
|
||||
}
|
||||
|
||||
struct gmu_core_ops rgmu_ops = {
|
||||
.probe = rgmu_probe,
|
||||
.remove = rgmu_stop,
|
||||
static void rgmu_remove(struct kgsl_device *device)
|
||||
{
|
||||
rgmu_stop(device);
|
||||
|
||||
memset(&device->gmu_core, 0, sizeof(device->gmu_core));
|
||||
}
|
||||
|
||||
static struct gmu_core_ops rgmu_ops = {
|
||||
.init = rgmu_init,
|
||||
.start = rgmu_start,
|
||||
.stop = rgmu_stop,
|
||||
|
|
@ -458,3 +465,48 @@ struct gmu_core_ops rgmu_ops = {
|
|||
.regulator_isenabled = rgmu_regulator_isenabled,
|
||||
.suspend = rgmu_suspend,
|
||||
};
|
||||
|
||||
static int kgsl_rgmu_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
struct kgsl_device *device = dev_get_drvdata(master);
|
||||
|
||||
return rgmu_probe(device, to_platform_device(dev));
|
||||
}
|
||||
|
||||
static void kgsl_rgmu_unbind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
struct kgsl_device *device = dev_get_drvdata(master);
|
||||
|
||||
rgmu_remove(device);
|
||||
}
|
||||
|
||||
static const struct component_ops kgsl_rgmu_ops = {
|
||||
.bind = kgsl_rgmu_bind,
|
||||
.unbind = kgsl_rgmu_unbind,
|
||||
};
|
||||
|
||||
static int kgsl_rgmu_probe(struct platform_device *pdev)
|
||||
{
|
||||
return component_add(&pdev->dev, &kgsl_rgmu_ops);
|
||||
}
|
||||
|
||||
static int kgsl_rgmu_remove(struct platform_device *pdev)
|
||||
{
|
||||
component_del(&pdev->dev, &kgsl_rgmu_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id kgsl_rgmu_match_table[] = {
|
||||
{ .compatible = "qcom,gpu-rgmu" },
|
||||
{ },
|
||||
};
|
||||
|
||||
struct platform_driver kgsl_rgmu_driver = {
|
||||
.probe = kgsl_rgmu_probe,
|
||||
.remove = kgsl_rgmu_remove,
|
||||
.driver = {
|
||||
.name = "kgsl-rgmu",
|
||||
.of_match_table = kgsl_rgmu_match_table,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue