diff options
| author | Lloyd Atkinson <latkinso@codeaurora.org> | 2016-09-26 17:52:16 -0400 |
|---|---|---|
| committer | Lloyd Atkinson <latkinso@codeaurora.org> | 2016-10-17 15:34:56 -0400 |
| commit | 3b517e89dc75052caeee9a42dea43121730b681a (patch) | |
| tree | 5212dc3311a9f0c331a9de6838f054090b5bcf97 | |
| parent | 167009badbf0c3ca29b5a4f956c77356ebb7d16c (diff) | |
drm/msm/sde: move vbif functions to their own file
Move vbif related functionality out of the sde_kms file and
into its own file to keep the main kms file clean.
Change-Id: Iff067b82813fc29b3ba48d029543d57bd88e3e1b
Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org>
| -rw-r--r-- | drivers/gpu/drm/msm/Makefile | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.c | 192 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.h | 20 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_plane.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_vbif.c | 209 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_vbif.h | 38 |
7 files changed, 251 insertions, 213 deletions
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 3178e3062cda..55b5ac96506f 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -43,6 +43,7 @@ msm_drm-y := \ sde/sde_plane.o \ sde/sde_connector.o \ sde/sde_color_processing.o \ + sde/sde_vbif.o \ msm_atomic.o \ msm_drv.o \ msm_fb.o \ @@ -120,7 +121,7 @@ obj-$(CONFIG_DRM_MSM) += sde/sde_hw_catalog.o \ sde/sde_hw_top.o \ sde/sde_hw_interrupts.o \ sde/sde_hw_vbif.o \ - sde/sde_formats.o + sde/sde_formats.o \ obj-$(CONFIG_DRM_MSM) += display-manager/display_manager.o diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c index 9bc8914fd493..aa91c2d00d0a 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c @@ -23,6 +23,7 @@ #include "sde_hw_interrupts.h" #include "sde_core_irq.h" #include "sde_wb.h" +#include "sde_vbif.h" /* wait for at most 2 vsync for lowest refresh rate (24hz) */ #define WAIT_TIMEOUT_MSEC 84 diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 900269aac053..f7e2681e8458 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -462,198 +462,6 @@ static void core_hw_rev_init(struct sde_kms *sde_kms) sde_kms->core_rev = readl_relaxed(sde_kms->mmio + 0x0); } -/** - * _sde_vbif_wait_for_xin_halt - wait for the xin to halt - * @vbif: Pointer to hardware vbif driver - * @xin_id: Client interface identifier - * @return: 0 if success; error code otherwise - */ -static int _sde_vbif_wait_for_xin_halt(struct sde_hw_vbif *vbif, u32 xin_id) -{ - ktime_t timeout; - bool status; - int rc; - - if (!vbif || !vbif->cap || !vbif->ops.get_halt_ctrl) { - SDE_ERROR("invalid arguments vbif %d\n", vbif != 0); - return -EINVAL; - } - - timeout = ktime_add_us(ktime_get(), vbif->cap->xin_halt_timeout); - for (;;) { - status = vbif->ops.get_halt_ctrl(vbif, xin_id); - if (status) - break; - if (ktime_compare_safe(ktime_get(), timeout) > 0) { - status = vbif->ops.get_halt_ctrl(vbif, xin_id); - break; - } - usleep_range(501, 1000); - } - - if (!status) { - rc = -ETIMEDOUT; - SDE_ERROR("VBIF %d client %d not halting. TIMEDOUT.\n", - vbif->idx - VBIF_0, xin_id); - } else { - rc = 0; - SDE_DEBUG("VBIF %d client %d is halted\n", - vbif->idx - VBIF_0, xin_id); - } - - return rc; -} - -/** - * _sde_vbif_apply_dynamic_ot_limit - determine OT based on usecase parameters - * @vbif: Pointer to hardware vbif driver - * @ot_lim: Pointer to OT limit to be modified - * @params: Pointer to usecase parameters - */ -static void _sde_vbif_apply_dynamic_ot_limit(struct sde_hw_vbif *vbif, - u32 *ot_lim, struct sde_vbif_set_ot_params *params) -{ - u64 pps; - const struct sde_vbif_dynamic_ot_tbl *tbl; - u32 i; - - if (!vbif || !(vbif->cap->features & BIT(SDE_VBIF_QOS_OTLIM))) - return; - - /* Dynamic OT setting done only for WFD */ - if (!params->is_wfd) - return; - - pps = params->frame_rate; - pps *= params->width; - pps *= params->height; - - tbl = params->rd ? &vbif->cap->dynamic_ot_rd_tbl : - &vbif->cap->dynamic_ot_wr_tbl; - - for (i = 0; i < tbl->count; i++) { - if (pps <= tbl->cfg[i].pps) { - *ot_lim = tbl->cfg[i].ot_limit; - break; - } - } - - SDE_DEBUG("vbif:%d xin:%d w:%d h:%d fps:%d pps:%llu ot:%u\n", - vbif->idx - VBIF_0, params->xin_id, - params->width, params->height, params->frame_rate, - pps, *ot_lim); -} - -/** - * _sde_vbif_get_ot_limit - get OT based on usecase & configuration parameters - * @vbif: Pointer to hardware vbif driver - * @params: Pointer to usecase parameters - * @return: OT limit - */ -static u32 _sde_vbif_get_ot_limit(struct sde_hw_vbif *vbif, - struct sde_vbif_set_ot_params *params) -{ - u32 ot_lim = 0; - u32 val; - - if (!vbif || !vbif->cap) { - SDE_ERROR("invalid arguments vbif %d\n", vbif != 0); - return -EINVAL; - } - - if (vbif->cap->default_ot_wr_limit && !params->rd) - ot_lim = vbif->cap->default_ot_wr_limit; - else if (vbif->cap->default_ot_rd_limit && params->rd) - ot_lim = vbif->cap->default_ot_rd_limit; - - /* - * If default ot is not set from dt/catalog, - * then do not configure it. - */ - if (ot_lim == 0) - goto exit; - - /* Modify the limits if the target and the use case requires it */ - _sde_vbif_apply_dynamic_ot_limit(vbif, &ot_lim, params); - - if (vbif && vbif->ops.get_limit_conf) { - val = vbif->ops.get_limit_conf(vbif, - params->xin_id, params->rd); - if (val == ot_lim) - ot_lim = 0; - } - -exit: - SDE_DEBUG("vbif:%d xin:%d ot_lim:%d\n", - vbif->idx - VBIF_0, params->xin_id, ot_lim); - return ot_lim; -} - -/** - * sde_vbif_set_ot_limit - set OT based on usecase & configuration parameters - * @vbif: Pointer to hardware vbif driver - * @params: Pointer to usecase parameters - * - * Note this function would block waiting for bus halt. - */ -void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, - struct sde_vbif_set_ot_params *params) -{ - struct sde_hw_vbif *vbif = NULL; - struct sde_hw_mdp *mdp; - bool forced_on = false; - u32 ot_lim; - int ret, i; - - if (!sde_kms) { - SDE_ERROR("invalid arguments\n"); - return; - } - mdp = sde_kms->hw_mdp; - - for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) { - if (sde_kms->hw_vbif[i] && - sde_kms->hw_vbif[i]->idx == params->vbif_idx) - vbif = sde_kms->hw_vbif[i]; - } - - if (!vbif || !mdp) { - SDE_DEBUG("invalid arguments vbif %d mdp %d\n", - vbif != 0, mdp != 0); - return; - } - - if (!mdp->ops.setup_clk_force_ctrl || - !vbif->ops.set_limit_conf || - !vbif->ops.set_halt_ctrl) - return; - - ot_lim = _sde_vbif_get_ot_limit(vbif, params) & 0xFF; - - if (ot_lim == 0) - goto exit; - - trace_sde_perf_set_ot(params->num, params->xin_id, ot_lim, - params->vbif_idx); - - forced_on = mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, true); - - vbif->ops.set_limit_conf(vbif, params->xin_id, params->rd, ot_lim); - - vbif->ops.set_halt_ctrl(vbif, params->xin_id, true); - - ret = _sde_vbif_wait_for_xin_halt(vbif, params->xin_id); - if (ret) - MSM_EVT(sde_kms->dev, vbif->idx, params->xin_id); - - vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); - - if (forced_on) - mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false); -exit: - return; -} - int sde_mmu_init(struct sde_kms *sde_kms) { struct msm_mmu *mmu; diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h index 9c35060065db..ca519529792a 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.h +++ b/drivers/gpu/drm/msm/sde/sde_kms.h @@ -149,18 +149,6 @@ struct vsync_info { #define to_sde_kms(x) container_of(x, struct sde_kms, base) -struct sde_vbif_set_ot_params { - u32 xin_id; - u32 num; - u32 width; - u32 height; - u32 frame_rate; - bool rd; - bool is_wfd; - u32 vbif_idx; - u32 clk_ctrl; -}; - struct sde_plane_state { struct drm_plane_state base; @@ -509,12 +497,4 @@ int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder); */ void sde_encoders_init(struct drm_device *dev); -/** - * sde_vbif_set_ot_limit - set OT limit for vbif client - * @sde_kms: SDE handler - * @params: Pointer to OT configuration parameters - */ -void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, - struct sde_vbif_set_ot_params *params); - #endif /* __sde_kms_H__ */ diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 8a1cd1f7e573..939621dc8ed6 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -23,6 +23,7 @@ #include "sde_hw_sspp.h" #include "sde_trace.h" #include "sde_crtc.h" +#include "sde_vbif.h" #define SDE_DEBUG_PLANE(pl, fmt, ...) SDE_DEBUG("plane%d " fmt,\ (pl) ? (pl)->base.base.id : -1, ##__VA_ARGS__) diff --git a/drivers/gpu/drm/msm/sde/sde_vbif.c b/drivers/gpu/drm/msm/sde/sde_vbif.c new file mode 100644 index 000000000000..4e6c0ebf04e2 --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_vbif.c @@ -0,0 +1,209 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ + +#include "sde_vbif.h" +#include "sde_hw_vbif.h" +#include "sde_trace.h" + +/** + * _sde_vbif_wait_for_xin_halt - wait for the xin to halt + * @vbif: Pointer to hardware vbif driver + * @xin_id: Client interface identifier + * @return: 0 if success; error code otherwise + */ +static int _sde_vbif_wait_for_xin_halt(struct sde_hw_vbif *vbif, u32 xin_id) +{ + ktime_t timeout; + bool status; + int rc; + + if (!vbif || !vbif->cap || !vbif->ops.get_halt_ctrl) { + SDE_ERROR("invalid arguments vbif %d\n", vbif != 0); + return -EINVAL; + } + + timeout = ktime_add_us(ktime_get(), vbif->cap->xin_halt_timeout); + for (;;) { + status = vbif->ops.get_halt_ctrl(vbif, xin_id); + if (status) + break; + if (ktime_compare_safe(ktime_get(), timeout) > 0) { + status = vbif->ops.get_halt_ctrl(vbif, xin_id); + break; + } + usleep_range(501, 1000); + } + + if (!status) { + rc = -ETIMEDOUT; + SDE_ERROR("VBIF %d client %d not halting. TIMEDOUT.\n", + vbif->idx - VBIF_0, xin_id); + } else { + rc = 0; + SDE_DEBUG("VBIF %d client %d is halted\n", + vbif->idx - VBIF_0, xin_id); + } + + return rc; +} + +/** + * _sde_vbif_apply_dynamic_ot_limit - determine OT based on usecase parameters + * @vbif: Pointer to hardware vbif driver + * @ot_lim: Pointer to OT limit to be modified + * @params: Pointer to usecase parameters + */ +static void _sde_vbif_apply_dynamic_ot_limit(struct sde_hw_vbif *vbif, + u32 *ot_lim, struct sde_vbif_set_ot_params *params) +{ + u64 pps; + const struct sde_vbif_dynamic_ot_tbl *tbl; + u32 i; + + if (!vbif || !(vbif->cap->features & BIT(SDE_VBIF_QOS_OTLIM))) + return; + + /* Dynamic OT setting done only for WFD */ + if (!params->is_wfd) + return; + + pps = params->frame_rate; + pps *= params->width; + pps *= params->height; + + tbl = params->rd ? &vbif->cap->dynamic_ot_rd_tbl : + &vbif->cap->dynamic_ot_wr_tbl; + + for (i = 0; i < tbl->count; i++) { + if (pps <= tbl->cfg[i].pps) { + *ot_lim = tbl->cfg[i].ot_limit; + break; + } + } + + SDE_DEBUG("vbif:%d xin:%d w:%d h:%d fps:%d pps:%llu ot:%u\n", + vbif->idx - VBIF_0, params->xin_id, + params->width, params->height, params->frame_rate, + pps, *ot_lim); +} + +/** + * _sde_vbif_get_ot_limit - get OT based on usecase & configuration parameters + * @vbif: Pointer to hardware vbif driver + * @params: Pointer to usecase parameters + * @return: OT limit + */ +static u32 _sde_vbif_get_ot_limit(struct sde_hw_vbif *vbif, + struct sde_vbif_set_ot_params *params) +{ + u32 ot_lim = 0; + u32 val; + + if (!vbif || !vbif->cap) { + SDE_ERROR("invalid arguments vbif %d\n", vbif != 0); + return -EINVAL; + } + + if (vbif->cap->default_ot_wr_limit && !params->rd) + ot_lim = vbif->cap->default_ot_wr_limit; + else if (vbif->cap->default_ot_rd_limit && params->rd) + ot_lim = vbif->cap->default_ot_rd_limit; + + /* + * If default ot is not set from dt/catalog, + * then do not configure it. + */ + if (ot_lim == 0) + goto exit; + + /* Modify the limits if the target and the use case requires it */ + _sde_vbif_apply_dynamic_ot_limit(vbif, &ot_lim, params); + + if (vbif && vbif->ops.get_limit_conf) { + val = vbif->ops.get_limit_conf(vbif, + params->xin_id, params->rd); + if (val == ot_lim) + ot_lim = 0; + } + +exit: + SDE_DEBUG("vbif:%d xin:%d ot_lim:%d\n", + vbif->idx - VBIF_0, params->xin_id, ot_lim); + return ot_lim; +} + +/** + * sde_vbif_set_ot_limit - set OT based on usecase & configuration parameters + * @vbif: Pointer to hardware vbif driver + * @params: Pointer to usecase parameters + * + * Note this function would block waiting for bus halt. + */ +void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, + struct sde_vbif_set_ot_params *params) +{ + struct sde_hw_vbif *vbif = NULL; + struct sde_hw_mdp *mdp; + bool forced_on = false; + u32 ot_lim; + int ret, i; + + if (!sde_kms) { + SDE_ERROR("invalid arguments\n"); + return; + } + mdp = sde_kms->hw_mdp; + + for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) { + if (sde_kms->hw_vbif[i] && + sde_kms->hw_vbif[i]->idx == params->vbif_idx) + vbif = sde_kms->hw_vbif[i]; + } + + if (!vbif || !mdp) { + SDE_DEBUG("invalid arguments vbif %d mdp %d\n", + vbif != 0, mdp != 0); + return; + } + + if (!mdp->ops.setup_clk_force_ctrl || + !vbif->ops.set_limit_conf || + !vbif->ops.set_halt_ctrl) + return; + + ot_lim = _sde_vbif_get_ot_limit(vbif, params) & 0xFF; + + if (ot_lim == 0) + goto exit; + + trace_sde_perf_set_ot(params->num, params->xin_id, ot_lim, + params->vbif_idx); + + forced_on = mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, true); + + vbif->ops.set_limit_conf(vbif, params->xin_id, params->rd, ot_lim); + + vbif->ops.set_halt_ctrl(vbif, params->xin_id, true); + + ret = _sde_vbif_wait_for_xin_halt(vbif, params->xin_id); + if (ret) + MSM_EVT(sde_kms->dev, vbif->idx, params->xin_id); + + vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); + + if (forced_on) + mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false); +exit: + return; +} diff --git a/drivers/gpu/drm/msm/sde/sde_vbif.h b/drivers/gpu/drm/msm/sde/sde_vbif.h new file mode 100644 index 000000000000..4a76acd6a2d4 --- /dev/null +++ b/drivers/gpu/drm/msm/sde/sde_vbif.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __SDE_VBIF_H__ +#define __SDE_VBIF_H__ + +#include "sde_kms.h" + +struct sde_vbif_set_ot_params { + u32 xin_id; + u32 num; + u32 width; + u32 height; + u32 frame_rate; + bool rd; + bool is_wfd; + u32 vbif_idx; + u32 clk_ctrl; +}; + +/** + * sde_vbif_set_ot_limit - set OT limit for vbif client + * @sde_kms: SDE handler + * @params: Pointer to OT configuration parameters + */ +void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, + struct sde_vbif_set_ot_params *params); + +#endif /* __SDE_VBIF_H__ */ |
