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; 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 (!info) { dev_warn(dev->dev, "Unknown GPU revision: %u.%u.%u.%u\n", rev.core, rev.major, rev.minor, rev.patchid); 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; mutex_lock(&dev->struct_mutex); gpu->funcs->pm_resume(gpu); mutex_unlock(&dev->struct_mutex); ret = gpu->funcs->hw_init(gpu); if (ret) { dev_err(dev->dev, "gpu hw init failed: %d\n", ret); gpu->funcs->destroy(gpu); gpu = NULL; } else { /* give inactive pm a chance to kick in: */ msm_gpu_retire(gpu); } } return gpu; }
static int adreno_bind(struct device *dev, struct device *master, void *data) { 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; ret = find_chipid(dev, &config.rev); if (ret) return ret; dev->platform_data = &config; set_gpu_pdev(drm, to_platform_device(dev)); info = adreno_info(config.rev); 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; } DBG("Found GPU: %u.%u.%u.%u", config.rev.core, config.rev.major, config.rev.minor, config.rev.patchid); gpu = info->init(drm); if (IS_ERR(gpu)) { dev_warn(drm->dev, "failed to load adreno gpu\n"); return PTR_ERR(gpu); } dev_set_drvdata(dev, gpu); return 0; }
int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs) { struct adreno_platform_config *config = pdev->dev.platform_data; struct msm_gpu *gpu = &adreno_gpu->base; int ret; adreno_gpu->funcs = funcs; adreno_gpu->info = adreno_info(config->rev); adreno_gpu->gmem = adreno_gpu->info->gmem; adreno_gpu->revn = adreno_gpu->info->revn; adreno_gpu->rev = config->rev; gpu->fast_rate = config->fast_rate; gpu->bus_freq = config->bus_freq; #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING gpu->bus_scale_table = config->bus_scale_table; #endif DBG("fast_rate=%u, slow_rate=27000000, bus_freq=%u", gpu->fast_rate, gpu->bus_freq); ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, "kgsl_3d0_reg_memory", "kgsl_3d0_irq", RB_SIZE); if (ret) return ret; pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); if (ret) { dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", adreno_gpu->info->pm4fw, ret); return ret; } ret = request_firmware(&adreno_gpu->pfp, adreno_gpu->info->pfpfw, drm->dev); if (ret) { dev_err(drm->dev, "failed to load %s PFP firmware: %d\n", adreno_gpu->info->pfpfw, ret); return ret; } if (gpu->aspace && gpu->aspace->mmu) { struct msm_mmu *mmu = gpu->aspace->mmu; ret = mmu->funcs->attach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); if (ret) return ret; } mutex_lock(&drm->struct_mutex); adreno_gpu->memptrs_bo = msm_gem_new(drm, sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED); mutex_unlock(&drm->struct_mutex); if (IS_ERR(adreno_gpu->memptrs_bo)) { ret = PTR_ERR(adreno_gpu->memptrs_bo); adreno_gpu->memptrs_bo = NULL; dev_err(drm->dev, "could not allocate memptrs: %d\n", ret); return ret; } adreno_gpu->memptrs = msm_gem_get_vaddr(adreno_gpu->memptrs_bo); if (IS_ERR(adreno_gpu->memptrs)) { dev_err(drm->dev, "could not vmap memptrs\n"); return -ENOMEM; } ret = msm_gem_get_iova(adreno_gpu->memptrs_bo, gpu->id, &adreno_gpu->memptrs_iova); if (ret) { dev_err(drm->dev, "could not map memptrs: %d\n", ret); return ret; } return 0; }
int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs) { struct adreno_platform_config *config = pdev->dev.platform_data; struct msm_gpu_config adreno_gpu_config = { 0 }; struct msm_gpu *gpu = &adreno_gpu->base; int ret; adreno_gpu->funcs = funcs; adreno_gpu->info = adreno_info(config->rev); adreno_gpu->gmem = adreno_gpu->info->gmem; adreno_gpu->revn = adreno_gpu->info->revn; adreno_gpu->rev = config->rev; gpu->fast_rate = config->fast_rate; gpu->bus_freq = config->bus_freq; #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING gpu->bus_scale_table = config->bus_scale_table; #endif DBG("fast_rate=%u, slow_rate=27000000, bus_freq=%u", gpu->fast_rate, gpu->bus_freq); adreno_gpu_config.ioname = "kgsl_3d0_reg_memory"; adreno_gpu_config.irqname = "kgsl_3d0_irq"; adreno_gpu_config.va_start = SZ_16M; adreno_gpu_config.va_end = 0xffffffff; adreno_gpu_config.ringsz = RB_SIZE; pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config); if (ret) return ret; ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); if (ret) { dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", adreno_gpu->info->pm4fw, ret); return ret; } ret = request_firmware(&adreno_gpu->pfp, adreno_gpu->info->pfpfw, drm->dev); if (ret) { dev_err(drm->dev, "failed to load %s PFP firmware: %d\n", adreno_gpu->info->pfpfw, ret); return ret; } adreno_gpu->memptrs = msm_gem_kernel_new(drm, sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED, gpu->aspace, &adreno_gpu->memptrs_bo, &adreno_gpu->memptrs_iova); if (IS_ERR(adreno_gpu->memptrs)) { ret = PTR_ERR(adreno_gpu->memptrs); adreno_gpu->memptrs = NULL; dev_err(drm->dev, "could not allocate memptrs: %d\n", ret); } return ret; }