aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/adreno/adreno_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/adreno/adreno_device.c')
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_device.c206
1 files changed, 73 insertions, 133 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index c75c4df4bc39..62bdb7316da1 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -17,7 +17,6 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/pm_opp.h>
#include "adreno_gpu.h"
#define ANY_ID 0xff
@@ -90,14 +89,19 @@ static const struct adreno_info gpulist[] = {
},
};
-MODULE_FIRMWARE("a300_pm4.fw");
-MODULE_FIRMWARE("a300_pfp.fw");
-MODULE_FIRMWARE("a330_pm4.fw");
-MODULE_FIRMWARE("a330_pfp.fw");
-MODULE_FIRMWARE("a420_pm4.fw");
-MODULE_FIRMWARE("a420_pfp.fw");
-MODULE_FIRMWARE("a530_fm4.fw");
-MODULE_FIRMWARE("a530_pfp.fw");
+MODULE_FIRMWARE("qcom/a300_pm4.fw");
+MODULE_FIRMWARE("qcom/a300_pfp.fw");
+MODULE_FIRMWARE("qcom/a330_pm4.fw");
+MODULE_FIRMWARE("qcom/a330_pfp.fw");
+MODULE_FIRMWARE("qcom/a420_pm4.fw");
+MODULE_FIRMWARE("qcom/a420_pfp.fw");
+MODULE_FIRMWARE("qcom/a530_pm4.fw");
+MODULE_FIRMWARE("qcom/a530_pfp.fw");
+MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2");
+MODULE_FIRMWARE("qcom/a530_zap.mdt");
+MODULE_FIRMWARE("qcom/a530_zap.b00");
+MODULE_FIRMWARE("qcom/a530_zap.b01");
+MODULE_FIRMWARE("qcom/a530_zap.b02");
static inline bool _rev_match(uint8_t entry, uint8_t id)
{
@@ -125,49 +129,25 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
struct platform_device *pdev = priv->gpu_pdev;
- struct adreno_platform_config *config;
- struct adreno_rev rev;
- const struct adreno_info *info;
struct msm_gpu *gpu = NULL;
+ int ret;
- if (!pdev) {
- dev_err(dev->dev, "no adreno device\n");
- return NULL;
- }
-
- config = pdev->dev.platform_data;
- rev = config->rev;
- info = adreno_info(config->rev);
+ if (pdev)
+ gpu = platform_get_drvdata(pdev);
- if (!info) {
- dev_warn(dev->dev, "Unknown GPU revision: %u.%u.%u.%u\n",
- rev.core, rev.major, rev.minor, rev.patchid);
+ if (!gpu) {
+ dev_err_once(dev->dev, "no GPU device was found\n");
return NULL;
}
- DBG("Found GPU: %u.%u.%u.%u", rev.core, rev.major,
- rev.minor, rev.patchid);
-
- gpu = info->init(dev);
- if (IS_ERR(gpu)) {
- dev_warn(dev->dev, "failed to load adreno gpu\n");
- gpu = NULL;
- /* not fatal */
- }
-
- if (gpu) {
- int ret;
-
- pm_runtime_get_sync(&pdev->dev);
- mutex_lock(&dev->struct_mutex);
- ret = msm_gpu_hw_init(gpu);
- mutex_unlock(&dev->struct_mutex);
- pm_runtime_put_sync(&pdev->dev);
- if (ret) {
- dev_err(dev->dev, "gpu hw init failed: %d\n", ret);
- gpu->funcs->destroy(gpu);
- gpu = NULL;
- }
+ pm_runtime_get_sync(&pdev->dev);
+ mutex_lock(&dev->struct_mutex);
+ ret = msm_gpu_hw_init(gpu);
+ mutex_unlock(&dev->struct_mutex);
+ pm_runtime_put_sync(&pdev->dev);
+ if (ret) {
+ dev_err(dev->dev, "gpu hw init failed: %d\n", ret);
+ return NULL;
}
return gpu;
@@ -180,135 +160,95 @@ static void set_gpu_pdev(struct drm_device *dev,
priv->gpu_pdev = pdev;
}
-static int find_chipid(struct device *dev, u32 *chipid)
+static int find_chipid(struct device *dev, struct adreno_rev *rev)
{
struct device_node *node = dev->of_node;
const char *compat;
int ret;
+ u32 chipid;
/* first search the compat strings for qcom,adreno-XYZ.W: */
ret = of_property_read_string_index(node, "compatible", 0, &compat);
if (ret == 0) {
- unsigned rev, patch;
+ unsigned int r, patch;
- if (sscanf(compat, "qcom,adreno-%u.%u", &rev, &patch) == 2) {
- *chipid = 0;
- *chipid |= (rev / 100) << 24; /* core */
- rev %= 100;
- *chipid |= (rev / 10) << 16; /* major */
- rev %= 10;
- *chipid |= rev << 8; /* minor */
- *chipid |= patch;
+ if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2) {
+ rev->core = r / 100;
+ r %= 100;
+ rev->major = r / 10;
+ r %= 10;
+ rev->minor = r;
+ rev->patchid = patch;
return 0;
}
}
/* and if that fails, fall back to legacy "qcom,chipid" property: */
- ret = of_property_read_u32(node, "qcom,chipid", chipid);
- if (ret)
+ ret = of_property_read_u32(node, "qcom,chipid", &chipid);
+ if (ret) {
+ dev_err(dev, "could not parse qcom,chipid: %d\n", ret);
return ret;
-
- dev_warn(dev, "Using legacy qcom,chipid binding!\n");
- dev_warn(dev, "Use compatible qcom,adreno-%u%u%u.%u instead.\n",
- (*chipid >> 24) & 0xff, (*chipid >> 16) & 0xff,
- (*chipid >> 8) & 0xff, *chipid & 0xff);
-
- return 0;
-}
-
-/* Get legacy powerlevels from qcom,gpu-pwrlevels and populate the opp table */
-static int adreno_get_legacy_pwrlevels(struct device *dev)
-{
- struct device_node *child, *node;
- int ret;
-
- node = of_find_compatible_node(dev->of_node, NULL,
- "qcom,gpu-pwrlevels");
- if (!node) {
- dev_err(dev, "Could not find the GPU powerlevels\n");
- return -ENXIO;
}
- for_each_child_of_node(node, child) {
- unsigned int val;
-
- ret = of_property_read_u32(child, "qcom,gpu-freq", &val);
- if (ret)
- continue;
+ rev->core = (chipid >> 24) & 0xff;
+ rev->major = (chipid >> 16) & 0xff;
+ rev->minor = (chipid >> 8) & 0xff;
+ rev->patchid = (chipid & 0xff);
- /*
- * Skip the intentionally bogus clock value found at the bottom
- * of most legacy frequency tables
- */
- if (val != 27000000)
- dev_pm_opp_add(dev, val, 0);
- }
+ dev_warn(dev, "Using legacy qcom,chipid binding!\n");
+ dev_warn(dev, "Use compatible qcom,adreno-%u%u%u.%u instead.\n",
+ rev->core, rev->major, rev->minor, rev->patchid);
return 0;
}
-static int adreno_get_pwrlevels(struct device *dev,
- struct adreno_platform_config *config)
+static int adreno_bind(struct device *dev, struct device *master, void *data)
{
- unsigned long freq = ULONG_MAX;
- struct dev_pm_opp *opp;
+ static struct adreno_platform_config config = {};
+ const struct adreno_info *info;
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct msm_gpu *gpu;
int ret;
- /* You down with OPP? */
- if (!of_find_property(dev->of_node, "operating-points-v2", NULL))
- ret = adreno_get_legacy_pwrlevels(dev);
- else
- ret = dev_pm_opp_of_add_table(dev);
-
+ ret = find_chipid(dev, &config.rev);
if (ret)
return ret;
- /* Find the fastest defined rate */
- opp = dev_pm_opp_find_freq_floor(dev, &freq);
- if (!IS_ERR(opp))
- config->fast_rate = dev_pm_opp_get_freq(opp);
-
- if (!config->fast_rate) {
- DRM_DEV_INFO(dev,
- "Could not find clock rate. Using default\n");
- /* Pick a suitably safe clock speed for any target */
- config->fast_rate = 200000000;
- }
+ dev->platform_data = &config;
+ set_gpu_pdev(drm, to_platform_device(dev));
- return 0;
-}
+ info = adreno_info(config.rev);
-static int adreno_bind(struct device *dev, struct device *master, void *data)
-{
- static struct adreno_platform_config config = {};
- u32 val;
- int ret;
-
- ret = find_chipid(dev, &val);
- if (ret) {
- dev_err(dev, "could not find chipid: %d\n", ret);
- return ret;
+ if (!info) {
+ dev_warn(drm->dev, "Unknown GPU revision: %u.%u.%u.%u\n",
+ config.rev.core, config.rev.major,
+ config.rev.minor, config.rev.patchid);
+ return -ENXIO;
}
- config.rev = ADRENO_REV((val >> 24) & 0xff,
- (val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff);
+ DBG("Found GPU: %u.%u.%u.%u", config.rev.core, config.rev.major,
+ config.rev.minor, config.rev.patchid);
- /* find clock rates: */
- config.fast_rate = 0;
+ gpu = info->init(drm);
+ if (IS_ERR(gpu)) {
+ dev_warn(drm->dev, "failed to load adreno gpu\n");
+ return PTR_ERR(gpu);
+ }
- ret = adreno_get_pwrlevels(dev, &config);
- if (ret)
- return ret;
+ dev_set_drvdata(dev, gpu);
- dev->platform_data = &config;
- set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev));
return 0;
}
static void adreno_unbind(struct device *dev, struct device *master,
void *data)
{
+ struct msm_gpu *gpu = dev_get_drvdata(dev);
+
+ gpu->funcs->pm_suspend(gpu);
+ gpu->funcs->destroy(gpu);
+
set_gpu_pdev(dev_get_drvdata(master), NULL);
}