You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'drm-msm-next-2017-08-22' of git://people.freedesktop.org/~robclark/linux into drm-next
Updates for 4.14.. I have some further patches from Jordan to add multiple priority levels and pre-emption, but those will probably be for 4.15 to give me time for the mesa parts. * tag 'drm-msm-next-2017-08-22' of git://people.freedesktop.org/~robclark/linux: drm/msm/mdp5: mark runtime_pm functions as __maybe_unused drm/msm: remove unused variable drm/msm/mdp5: make helper function static drm/msm: make msm_framebuffer_init() static drm/msm: add helper to allocate stolen fb drm/msm: don't track fbdev's gem object separately drm/msm: add modeset module param drm/msm/mdp5: add tracking for clk enable-count drm/msm: remove unused define drm/msm: Add a helper function for in-kernel buffer allocations drm/msm: Attach the GPU MMU when it is created drm/msm: Add A5XX hardware fault detection drm/msm: Remove uneeded platform dev members drm/msm/mdp5: Set up runtime PM for MDSS drm/msm/mdp5: Write to SMP registers even if allocations don't change drm/msm/mdp5: Don't use mode_set helper funcs for encoders and CRTCs drm/msm/dsi: Implement RPM suspend/resume callbacks drm/msm/dsi: Set up runtime PM for DSI drm/msm/hdmi: Set up runtime PM for HDMI drm/msm/mdp5: Use runtime PM get/put API instead of toggling clocks
This commit is contained in:
@@ -486,8 +486,6 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
|
||||
adreno_gpu = &a3xx_gpu->base;
|
||||
gpu = &adreno_gpu->base;
|
||||
|
||||
a3xx_gpu->pdev = pdev;
|
||||
|
||||
gpu->perfcntrs = perfcntrs;
|
||||
gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
struct a3xx_gpu {
|
||||
struct adreno_gpu base;
|
||||
struct platform_device *pdev;
|
||||
|
||||
/* if OCMEM is used for GMEM: */
|
||||
uint32_t ocmem_base;
|
||||
|
||||
@@ -568,8 +568,6 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
|
||||
adreno_gpu = &a4xx_gpu->base;
|
||||
gpu = &adreno_gpu->base;
|
||||
|
||||
a4xx_gpu->pdev = pdev;
|
||||
|
||||
gpu->perfcntrs = NULL;
|
||||
gpu->num_perfcntrs = 0;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
struct a4xx_gpu {
|
||||
struct adreno_gpu base;
|
||||
struct platform_device *pdev;
|
||||
|
||||
/* if OCMEM is used for GMEM: */
|
||||
uint32_t ocmem_base;
|
||||
|
||||
@@ -284,28 +284,14 @@ static int a5xx_me_init(struct msm_gpu *gpu)
|
||||
static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu,
|
||||
const struct firmware *fw, u64 *iova)
|
||||
{
|
||||
struct drm_device *drm = gpu->dev;
|
||||
struct drm_gem_object *bo;
|
||||
void *ptr;
|
||||
|
||||
bo = msm_gem_new_locked(drm, fw->size - 4, MSM_BO_UNCACHED);
|
||||
if (IS_ERR(bo))
|
||||
return bo;
|
||||
ptr = msm_gem_kernel_new_locked(gpu->dev, fw->size - 4,
|
||||
MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace, &bo, iova);
|
||||
|
||||
ptr = msm_gem_get_vaddr(bo);
|
||||
if (!ptr) {
|
||||
drm_gem_object_unreference(bo);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
if (iova) {
|
||||
int ret = msm_gem_get_iova(bo, gpu->aspace, iova);
|
||||
|
||||
if (ret) {
|
||||
drm_gem_object_unreference(bo);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
}
|
||||
if (IS_ERR(ptr))
|
||||
return ERR_CAST(ptr);
|
||||
|
||||
memcpy(ptr, &fw->data[4], fw->size - 4);
|
||||
|
||||
@@ -372,8 +358,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
|
||||
{
|
||||
static bool loaded;
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
|
||||
struct platform_device *pdev = a5xx_gpu->pdev;
|
||||
struct platform_device *pdev = gpu->pdev;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -410,6 +395,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
|
||||
A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
|
||||
A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW | \
|
||||
A5XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
|
||||
A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT | \
|
||||
A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
|
||||
A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
|
||||
A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
|
||||
@@ -812,6 +798,27 @@ static void a5xx_gpmu_err_irq(struct msm_gpu *gpu)
|
||||
dev_err_ratelimited(gpu->dev->dev, "GPMU | voltage droop\n");
|
||||
}
|
||||
|
||||
static void a5xx_fault_detect_irq(struct msm_gpu *gpu)
|
||||
{
|
||||
struct drm_device *dev = gpu->dev;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
|
||||
dev_err(dev->dev, "gpu fault fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
|
||||
gpu->funcs->last_fence(gpu),
|
||||
gpu_read(gpu, REG_A5XX_RBBM_STATUS),
|
||||
gpu_read(gpu, REG_A5XX_CP_RB_RPTR),
|
||||
gpu_read(gpu, REG_A5XX_CP_RB_WPTR),
|
||||
gpu_read64(gpu, REG_A5XX_CP_IB1_BASE, REG_A5XX_CP_IB1_BASE_HI),
|
||||
gpu_read(gpu, REG_A5XX_CP_IB1_BUFSZ),
|
||||
gpu_read64(gpu, REG_A5XX_CP_IB2_BASE, REG_A5XX_CP_IB2_BASE_HI),
|
||||
gpu_read(gpu, REG_A5XX_CP_IB2_BUFSZ));
|
||||
|
||||
/* Turn off the hangcheck timer to keep it from bothering us */
|
||||
del_timer(&gpu->hangcheck_timer);
|
||||
|
||||
queue_work(priv->wq, &gpu->recover_work);
|
||||
}
|
||||
|
||||
#define RBBM_ERROR_MASK \
|
||||
(A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
|
||||
A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
|
||||
@@ -838,6 +845,9 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
|
||||
if (status & A5XX_RBBM_INT_0_MASK_CP_HW_ERROR)
|
||||
a5xx_cp_err_irq(gpu);
|
||||
|
||||
if (status & A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT)
|
||||
a5xx_fault_detect_irq(gpu);
|
||||
|
||||
if (status & A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
|
||||
a5xx_uche_err_irq(gpu);
|
||||
|
||||
@@ -1015,7 +1025,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
|
||||
adreno_gpu = &a5xx_gpu->base;
|
||||
gpu = &adreno_gpu->base;
|
||||
|
||||
a5xx_gpu->pdev = pdev;
|
||||
adreno_gpu->registers = a5xx_registers;
|
||||
adreno_gpu->reg_offsets = a5xx_register_offsets;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
struct a5xx_gpu {
|
||||
struct adreno_gpu base;
|
||||
struct platform_device *pdev;
|
||||
|
||||
struct drm_gem_object *pm4_bo;
|
||||
uint64_t pm4_iova;
|
||||
|
||||
@@ -294,16 +294,10 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
|
||||
*/
|
||||
bosize = (cmds_size + (cmds_size / TYPE4_MAX_PAYLOAD) + 1) << 2;
|
||||
|
||||
a5xx_gpu->gpmu_bo = msm_gem_new_locked(drm, bosize, MSM_BO_UNCACHED);
|
||||
if (IS_ERR(a5xx_gpu->gpmu_bo))
|
||||
goto err;
|
||||
|
||||
if (msm_gem_get_iova(a5xx_gpu->gpmu_bo, gpu->aspace,
|
||||
&a5xx_gpu->gpmu_iova))
|
||||
goto err;
|
||||
|
||||
ptr = msm_gem_get_vaddr(a5xx_gpu->gpmu_bo);
|
||||
if (!ptr)
|
||||
ptr = msm_gem_kernel_new_locked(drm, bosize,
|
||||
MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace,
|
||||
&a5xx_gpu->gpmu_bo, &a5xx_gpu->gpmu_iova);
|
||||
if (IS_ERR(ptr))
|
||||
goto err;
|
||||
|
||||
while (cmds_size > 0) {
|
||||
|
||||
@@ -337,11 +337,6 @@ void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
|
||||
DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
|
||||
}
|
||||
|
||||
static const char *iommu_ports[] = {
|
||||
"gfx3d_user", "gfx3d_priv",
|
||||
"gfx3d1_user", "gfx3d1_priv",
|
||||
};
|
||||
|
||||
int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
|
||||
struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs)
|
||||
{
|
||||
@@ -373,15 +368,15 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
|
||||
|
||||
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;
|
||||
|
||||
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",
|
||||
@@ -396,37 +391,17 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
adreno_gpu->memptrs_bo = msm_gem_new(drm, sizeof(*adreno_gpu->memptrs),
|
||||
MSM_BO_UNCACHED);
|
||||
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 = PTR_ERR(adreno_gpu->memptrs);
|
||||
adreno_gpu->memptrs = NULL;
|
||||
dev_err(drm->dev, "could not allocate memptrs: %d\n", ret);
|
||||
}
|
||||
|
||||
ret = msm_gem_get_iova(adreno_gpu->memptrs_bo, gpu->aspace,
|
||||
&adreno_gpu->memptrs_iova);
|
||||
if (ret) {
|
||||
dev_err(drm->dev, "could not map memptrs: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
|
||||
@@ -446,10 +421,4 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
|
||||
release_firmware(adreno_gpu->pfp);
|
||||
|
||||
msm_gpu_cleanup(gpu);
|
||||
|
||||
if (gpu->aspace) {
|
||||
gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
|
||||
iommu_ports, ARRAY_SIZE(iommu_ports));
|
||||
msm_gem_address_space_put(gpu->aspace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,12 +161,17 @@ static const struct of_device_id dt_match[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct dev_pm_ops dsi_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver dsi_driver = {
|
||||
.probe = dsi_dev_probe,
|
||||
.remove = dsi_dev_remove,
|
||||
.driver = {
|
||||
.name = "msm_dsi",
|
||||
.of_match_table = dt_match,
|
||||
.pm = &dsi_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -179,6 +179,8 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host);
|
||||
int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
|
||||
struct drm_device *dev);
|
||||
int msm_dsi_host_init(struct msm_dsi *msm_dsi);
|
||||
int msm_dsi_runtime_suspend(struct device *dev);
|
||||
int msm_dsi_runtime_resume(struct device *dev);
|
||||
|
||||
/* dsi phy */
|
||||
struct msm_dsi_phy;
|
||||
|
||||
@@ -135,7 +135,6 @@ struct msm_dsi_host {
|
||||
struct completion video_comp;
|
||||
struct mutex dev_mutex;
|
||||
struct mutex cmd_mutex;
|
||||
struct mutex clk_mutex;
|
||||
spinlock_t intr_lock; /* Protect interrupt ctrl register */
|
||||
|
||||
u32 err_work_state;
|
||||
@@ -221,6 +220,8 @@ static const struct msm_dsi_cfg_handler *dsi_get_config(
|
||||
goto put_gdsc;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
ret = regulator_enable(gdsc_reg);
|
||||
if (ret) {
|
||||
pr_err("%s: unable to enable gdsc\n", __func__);
|
||||
@@ -247,6 +248,7 @@ disable_clks:
|
||||
clk_disable_unprepare(ahb_clk);
|
||||
disable_gdsc:
|
||||
regulator_disable(gdsc_reg);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
put_clk:
|
||||
clk_put(ahb_clk);
|
||||
put_gdsc:
|
||||
@@ -455,6 +457,34 @@ static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host)
|
||||
clk_disable_unprepare(msm_host->bus_clks[i]);
|
||||
}
|
||||
|
||||
int msm_dsi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
|
||||
struct mipi_dsi_host *host = msm_dsi->host;
|
||||
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
|
||||
|
||||
if (!msm_host->cfg_hnd)
|
||||
return 0;
|
||||
|
||||
dsi_bus_clk_disable(msm_host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_dsi_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
|
||||
struct mipi_dsi_host *host = msm_dsi->host;
|
||||
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
|
||||
|
||||
if (!msm_host->cfg_hnd)
|
||||
return 0;
|
||||
|
||||
return dsi_bus_clk_enable(msm_host);
|
||||
}
|
||||
|
||||
static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
|
||||
{
|
||||
int ret;
|
||||
@@ -596,35 +626,6 @@ static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
|
||||
}
|
||||
}
|
||||
|
||||
static int dsi_clk_ctrl(struct msm_dsi_host *msm_host, bool enable)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&msm_host->clk_mutex);
|
||||
if (enable) {
|
||||
ret = dsi_bus_clk_enable(msm_host);
|
||||
if (ret) {
|
||||
pr_err("%s: Can not enable bus clk, %d\n",
|
||||
__func__, ret);
|
||||
goto unlock_ret;
|
||||
}
|
||||
ret = dsi_link_clk_enable(msm_host);
|
||||
if (ret) {
|
||||
pr_err("%s: Can not enable link clk, %d\n",
|
||||
__func__, ret);
|
||||
dsi_bus_clk_disable(msm_host);
|
||||
goto unlock_ret;
|
||||
}
|
||||
} else {
|
||||
dsi_link_clk_disable(msm_host);
|
||||
dsi_bus_clk_disable(msm_host);
|
||||
}
|
||||
|
||||
unlock_ret:
|
||||
mutex_unlock(&msm_host->clk_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
|
||||
{
|
||||
struct drm_display_mode *mode = msm_host->mode;
|
||||
@@ -1699,6 +1700,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
|
||||
}
|
||||
|
||||
msm_host->pdev = pdev;
|
||||
msm_dsi->host = &msm_host->base;
|
||||
|
||||
ret = dsi_host_parse_dt(msm_host);
|
||||
if (ret) {
|
||||
@@ -1713,6 +1715,8 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
msm_host->cfg_hnd = dsi_get_config(msm_host);
|
||||
if (!msm_host->cfg_hnd) {
|
||||
ret = -EINVAL;
|
||||
@@ -1753,7 +1757,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
|
||||
init_completion(&msm_host->video_comp);
|
||||
mutex_init(&msm_host->dev_mutex);
|
||||
mutex_init(&msm_host->cmd_mutex);
|
||||
mutex_init(&msm_host->clk_mutex);
|
||||
spin_lock_init(&msm_host->intr_lock);
|
||||
|
||||
/* setup workqueue */
|
||||
@@ -1761,7 +1764,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
|
||||
INIT_WORK(&msm_host->err_work, dsi_err_worker);
|
||||
INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker);
|
||||
|
||||
msm_dsi->host = &msm_host->base;
|
||||
msm_dsi->id = msm_host->id;
|
||||
|
||||
DBG("Dsi Host %d initialized", msm_host->id);
|
||||
@@ -1783,9 +1785,10 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host)
|
||||
msm_host->workqueue = NULL;
|
||||
}
|
||||
|
||||
mutex_destroy(&msm_host->clk_mutex);
|
||||
mutex_destroy(&msm_host->cmd_mutex);
|
||||
mutex_destroy(&msm_host->dev_mutex);
|
||||
|
||||
pm_runtime_disable(&msm_host->pdev->dev);
|
||||
}
|
||||
|
||||
int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
|
||||
@@ -1881,7 +1884,8 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
|
||||
* mdss interrupt is generated in mdp core clock domain
|
||||
* mdp clock need to be enabled to receive dsi interrupt
|
||||
*/
|
||||
dsi_clk_ctrl(msm_host, 1);
|
||||
pm_runtime_get_sync(&msm_host->pdev->dev);
|
||||
dsi_link_clk_enable(msm_host);
|
||||
|
||||
/* TODO: vote for bus bandwidth */
|
||||
|
||||
@@ -1911,7 +1915,8 @@ void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
|
||||
|
||||
/* TODO: unvote for bus bandwidth */
|
||||
|
||||
dsi_clk_ctrl(msm_host, 0);
|
||||
dsi_link_clk_disable(msm_host);
|
||||
pm_runtime_put_autosuspend(&msm_host->pdev->dev);
|
||||
}
|
||||
|
||||
int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
|
||||
@@ -2160,8 +2165,11 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host)
|
||||
* and only turned on before MDP START.
|
||||
* This part of code should be enabled once mdp driver support it.
|
||||
*/
|
||||
/* if (msm_panel->mode == MSM_DSI_CMD_MODE)
|
||||
dsi_clk_ctrl(msm_host, 0); */
|
||||
/* if (msm_panel->mode == MSM_DSI_CMD_MODE) {
|
||||
* dsi_link_clk_disable(msm_host);
|
||||
* pm_runtime_put_autosuspend(&msm_host->pdev->dev);
|
||||
* }
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2217,9 +2225,11 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
|
||||
goto unlock_ret;
|
||||
}
|
||||
|
||||
ret = dsi_clk_ctrl(msm_host, 1);
|
||||
pm_runtime_get_sync(&msm_host->pdev->dev);
|
||||
ret = dsi_link_clk_enable(msm_host);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to enable clocks. ret=%d\n", __func__, ret);
|
||||
pr_err("%s: failed to enable link clocks. ret=%d\n",
|
||||
__func__, ret);
|
||||
goto fail_disable_reg;
|
||||
}
|
||||
|
||||
@@ -2243,7 +2253,8 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
|
||||
return 0;
|
||||
|
||||
fail_disable_clk:
|
||||
dsi_clk_ctrl(msm_host, 0);
|
||||
dsi_link_clk_disable(msm_host);
|
||||
pm_runtime_put_autosuspend(&msm_host->pdev->dev);
|
||||
fail_disable_reg:
|
||||
dsi_host_regulator_disable(msm_host);
|
||||
unlock_ret:
|
||||
@@ -2268,7 +2279,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
|
||||
|
||||
pinctrl_pm_select_sleep_state(&msm_host->pdev->dev);
|
||||
|
||||
dsi_clk_ctrl(msm_host, 0);
|
||||
dsi_link_clk_disable(msm_host);
|
||||
pm_runtime_put_autosuspend(&msm_host->pdev->dev);
|
||||
|
||||
dsi_host_regulator_disable(msm_host);
|
||||
|
||||
|
||||
@@ -373,7 +373,7 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy)
|
||||
static void dsi_phy_disable_resource(struct msm_dsi_phy *phy)
|
||||
{
|
||||
clk_disable_unprepare(phy->ahb_clk);
|
||||
pm_runtime_put_sync(&phy->pdev->dev);
|
||||
pm_runtime_put_autosuspend(&phy->pdev->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id dsi_phy_dt_match[] = {
|
||||
|
||||
@@ -239,6 +239,8 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev)
|
||||
hdmi->pwr_clks[i] = clk;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
|
||||
|
||||
hdmi->i2c = msm_hdmi_i2c_init(hdmi);
|
||||
|
||||
@@ -35,6 +35,8 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge)
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
int i, ret;
|
||||
|
||||
pm_runtime_get_sync(&hdmi->pdev->dev);
|
||||
|
||||
for (i = 0; i < config->pwr_reg_cnt; i++) {
|
||||
ret = regulator_enable(hdmi->pwr_regs[i]);
|
||||
if (ret) {
|
||||
@@ -84,6 +86,8 @@ static void power_off(struct drm_bridge *bridge)
|
||||
config->pwr_reg_names[i], ret);
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_put_autosuspend(&hdmi->pdev->dev);
|
||||
}
|
||||
|
||||
#define AVI_IFRAME_LINE_NUMBER 1
|
||||
|
||||
@@ -137,6 +137,36 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
|
||||
{
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
struct device *dev = &hdmi->pdev->dev;
|
||||
int i, ret;
|
||||
|
||||
if (enable) {
|
||||
for (i = 0; i < config->hpd_clk_cnt; i++) {
|
||||
if (config->hpd_freq && config->hpd_freq[i]) {
|
||||
ret = clk_set_rate(hdmi->hpd_clks[i],
|
||||
config->hpd_freq[i]);
|
||||
if (ret)
|
||||
dev_warn(dev,
|
||||
"failed to set clk %s (%d)\n",
|
||||
config->hpd_clk_names[i], ret);
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(hdmi->hpd_clks[i]);
|
||||
if (ret) {
|
||||
dev_err(dev,
|
||||
"failed to enable hpd clk: %s (%d)\n",
|
||||
config->hpd_clk_names[i], ret);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
|
||||
clk_disable_unprepare(hdmi->hpd_clks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int hpd_enable(struct hdmi_connector *hdmi_connector)
|
||||
{
|
||||
struct hdmi *hdmi = hdmi_connector->hdmi;
|
||||
@@ -167,22 +197,8 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < config->hpd_clk_cnt; i++) {
|
||||
if (config->hpd_freq && config->hpd_freq[i]) {
|
||||
ret = clk_set_rate(hdmi->hpd_clks[i],
|
||||
config->hpd_freq[i]);
|
||||
if (ret)
|
||||
dev_warn(dev, "failed to set clk %s (%d)\n",
|
||||
config->hpd_clk_names[i], ret);
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(hdmi->hpd_clks[i]);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable hpd clk: %s (%d)\n",
|
||||
config->hpd_clk_names[i], ret);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
pm_runtime_get_sync(dev);
|
||||
enable_hpd_clocks(hdmi, true);
|
||||
|
||||
msm_hdmi_set_mode(hdmi, false);
|
||||
msm_hdmi_phy_reset(hdmi);
|
||||
@@ -225,8 +241,8 @@ static void hdp_disable(struct hdmi_connector *hdmi_connector)
|
||||
|
||||
msm_hdmi_set_mode(hdmi, false);
|
||||
|
||||
for (i = 0; i < config->hpd_clk_cnt; i++)
|
||||
clk_disable_unprepare(hdmi->hpd_clks[i]);
|
||||
enable_hpd_clocks(hdmi, false);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
ret = gpio_config(hdmi, false);
|
||||
if (ret)
|
||||
@@ -285,7 +301,16 @@ void msm_hdmi_connector_irq(struct drm_connector *connector)
|
||||
|
||||
static enum drm_connector_status detect_reg(struct hdmi *hdmi)
|
||||
{
|
||||
uint32_t hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
|
||||
uint32_t hpd_int_status;
|
||||
|
||||
pm_runtime_get_sync(&hdmi->pdev->dev);
|
||||
enable_hpd_clocks(hdmi, true);
|
||||
|
||||
hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
|
||||
|
||||
enable_hpd_clocks(hdmi, false);
|
||||
pm_runtime_put_autosuspend(&hdmi->pdev->dev);
|
||||
|
||||
return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
|
||||
connector_status_connected : connector_status_disconnected;
|
||||
}
|
||||
|
||||
@@ -192,6 +192,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
|
||||
{
|
||||
struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
|
||||
struct mdp5_kms *mdp5_kms;
|
||||
struct device *dev;
|
||||
int intf_num;
|
||||
u32 data = 0;
|
||||
|
||||
@@ -214,14 +215,16 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
|
||||
/* Smart Panel, Sync mode */
|
||||
data |= MDP5_SPLIT_DPL_UPPER_SMART_PANEL;
|
||||
|
||||
dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
/* Make sure clocks are on when connectors calling this function. */
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, data);
|
||||
|
||||
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER,
|
||||
MDP5_SPLIT_DPL_LOWER_SMART_PANEL);
|
||||
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_EN, 1);
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -415,6 +415,7 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
||||
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
|
||||
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
DBG("%s", crtc->name);
|
||||
|
||||
@@ -425,7 +426,7 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->pp_done);
|
||||
|
||||
mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err);
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
mdp5_crtc->enabled = false;
|
||||
}
|
||||
@@ -436,13 +437,17 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
|
||||
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
|
||||
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
DBG("%s", crtc->name);
|
||||
|
||||
if (WARN_ON(mdp5_crtc->enabled))
|
||||
return;
|
||||
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
mdp5_crtc_mode_set_nofb(crtc);
|
||||
|
||||
mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err);
|
||||
|
||||
if (mdp5_cstate->cmd_mode)
|
||||
@@ -533,7 +538,7 @@ static bool is_fullscreen(struct drm_crtc_state *cstate,
|
||||
((pstate->crtc_y + pstate->crtc_h) >= cstate->mode.vdisplay);
|
||||
}
|
||||
|
||||
enum mdp_mixer_stage_id get_start_stage(struct drm_crtc *crtc,
|
||||
static enum mdp_mixer_stage_id get_start_stage(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *new_crtc_state,
|
||||
struct drm_plane_state *bpstate)
|
||||
{
|
||||
@@ -727,6 +732,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct mdp5_kms *mdp5_kms = get_kms(crtc);
|
||||
struct platform_device *pdev = mdp5_kms->pdev;
|
||||
struct msm_kms *kms = &mdp5_kms->base.base;
|
||||
struct drm_gem_object *cursor_bo, *old_bo = NULL;
|
||||
uint32_t blendcfg, stride;
|
||||
@@ -755,7 +761,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
if (!handle) {
|
||||
DBG("Cursor off");
|
||||
cursor_enable = false;
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
goto set_cursor;
|
||||
}
|
||||
|
||||
@@ -770,6 +776,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
lm = mdp5_cstate->pipeline.mixer->lm;
|
||||
stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
|
||||
old_bo = mdp5_crtc->cursor.scanout_bo;
|
||||
|
||||
@@ -779,8 +787,6 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
|
||||
get_roi(crtc, &roi_w, &roi_h);
|
||||
|
||||
mdp5_enable(mdp5_kms);
|
||||
|
||||
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride);
|
||||
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm),
|
||||
MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888));
|
||||
@@ -798,6 +804,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
|
||||
spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
|
||||
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
set_cursor:
|
||||
ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable);
|
||||
if (ret) {
|
||||
@@ -809,7 +817,7 @@ set_cursor:
|
||||
crtc_flush(crtc, flush_mask);
|
||||
|
||||
end:
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
if (old_bo) {
|
||||
drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo);
|
||||
/* enable vblank to complete cursor work: */
|
||||
@@ -842,7 +850,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
||||
|
||||
get_roi(crtc, &roi_w, &roi_h);
|
||||
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(&mdp5_kms->pdev->dev);
|
||||
|
||||
spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
|
||||
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm),
|
||||
@@ -855,7 +863,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
||||
|
||||
crtc_flush(crtc, flush_mask);
|
||||
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(&mdp5_kms->pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -297,6 +297,10 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
|
||||
{
|
||||
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
|
||||
struct mdp5_interface *intf = mdp5_encoder->intf;
|
||||
/* this isn't right I think */
|
||||
struct drm_crtc_state *cstate = encoder->crtc->state;
|
||||
|
||||
mdp5_encoder_mode_set(encoder, &cstate->mode, &cstate->adjusted_mode);
|
||||
|
||||
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
|
||||
mdp5_cmd_encoder_enable(encoder);
|
||||
@@ -320,7 +324,6 @@ static int mdp5_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
|
||||
.mode_set = mdp5_encoder_mode_set,
|
||||
.disable = mdp5_encoder_disable,
|
||||
.enable = mdp5_encoder_enable,
|
||||
.atomic_check = mdp5_encoder_atomic_check,
|
||||
@@ -350,6 +353,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
|
||||
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
|
||||
struct mdp5_encoder *mdp5_slave_enc = to_mdp5_encoder(slave_encoder);
|
||||
struct mdp5_kms *mdp5_kms;
|
||||
struct device *dev;
|
||||
int intf_num;
|
||||
u32 data = 0;
|
||||
|
||||
@@ -369,8 +373,10 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
dev = &mdp5_kms->pdev->dev;
|
||||
/* Make sure clocks are on when connectors calling this function. */
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
/* Dumb Panel, Sync mode */
|
||||
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, 0);
|
||||
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER, data);
|
||||
@@ -378,7 +384,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
|
||||
|
||||
mdp5_ctl_pair(mdp5_encoder->ctl, mdp5_slave_enc->ctl, true);
|
||||
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -49,16 +49,19 @@ static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
|
||||
void mdp5_irq_preinstall(struct msm_kms *kms)
|
||||
{
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
|
||||
mdp5_enable(mdp5_kms);
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff);
|
||||
mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
int mdp5_irq_postinstall(struct msm_kms *kms)
|
||||
{
|
||||
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
struct mdp_irq *error_handler = &mdp5_kms->error_handler;
|
||||
|
||||
error_handler->irq = mdp5_irq_error_handler;
|
||||
@@ -67,9 +70,9 @@ int mdp5_irq_postinstall(struct msm_kms *kms)
|
||||
MDP5_IRQ_INTF2_UNDER_RUN |
|
||||
MDP5_IRQ_INTF3_UNDER_RUN;
|
||||
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
mdp_irq_register(mdp_kms, error_handler);
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -77,9 +80,11 @@ int mdp5_irq_postinstall(struct msm_kms *kms)
|
||||
void mdp5_irq_uninstall(struct msm_kms *kms)
|
||||
{
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
|
||||
mdp5_enable(mdp5_kms);
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
irqreturn_t mdp5_irq(struct msm_kms *kms)
|
||||
@@ -109,11 +114,12 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
|
||||
int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
|
||||
{
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
mdp_update_vblank_mask(to_mdp_kms(kms),
|
||||
mdp5_crtc_vblank(crtc), true);
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -121,9 +127,10 @@ int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
|
||||
void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
|
||||
{
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
mdp_update_vblank_mask(to_mdp_kms(kms),
|
||||
mdp5_crtc_vblank(crtc), false);
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
@@ -30,11 +30,10 @@ static const char *iommu_ports[] = {
|
||||
static int mdp5_hw_init(struct msm_kms *kms)
|
||||
{
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
|
||||
struct platform_device *pdev = mdp5_kms->pdev;
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
unsigned long flags;
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
/* Magic unknown register writes:
|
||||
*
|
||||
@@ -66,8 +65,7 @@ static int mdp5_hw_init(struct msm_kms *kms)
|
||||
|
||||
mdp5_ctlm_hw_reset(mdp5_kms->ctlm);
|
||||
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_put_sync(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -111,8 +109,9 @@ static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)
|
||||
static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
|
||||
{
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
if (mdp5_kms->smp)
|
||||
mdp5_smp_prepare_commit(mdp5_kms->smp, &mdp5_kms->state->smp);
|
||||
@@ -121,11 +120,12 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
|
||||
static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
|
||||
{
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
|
||||
if (mdp5_kms->smp)
|
||||
mdp5_smp_complete_commit(mdp5_kms->smp, &mdp5_kms->state->smp);
|
||||
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
static void mdp5_wait_for_crtc_commit_done(struct msm_kms *kms,
|
||||
@@ -249,6 +249,9 @@ int mdp5_disable(struct mdp5_kms *mdp5_kms)
|
||||
{
|
||||
DBG("");
|
||||
|
||||
mdp5_kms->enable_count--;
|
||||
WARN_ON(mdp5_kms->enable_count < 0);
|
||||
|
||||
clk_disable_unprepare(mdp5_kms->ahb_clk);
|
||||
clk_disable_unprepare(mdp5_kms->axi_clk);
|
||||
clk_disable_unprepare(mdp5_kms->core_clk);
|
||||
@@ -262,6 +265,8 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
|
||||
{
|
||||
DBG("");
|
||||
|
||||
mdp5_kms->enable_count++;
|
||||
|
||||
clk_prepare_enable(mdp5_kms->ahb_clk);
|
||||
clk_prepare_enable(mdp5_kms->axi_clk);
|
||||
clk_prepare_enable(mdp5_kms->core_clk);
|
||||
@@ -486,11 +491,12 @@ fail:
|
||||
static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms,
|
||||
u32 *major, u32 *minor)
|
||||
{
|
||||
struct device *dev = &mdp5_kms->pdev->dev;
|
||||
u32 version;
|
||||
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(dev);
|
||||
version = mdp5_read(mdp5_kms, REG_MDP5_HW_VERSION);
|
||||
mdp5_disable(mdp5_kms);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
*major = FIELD(version, MDP5_HW_VERSION_MAJOR);
|
||||
*minor = FIELD(version, MDP5_HW_VERSION_MINOR);
|
||||
@@ -643,7 +649,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
|
||||
* have left things on, in which case we'll start getting faults if
|
||||
* we don't disable):
|
||||
*/
|
||||
mdp5_enable(mdp5_kms);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
|
||||
if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
|
||||
!config->hw->intf.base[i])
|
||||
@@ -652,7 +658,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
|
||||
|
||||
mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(i), 0x3);
|
||||
}
|
||||
mdp5_disable(mdp5_kms);
|
||||
mdelay(16);
|
||||
|
||||
if (config->platform.iommu) {
|
||||
@@ -678,6 +683,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
|
||||
aspace = NULL;;
|
||||
}
|
||||
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
ret = modeset_init(mdp5_kms);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "modeset_init failed: %d\n", ret);
|
||||
@@ -1005,6 +1012,30 @@ static int mdp5_dev_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __maybe_unused int mdp5_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
|
||||
|
||||
DBG("");
|
||||
|
||||
return mdp5_disable(mdp5_kms);
|
||||
}
|
||||
|
||||
static __maybe_unused int mdp5_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
|
||||
|
||||
DBG("");
|
||||
|
||||
return mdp5_enable(mdp5_kms);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops mdp5_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(mdp5_runtime_suspend, mdp5_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct of_device_id mdp5_dt_match[] = {
|
||||
{ .compatible = "qcom,mdp5", },
|
||||
/* to support downstream DT files */
|
||||
@@ -1019,6 +1050,7 @@ static struct platform_driver mdp5_driver = {
|
||||
.driver = {
|
||||
.name = "msm_mdp",
|
||||
.of_match_table = mdp5_dt_match,
|
||||
.pm = &mdp5_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user