Remove writeback support from dpu driver as it is not enabled. Writeback support will be added back later based on DRM writeback connector.
Signed-off-by: Rajesh Yadav <rya...@codeaurora.org> --- drivers/gpu/drm/msm/Makefile | 5 - drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 94 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 2 - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 63 - .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 1349 -------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 41 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 77 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c | 3 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 19 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 6 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 12 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 4 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 321 ----- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 186 --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 5 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 42 +- drivers/gpu/drm/msm/disp/dpu1/dpu_wb.c | 767 ----------- drivers/gpu/drm/msm/disp/dpu1/dpu_wb.h | 232 ---- 21 files changed, 23 insertions(+), 3211 deletions(-) delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_wb.c delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_wb.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7fc3974..f4c5951 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -68,7 +68,6 @@ msm-y := \ disp/dpu1/dpu_hw_top.o \ disp/dpu1/dpu_hw_util.o \ disp/dpu1/dpu_hw_vbif.o \ - disp/dpu1/dpu_hw_wb.o \ disp/dpu1/dpu_irq.o \ disp/dpu1/dpu_kms.o \ disp/dpu1/dpu_kms_utils.o \ @@ -99,9 +98,6 @@ msm-y := \ msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o -msm_wb-$(CONFIG_DRM_MSM_WRITEBACK) += disp/dpu1/dpu_wb.o \ - disp/dpu1/dpu_encoder_phys_wb.o - msm-$(CONFIG_DRM_MSM_ROTATOR) += disp/dpu1/dpu_hw_rot.o msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o @@ -134,4 +130,3 @@ msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/pll/dsi_pll_10nm.o endif obj-$(CONFIG_DRM_MSM) += msm.o -obj-$(CONFIG_DRM_MSM_WRITEBACK) += msm_wb.o diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 0f3aa60..39def93 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -440,8 +440,7 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type( if (!cstate) return NRT_CLIENT; - return dpu_crtc_get_intf_mode(crtc) == INTF_MODE_WB_LINE ? NRT_CLIENT : - RT_CLIENT; + return RT_CLIENT; } /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 1d45c8f..7dd609c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1405,15 +1405,6 @@ static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg *catalog, return INTF_MAX; } -static enum dpu_wb dpu_encoder_get_wb(struct dpu_mdss_cfg *catalog, - enum dpu_intf_type type, u32 controller_id) -{ - if (controller_id < catalog->wb_count) - return catalog->wb[controller_id].id; - - return WB_MAX; -} - static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, struct dpu_encoder_phys *phy_enc) { @@ -2144,12 +2135,6 @@ static int _dpu_encoder_status_show(struct seq_file *s, void *data) case INTF_MODE_CMD: seq_puts(s, "mode: command\n"); break; - case INTF_MODE_WB_BLOCK: - seq_puts(s, "mode: wb block\n"); - break; - case INTF_MODE_WB_LINE: - seq_puts(s, "mode: wb line\n"); - break; default: seq_puts(s, "mode: ???\n"); break; @@ -2409,39 +2394,6 @@ static int dpu_encoder_virt_add_phys_encs( return 0; } -static int dpu_encoder_virt_add_phys_enc_wb(struct dpu_encoder_virt *dpu_enc, - struct dpu_enc_phys_init_params *params) -{ -#ifdef CONFIG_DRM_MSM_WRITEBACK - struct dpu_encoder_phys *enc = NULL; - - if (!dpu_enc) { - DPU_ERROR("invalid encoder\n"); - return -EINVAL; - } - - DPU_DEBUG_ENC(dpu_enc, "\n"); - - if (dpu_enc->num_phys_encs + 1 >= ARRAY_SIZE(dpu_enc->phys_encs)) { - DPU_ERROR_ENC(dpu_enc, "too many physical encoders %d\n", - dpu_enc->num_phys_encs); - return -EINVAL; - } - - enc = dpu_encoder_phys_wb_init(params); - - if (IS_ERR_OR_NULL(enc)) { - DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n", - PTR_ERR(enc)); - return enc == 0 ? -EINVAL : PTR_ERR(enc); - } - - dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; - ++dpu_enc->num_phys_encs; -#endif - return 0; -} - static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_kms *dpu_kms, struct msm_display_info *disp_info, @@ -2480,9 +2432,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_DisplayPort) { *drm_enc_mode = DRM_MODE_ENCODER_TMDS; intf_type = INTF_DP; - } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_VIRTUAL) { - *drm_enc_mode = DRM_MODE_ENCODER_VIRTUAL; - intf_type = INTF_WB; } else { DPU_ERROR_ENC(dpu_enc, "unsupported display interface type\n"); return -EINVAL; @@ -2520,42 +2469,21 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, DPU_DEBUG("h_tile_instance %d = %d, split_role %d\n", i, controller_id, phys_params.split_role); - if (intf_type == INTF_WB) { - phys_params.intf_idx = INTF_MAX; - phys_params.wb_idx = dpu_encoder_get_wb( - dpu_kms->catalog, - intf_type, controller_id); - if (phys_params.wb_idx == WB_MAX) { - DPU_ERROR_ENC(dpu_enc, - "could not get wb: type %d, id %d\n", - intf_type, controller_id); - ret = -EINVAL; - } - } else { - phys_params.wb_idx = WB_MAX; - phys_params.intf_idx = dpu_encoder_get_intf( - dpu_kms->catalog, intf_type, - controller_id); - if (phys_params.intf_idx == INTF_MAX) { - DPU_ERROR_ENC(dpu_enc, - "could not get wb: type %d, id %d\n", - intf_type, controller_id); - ret = -EINVAL; - } + phys_params.intf_idx = dpu_encoder_get_intf(dpu_kms->catalog, + intf_type, + controller_id); + if (phys_params.intf_idx == INTF_MAX) { + DPU_ERROR_ENC(dpu_enc, "could not get intf: type %d, id %d\n", + intf_type, controller_id); + ret = -EINVAL; } if (!ret) { - if (intf_type == INTF_WB) - ret = dpu_encoder_virt_add_phys_enc_wb(dpu_enc, - &phys_params); - else - ret = dpu_encoder_virt_add_phys_encs( - disp_info->capabilities, - dpu_enc, - &phys_params); + ret = dpu_encoder_virt_add_phys_encs(disp_info->capabilities, + dpu_enc, + &phys_params); if (ret) - DPU_ERROR_ENC(dpu_enc, - "failed to add phys encs\n"); + DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n"); } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 0339dfd..ce92901 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -32,7 +32,6 @@ /** * Encoder functions and data types * @intfs: Interfaces this encoder is using, INTF_MODE_NONE if unused - * @wbs: Writebacks this encoder is using, INTF_MODE_NONE if unused * @needs_cdm: Encoder requests a CDM based on pixel format conversion needs * @display_num_of_h_tiles: Number of horizontal tiles in case of split * interface @@ -40,7 +39,6 @@ */ struct dpu_encoder_hw_resources { enum dpu_intf_mode intfs[INTF_MAX]; - enum dpu_intf_mode wbs[WB_MAX]; bool needs_cdm; u32 display_num_of_h_tiles; }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 35beefa..15459be 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -22,7 +22,6 @@ #include "dpu_hw_pingpong.h" #include "dpu_hw_ctl.h" #include "dpu_hw_top.h" -#include "dpu_hw_wb.h" #include "dpu_hw_cdm.h" #include "dpu_encoder.h" @@ -303,61 +302,12 @@ struct dpu_encoder_phys_cmd { }; /** - * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to handle - * writeback specific operations - * @base: Baseclass physical encoder structure - * @hw_wb: Hardware interface to the wb registers - * @irq_idx: IRQ interface lookup index - * @wbdone_timeout: Timeout value for writeback done in msec - * @bypass_irqreg: Bypass irq register/unregister if non-zero - * @wbdone_complete: for wbdone irq synchronization - * @wb_cfg: Writeback hardware configuration - * @cdp_cfg: Writeback CDP configuration - * @intf_cfg: Interface hardware configuration - * @wb_roi: Writeback region-of-interest - * @wb_fmt: Writeback pixel format - * @wb_fb: Pointer to current writeback framebuffer - * @wb_aspace: Pointer to current writeback address space - * @frame_count: Counter of completed writeback operations - * @kickoff_count: Counter of issued writeback operations - * @aspace: address space identifier for non-secure/secure domain - * @wb_dev: Pointer to writeback device - * @start_time: Start time of writeback latest request - * @end_time: End time of writeback latest request - * @bo_disable: Buffer object(s) to use during the disabling state - * @fb_disable: Frame buffer to use during the disabling state - */ -struct dpu_encoder_phys_wb { - struct dpu_encoder_phys base; - struct dpu_hw_wb *hw_wb; - int irq_idx; - struct dpu_irq_callback irq_cb; - u32 wbdone_timeout; - u32 bypass_irqreg; - struct completion wbdone_complete; - struct dpu_hw_wb_cfg wb_cfg; - struct dpu_hw_wb_cdp_cfg cdp_cfg; - struct dpu_hw_intf_cfg intf_cfg; - struct dpu_rect wb_roi; - const struct dpu_format *wb_fmt; - struct drm_framebuffer *wb_fb; - u32 frame_count; - u32 kickoff_count; - struct dpu_wb_device *wb_dev; - ktime_t start_time; - ktime_t end_time; - struct drm_gem_object *bo_disable[DPU_MAX_PLANES]; - struct drm_framebuffer *fb_disable; -}; - -/** * struct dpu_enc_phys_init_params - initialization parameters for phys encs * @dpu_kms: Pointer to the dpu_kms top level * @parent: Pointer to the containing virtual encoder * @parent_ops: Callbacks exposed by the parent to the phys_enc * @split_role: Role to play in a split-panel configuration * @intf_idx: Interface index this phys_enc will control - * @wb_idx: Writeback index this phys_enc will control * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes */ struct dpu_enc_phys_init_params { @@ -366,7 +316,6 @@ struct dpu_enc_phys_init_params { struct dpu_encoder_virt_ops parent_ops; enum dpu_enc_split_role split_role; enum dpu_intf intf_idx; - enum dpu_wb wb_idx; spinlock_t *enc_spinlock; }; @@ -399,18 +348,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( struct dpu_enc_phys_init_params *p); /** - * dpu_encoder_phys_wb_init - Construct a new writeback physical encoder - * @p: Pointer to init params structure - * Return: Error code or newly allocated encoder - */ -struct dpu_encoder_phys *dpu_encoder_phys_wb_init( - struct dpu_enc_phys_init_params *p); - -void dpu_encoder_phys_setup_cdm(struct dpu_encoder_phys *phys_enc, - struct drm_framebuffer *fb, const struct dpu_format *format, - struct dpu_rect *wb_roi); - -/** * dpu_encoder_helper_trigger_start - control start helper function * This helper function may be optionally specified by physical * encoders if they require ctl_start triggering. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c deleted file mode 100644 index fd7b5ea..0000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ /dev/null @@ -1,1349 +0,0 @@ -/* - * Copyright (c) 2015-2018 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 <linux/debugfs.h> - -#include "dpu_encoder_phys.h" -#include "dpu_formats.h" -#include "dpu_hw_top.h" -#include "dpu_hw_interrupts.h" -#include "dpu_core_irq.h" -#include "dpu_wb.h" -#include "dpu_vbif.h" -#include "dpu_crtc.h" - -#define to_dpu_encoder_phys_wb(x) \ - container_of(x, struct dpu_encoder_phys_wb, base) - -#define WBID(wb_enc) ((wb_enc) ? wb_enc->wb_dev->wb_idx : -1) - -#define TO_S15D16(_x_) ((_x_) << 7) - -/** - * dpu_rgb2yuv_601l - rgb to yuv color space conversion matrix - * - */ -static struct dpu_csc_cfg dpu_encoder_phys_wb_rgb2yuv_601l = { - { - TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032), - TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1), - TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc) - }, - { 0x00, 0x00, 0x00 }, - { 0x0040, 0x0200, 0x0200 }, - { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff }, - { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 }, -}; - -/** - * dpu_encoder_phys_wb_is_master - report wb always as master encoder - */ -static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys *phys_enc) -{ - return true; -} - -/** - * dpu_encoder_phys_wb_get_intr_type - get interrupt type based on block mode - * @hw_wb: Pointer to h/w writeback driver - */ -static enum dpu_intr_type dpu_encoder_phys_wb_get_intr_type( - struct dpu_hw_wb *hw_wb) -{ - return (hw_wb->caps->features & BIT(DPU_WB_BLOCK_MODE)) ? - DPU_IRQ_TYPE_WB_ROT_COMP : DPU_IRQ_TYPE_WB_WFD_COMP; -} - -/** - * dpu_encoder_phys_wb_set_ot_limit - set OT limit for writeback interface - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_set_ot_limit( - struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - struct dpu_vbif_set_ot_params ot_params; - - memset(&ot_params, 0, sizeof(ot_params)); - ot_params.xin_id = hw_wb->caps->xin_id; - ot_params.num = hw_wb->idx - WB_0; - ot_params.width = wb_enc->wb_roi.w; - ot_params.height = wb_enc->wb_roi.h; - ot_params.is_wfd = true; - ot_params.frame_rate = phys_enc->cached_mode.vrefresh; - ot_params.vbif_idx = hw_wb->caps->vbif_idx; - ot_params.clk_ctrl = hw_wb->caps->clk_ctrl; - ot_params.rd = false; - - dpu_vbif_set_ot_limit(phys_enc->dpu_kms, &ot_params); -} - -/** - * dpu_encoder_phys_wb_set_traffic_shaper - set traffic shaper for writeback - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_set_traffic_shaper( - struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb_cfg *wb_cfg = &wb_enc->wb_cfg; - - /* traffic shaper is only enabled for rotator */ - wb_cfg->ts_cfg.en = false; -} - -/** - * dpu_encoder_phys_wb_set_qos_remap - set QoS remapper for writeback - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_set_qos_remap( - struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc; - struct dpu_hw_wb *hw_wb; - struct drm_crtc *crtc; - struct dpu_vbif_set_qos_params qos_params; - - if (!phys_enc || !phys_enc->parent || !phys_enc->parent->crtc) { - DPU_ERROR("invalid arguments\n"); - return; - } - - wb_enc = to_dpu_encoder_phys_wb(phys_enc); - crtc = phys_enc->parent->crtc; - - if (!wb_enc->hw_wb || !wb_enc->hw_wb->caps) { - DPU_ERROR("invalid writeback hardware\n"); - return; - } - - hw_wb = wb_enc->hw_wb; - - memset(&qos_params, 0, sizeof(qos_params)); - qos_params.vbif_idx = hw_wb->caps->vbif_idx; - qos_params.xin_id = hw_wb->caps->xin_id; - qos_params.clk_ctrl = hw_wb->caps->clk_ctrl; - qos_params.num = hw_wb->idx - WB_0; - qos_params.is_rt = dpu_crtc_get_client_type(crtc) != NRT_CLIENT; - - DPU_DEBUG("[qos_remap] wb:%d vbif:%d xin:%d rt:%d\n", - qos_params.num, - qos_params.vbif_idx, - qos_params.xin_id, qos_params.is_rt); - - dpu_vbif_set_qos_remap(phys_enc->dpu_kms, &qos_params); -} - -/** - * dpu_encoder_phys_setup_cdm - setup chroma down block - * @phys_enc: Pointer to physical encoder - * @fb: Pointer to output framebuffer - * @format: Output format - */ -void dpu_encoder_phys_setup_cdm(struct dpu_encoder_phys *phys_enc, - struct drm_framebuffer *fb, const struct dpu_format *format, - struct dpu_rect *wb_roi) -{ - struct dpu_hw_cdm *hw_cdm; - struct dpu_hw_cdm_cfg *cdm_cfg; - int ret; - - if (!phys_enc || !format) - return; - - cdm_cfg = &phys_enc->cdm_cfg; - hw_cdm = phys_enc->hw_cdm; - if (!hw_cdm) - return; - - if (!DPU_FORMAT_IS_YUV(format)) { - DPU_DEBUG("[cdm_disable fmt:%x]\n", - format->base.pixel_format); - - if (hw_cdm && hw_cdm->ops.disable) - hw_cdm->ops.disable(hw_cdm); - - return; - } - - memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg)); - - if (!wb_roi) - return; - - cdm_cfg->output_width = wb_roi->w; - cdm_cfg->output_height = wb_roi->h; - cdm_cfg->output_fmt = format; - cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB; - cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(format) ? - CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT; - - /* enable 10 bit logic */ - switch (cdm_cfg->output_fmt->chroma_sample) { - case DPU_CHROMA_RGB: - cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; - cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; - break; - case DPU_CHROMA_H2V1: - cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; - cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; - break; - case DPU_CHROMA_420: - cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; - cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE; - break; - case DPU_CHROMA_H1V2: - default: - DPU_ERROR("unsupported chroma sampling type\n"); - cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; - cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; - break; - } - - DPU_DEBUG("[cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n", - cdm_cfg->output_width, - cdm_cfg->output_height, - cdm_cfg->output_fmt->base.pixel_format, - cdm_cfg->output_type, - cdm_cfg->output_bit_depth, - cdm_cfg->h_cdwn_type, - cdm_cfg->v_cdwn_type); - - if (hw_cdm && hw_cdm->ops.setup_csc_data) { - ret = hw_cdm->ops.setup_csc_data(hw_cdm, - &dpu_encoder_phys_wb_rgb2yuv_601l); - if (ret < 0) { - DPU_ERROR("failed to setup CSC %d\n", ret); - return; - } - } - - if (hw_cdm && hw_cdm->ops.setup_cdwn) { - ret = hw_cdm->ops.setup_cdwn(hw_cdm, cdm_cfg); - if (ret < 0) { - DPU_ERROR("failed to setup CDM %d\n", ret); - return; - } - } - - if (hw_cdm && hw_cdm->ops.enable) { - ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg); - if (ret < 0) { - DPU_ERROR("failed to enable CDM %d\n", ret); - return; - } - } -} - -/** - * dpu_encoder_phys_wb_setup_fb - setup output framebuffer - * @phys_enc: Pointer to physical encoder - * @fb: Pointer to output framebuffer - * @wb_roi: Pointer to output region of interest - */ -static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, - struct drm_framebuffer *fb, struct dpu_rect *wb_roi) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb; - struct dpu_hw_wb_cfg *wb_cfg; - struct dpu_hw_wb_cdp_cfg *cdp_cfg; - const struct msm_format *format; - int ret; - struct msm_gem_address_space *aspace; - - if (!phys_enc || !phys_enc->dpu_kms || !phys_enc->dpu_kms->catalog || - !phys_enc->connector) { - DPU_ERROR("invalid encoder\n"); - return; - } - - hw_wb = wb_enc->hw_wb; - wb_cfg = &wb_enc->wb_cfg; - cdp_cfg = &wb_enc->cdp_cfg; - memset(wb_cfg, 0, sizeof(struct dpu_hw_wb_cfg)); - - wb_cfg->intf_mode = phys_enc->intf_mode; - - aspace = phys_enc->dpu_kms->base.aspace; - - ret = msm_framebuffer_prepare(fb, aspace); - if (ret) { - DPU_ERROR("prep fb failed, %d\n", ret); - return; - } - - /* cache framebuffer for cleanup in writeback done */ - wb_enc->wb_fb = fb; - - format = msm_framebuffer_format(fb); - if (!format) { - DPU_DEBUG("invalid format for fb\n"); - return; - } - - wb_cfg->dest.format = dpu_get_dpu_format_ext( - format->pixel_format, - fb->modifier); - if (!wb_cfg->dest.format) { - /* this error should be detected during atomic_check */ - DPU_ERROR("failed to get format %x\n", format->pixel_format); - return; - } - wb_cfg->roi = *wb_roi; - - if (hw_wb->caps->features & BIT(DPU_WB_XY_ROI_OFFSET)) { - ret = dpu_format_populate_layout(aspace, fb, &wb_cfg->dest); - if (ret) { - DPU_DEBUG("failed to populate layout %d\n", ret); - return; - } - wb_cfg->dest.width = fb->width; - wb_cfg->dest.height = fb->height; - wb_cfg->dest.num_planes = wb_cfg->dest.format->num_planes; - } else { - ret = dpu_format_populate_layout_with_roi(aspace, fb, wb_roi, - &wb_cfg->dest); - if (ret) { - /* this error should be detected during atomic_check */ - DPU_DEBUG("failed to populate layout %d\n", ret); - return; - } - } - - if ((wb_cfg->dest.format->fetch_planes == DPU_PLANE_PLANAR) && - (wb_cfg->dest.format->element[0] == C1_B_Cb)) - swap(wb_cfg->dest.plane_addr[1], wb_cfg->dest.plane_addr[2]); - - DPU_DEBUG("[fb_offset:%8.8x,%8.8x,%8.8x,%8.8x]\n", - wb_cfg->dest.plane_addr[0], - wb_cfg->dest.plane_addr[1], - wb_cfg->dest.plane_addr[2], - wb_cfg->dest.plane_addr[3]); - DPU_DEBUG("[fb_stride:%8.8x,%8.8x,%8.8x,%8.8x]\n", - wb_cfg->dest.plane_pitch[0], - wb_cfg->dest.plane_pitch[1], - wb_cfg->dest.plane_pitch[2], - wb_cfg->dest.plane_pitch[3]); - - if (hw_wb->ops.setup_roi) - hw_wb->ops.setup_roi(hw_wb, wb_cfg); - - if (hw_wb->ops.setup_outformat) - hw_wb->ops.setup_outformat(hw_wb, wb_cfg); - - if (hw_wb->ops.setup_cdp) { - memset(cdp_cfg, 0, sizeof(struct dpu_hw_wb_cdp_cfg)); - - cdp_cfg->enable = phys_enc->dpu_kms->catalog->perf.cdp_cfg - [DPU_PERF_CDP_USAGE_NRT].wr_enable; - cdp_cfg->ubwc_meta_enable = - DPU_FORMAT_IS_UBWC(wb_cfg->dest.format); - cdp_cfg->tile_amortize_enable = - DPU_FORMAT_IS_UBWC(wb_cfg->dest.format) || - DPU_FORMAT_IS_TILE(wb_cfg->dest.format); - cdp_cfg->preload_ahead = DPU_WB_CDP_PRELOAD_AHEAD_64; - - hw_wb->ops.setup_cdp(hw_wb, cdp_cfg); - } - - if (hw_wb->ops.setup_outaddress) { - DPU_EVT32(hw_wb->idx, - wb_cfg->dest.width, - wb_cfg->dest.height, - wb_cfg->dest.plane_addr[0], - wb_cfg->dest.plane_size[0], - wb_cfg->dest.plane_addr[1], - wb_cfg->dest.plane_size[1], - wb_cfg->dest.plane_addr[2], - wb_cfg->dest.plane_size[2], - wb_cfg->dest.plane_addr[3], - wb_cfg->dest.plane_size[3]); - hw_wb->ops.setup_outaddress(hw_wb, wb_cfg); - } -} - -/** - * dpu_encoder_phys_wb_setup_cdp - setup chroma down prefetch block - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - struct dpu_hw_intf_cfg *intf_cfg = &wb_enc->intf_cfg; - - memset(intf_cfg, 0, sizeof(struct dpu_hw_intf_cfg)); - - intf_cfg->intf = DPU_NONE; - intf_cfg->wb = hw_wb->idx; - intf_cfg->mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); - - if (phys_enc->hw_ctl && phys_enc->hw_ctl->ops.setup_intf_cfg) - phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, - intf_cfg); -} - -/** - * dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states - * @phys_enc: Pointer to physical encoder - * @crtc_state: Pointer to CRTC atomic state - * @conn_state: Pointer to connector atomic state - */ -static int dpu_encoder_phys_wb_atomic_check( - struct dpu_encoder_phys *phys_enc, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - const struct dpu_wb_cfg *wb_cfg = hw_wb->caps; - struct drm_framebuffer *fb; - const struct dpu_format *fmt; - struct dpu_rect wb_roi; - const struct drm_display_mode *mode = &crtc_state->mode; - int rc; - - DPU_DEBUG("[atomic_check:%d,%d,\"%s\",%d,%d]\n", - hw_wb->idx - WB_0, mode->base.id, mode->name, - mode->hdisplay, mode->vdisplay); - - if (!conn_state || !conn_state->connector) { - DPU_ERROR("invalid connector state\n"); - return -EINVAL; - } else if (conn_state->connector->status != - connector_status_connected) { - DPU_ERROR("connector not connected %d\n", - conn_state->connector->status); - return -EINVAL; - } - - memset(&wb_roi, 0, sizeof(struct dpu_rect)); - - rc = dpu_wb_connector_state_get_output_roi(conn_state, &wb_roi); - if (rc) { - DPU_ERROR("failed to get roi %d\n", rc); - return rc; - } - - DPU_DEBUG("[roi:%u,%u,%u,%u]\n", wb_roi.x, wb_roi.y, - wb_roi.w, wb_roi.h); - - fb = dpu_wb_connector_state_get_output_fb(conn_state); - if (!fb) { - DPU_ERROR("no output framebuffer\n"); - return -EINVAL; - } - - DPU_DEBUG("[fb_id:%u][fb:%u,%u]\n", fb->base.id, - fb->width, fb->height); - - fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier); - if (!fmt) { - DPU_ERROR("unsupported output pixel format:%x\n", - fb->format->format); - return -EINVAL; - } - - DPU_DEBUG("[fb_fmt:%x,%llx]\n", fb->format->format, - fb->modifier); - - if (DPU_FORMAT_IS_YUV(fmt) && - !(wb_cfg->features & BIT(DPU_WB_YUV_CONFIG))) { - DPU_ERROR("invalid output format %x\n", fmt->base.pixel_format); - return -EINVAL; - } - - if (DPU_FORMAT_IS_UBWC(fmt) && - !(wb_cfg->features & BIT(DPU_WB_UBWC))) { - DPU_ERROR("invalid output format %x\n", fmt->base.pixel_format); - return -EINVAL; - } - - if (DPU_FORMAT_IS_YUV(fmt) != !!phys_enc->hw_cdm) - crtc_state->mode_changed = true; - - if (wb_roi.w && wb_roi.h) { - if (wb_roi.w != mode->hdisplay) { - DPU_ERROR("invalid roi w=%d, mode w=%d\n", wb_roi.w, - mode->hdisplay); - return -EINVAL; - } else if (wb_roi.h != mode->vdisplay) { - DPU_ERROR("invalid roi h=%d, mode h=%d\n", wb_roi.h, - mode->vdisplay); - return -EINVAL; - } else if (wb_roi.x + wb_roi.w > fb->width) { - DPU_ERROR("invalid roi x=%d, w=%d, fb w=%d\n", - wb_roi.x, wb_roi.w, fb->width); - return -EINVAL; - } else if (wb_roi.y + wb_roi.h > fb->height) { - DPU_ERROR("invalid roi y=%d, h=%d, fb h=%d\n", - wb_roi.y, wb_roi.h, fb->height); - return -EINVAL; - } else if (wb_roi.w > wb_cfg->sblk->maxlinewidth) { - DPU_ERROR("invalid roi w=%d, maxlinewidth=%u\n", - wb_roi.w, wb_cfg->sblk->maxlinewidth); - return -EINVAL; - } - } else { - if (wb_roi.x || wb_roi.y) { - DPU_ERROR("invalid roi x=%d, y=%d\n", - wb_roi.x, wb_roi.y); - return -EINVAL; - } else if (fb->width != mode->hdisplay) { - DPU_ERROR("invalid fb w=%d, mode w=%d\n", fb->width, - mode->hdisplay); - return -EINVAL; - } else if (fb->height != mode->vdisplay) { - DPU_ERROR("invalid fb h=%d, mode h=%d\n", fb->height, - mode->vdisplay); - return -EINVAL; - } else if (fb->width > wb_cfg->sblk->maxlinewidth) { - DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n", - fb->width, wb_cfg->sblk->maxlinewidth); - return -EINVAL; - } - } - - return 0; -} - -/** - * _dpu_encoder_phys_wb_update_flush - flush hardware update - * @phys_enc: Pointer to physical encoder - */ -static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb; - struct dpu_hw_ctl *hw_ctl; - struct dpu_hw_cdm *hw_cdm; - u32 flush_mask = 0; - - if (!phys_enc) - return; - - hw_wb = wb_enc->hw_wb; - hw_ctl = phys_enc->hw_ctl; - hw_cdm = phys_enc->hw_cdm; - - DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); - - if (!hw_ctl) { - DPU_DEBUG("[wb:%d] no ctl assigned\n", hw_wb->idx - WB_0); - return; - } - - if (hw_ctl->ops.get_bitmask_wb) - hw_ctl->ops.get_bitmask_wb(hw_ctl, &flush_mask, hw_wb->idx); - - if (hw_ctl->ops.get_bitmask_cdm && hw_cdm) - hw_ctl->ops.get_bitmask_cdm(hw_ctl, &flush_mask, hw_cdm->idx); - - if (hw_ctl->ops.update_pending_flush) - hw_ctl->ops.update_pending_flush(hw_ctl, flush_mask); - - if (hw_ctl->ops.get_pending_flush) - flush_mask = hw_ctl->ops.get_pending_flush(hw_ctl); - - DPU_DEBUG("Pending flush mask for CTL_%d is 0x%x, WB %d\n", - hw_ctl->idx - CTL_0, flush_mask, hw_wb->idx - WB_0); -} - -/** - * dpu_encoder_phys_wb_setup - setup writeback encoder - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_setup( - struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - struct drm_display_mode mode = phys_enc->cached_mode; - struct drm_framebuffer *fb; - struct dpu_rect *wb_roi = &wb_enc->wb_roi; - - DPU_DEBUG("[mode_set:%d,%d,\"%s\",%d,%d]\n", - hw_wb->idx - WB_0, mode.base.id, mode.name, - mode.hdisplay, mode.vdisplay); - - memset(wb_roi, 0, sizeof(struct dpu_rect)); - - /* clear writeback framebuffer - will be updated in setup_fb */ - wb_enc->wb_fb = NULL; - - if (phys_enc->enable_state == DPU_ENC_DISABLING) { - fb = wb_enc->fb_disable; - wb_roi->w = 0; - wb_roi->h = 0; - } else { - fb = dpu_wb_get_output_fb(wb_enc->wb_dev); - dpu_wb_get_output_roi(wb_enc->wb_dev, wb_roi); - } - - if (!fb) { - DPU_DEBUG("no output framebuffer\n"); - return; - } - - DPU_DEBUG("[fb_id:%u][fb:%u,%u]\n", fb->base.id, - fb->width, fb->height); - - if (wb_roi->w == 0 || wb_roi->h == 0) { - wb_roi->x = 0; - wb_roi->y = 0; - wb_roi->w = fb->width; - wb_roi->h = fb->height; - } - - DPU_DEBUG("[roi:%u,%u,%u,%u]\n", wb_roi->x, wb_roi->y, - wb_roi->w, wb_roi->h); - - wb_enc->wb_fmt = dpu_get_dpu_format_ext(fb->format->format, - fb->modifier); - if (!wb_enc->wb_fmt) { - DPU_ERROR("unsupported output pixel format: %d\n", - fb->format->format); - return; - } - - DPU_DEBUG("[fb_fmt:%x,%llx]\n", fb->format->format, - fb->modifier); - - dpu_encoder_phys_wb_set_ot_limit(phys_enc); - - dpu_encoder_phys_wb_set_traffic_shaper(phys_enc); - - dpu_encoder_phys_wb_set_qos_remap(phys_enc); - - dpu_encoder_phys_setup_cdm(phys_enc, fb, wb_enc->wb_fmt, wb_roi); - - dpu_encoder_phys_wb_setup_fb(phys_enc, fb, wb_roi); - - dpu_encoder_phys_wb_setup_cdp(phys_enc); -} - -/** - * dpu_encoder_phys_wb_unregister_irq - unregister writeback interrupt handler - * @phys_enc: Pointer to physical encoder - */ -static int dpu_encoder_phys_wb_unregister_irq( - struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - - if (wb_enc->bypass_irqreg) - return 0; - - dpu_core_irq_disable(phys_enc->dpu_kms, &wb_enc->irq_idx, 1); - dpu_core_irq_unregister_callback(phys_enc->dpu_kms, wb_enc->irq_idx, - &wb_enc->irq_cb); - - DPU_DEBUG("un-register IRQ for wb %d, irq_idx=%d\n", - hw_wb->idx - WB_0, - wb_enc->irq_idx); - - return 0; -} - -/** - * dpu_encoder_phys_wb_done_irq - writeback interrupt handler - * @arg: Pointer to writeback encoder - * @irq_idx: interrupt index - */ -static void dpu_encoder_phys_wb_done_irq(void *arg, int irq_idx) -{ - struct dpu_encoder_phys_wb *wb_enc = arg; - struct dpu_encoder_phys *phys_enc = &wb_enc->base; - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - u32 event = 0; - - DPU_DEBUG("[wb:%d,%u]\n", hw_wb->idx - WB_0, - wb_enc->frame_count); - - /* don't notify upper layer for internal commit */ - if (phys_enc->enable_state == DPU_ENC_DISABLING) - goto complete; - - event = DPU_ENCODER_FRAME_EVENT_DONE; - - if (phys_enc->parent_ops.handle_frame_done) - phys_enc->parent_ops.handle_frame_done(phys_enc->parent, - phys_enc, event); - - if (phys_enc->parent_ops.handle_vblank_virt) - phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent, - phys_enc); - - DPU_EVT32_IRQ(DRMID(phys_enc->parent), hw_wb->idx - WB_0, event); - -complete: - complete_all(&wb_enc->wbdone_complete); -} - -/** - * dpu_encoder_phys_wb_register_irq - register writeback interrupt handler - * @phys_enc: Pointer to physical encoder - */ -static int dpu_encoder_phys_wb_register_irq(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - struct dpu_irq_callback *irq_cb = &wb_enc->irq_cb; - enum dpu_intr_type intr_type; - int ret = 0; - - if (wb_enc->bypass_irqreg) - return 0; - - intr_type = dpu_encoder_phys_wb_get_intr_type(hw_wb); - wb_enc->irq_idx = dpu_core_irq_idx_lookup(phys_enc->dpu_kms, - intr_type, hw_wb->idx); - if (wb_enc->irq_idx < 0) { - DPU_ERROR( - "failed to lookup IRQ index for WB_DONE with wb=%d\n", - hw_wb->idx - WB_0); - return -EINVAL; - } - - irq_cb->func = dpu_encoder_phys_wb_done_irq; - irq_cb->arg = wb_enc; - ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, - wb_enc->irq_idx, irq_cb); - if (ret) { - DPU_ERROR("failed to register IRQ callback WB_DONE\n"); - return ret; - } - - ret = dpu_core_irq_enable(phys_enc->dpu_kms, &wb_enc->irq_idx, 1); - if (ret) { - DPU_ERROR( - "failed to enable IRQ for WB_DONE, wb %d, irq_idx=%d\n", - hw_wb->idx - WB_0, - wb_enc->irq_idx); - wb_enc->irq_idx = -EINVAL; - - /* Unregister callback on IRQ enable failure */ - dpu_core_irq_unregister_callback(phys_enc->dpu_kms, - wb_enc->irq_idx, irq_cb); - return ret; - } - - DPU_DEBUG("registered IRQ for wb %d, irq_idx=%d\n", - hw_wb->idx - WB_0, - wb_enc->irq_idx); - - return ret; -} - -/** - * dpu_encoder_phys_wb_mode_set - set display mode - * @phys_enc: Pointer to physical encoder - * @mode: Pointer to requested display mode - * @adj_mode: Pointer to adjusted display mode - */ -static void dpu_encoder_phys_wb_mode_set( - struct dpu_encoder_phys *phys_enc, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_rm *rm = &phys_enc->dpu_kms->rm; - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - struct dpu_rm_hw_iter iter; - int i, instance; - - phys_enc->cached_mode = *adj_mode; - instance = phys_enc->split_role == ENC_ROLE_SLAVE ? 1 : 0; - - DPU_DEBUG("[mode_set_cache:%d,%d,\"%s\",%d,%d]\n", - hw_wb->idx - WB_0, mode->base.id, - mode->name, mode->hdisplay, mode->vdisplay); - - phys_enc->hw_ctl = NULL; - phys_enc->hw_cdm = NULL; - - /* Retrieve previously allocated HW Resources. CTL shouldn't fail */ - dpu_rm_init_hw_iter(&iter, phys_enc->parent->base.id, DPU_HW_BLK_CTL); - for (i = 0; i <= instance; i++) { - dpu_rm_get_hw(rm, &iter); - if (i == instance) - phys_enc->hw_ctl = (struct dpu_hw_ctl *) iter.hw; - } - - if (IS_ERR_OR_NULL(phys_enc->hw_ctl)) { - DPU_ERROR("failed init ctl: %ld\n", PTR_ERR(phys_enc->hw_ctl)); - phys_enc->hw_ctl = NULL; - return; - } - - /* CDM is optional */ - dpu_rm_init_hw_iter(&iter, phys_enc->parent->base.id, DPU_HW_BLK_CDM); - for (i = 0; i <= instance; i++) { - dpu_rm_get_hw(rm, &iter); - if (i == instance) - phys_enc->hw_cdm = (struct dpu_hw_cdm *) iter.hw; - } - - if (IS_ERR(phys_enc->hw_cdm)) { - DPU_ERROR("CDM required but not allocated: %ld\n", - PTR_ERR(phys_enc->hw_cdm)); - phys_enc->hw_ctl = NULL; - } -} - -/** - * dpu_encoder_phys_wb_wait_for_commit_done - wait until request is committed - * @phys_enc: Pointer to physical encoder - */ -static int dpu_encoder_phys_wb_wait_for_commit_done( - struct dpu_encoder_phys *phys_enc) -{ - unsigned long ret; - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - u32 irq_status, event = 0; - u64 wb_time = 0; - int rc = 0; - u32 timeout = max_t(u32, wb_enc->wbdone_timeout, KICKOFF_TIMEOUT_MS); - - /* Return EWOULDBLOCK since we know the wait isn't necessary */ - if (phys_enc->enable_state == DPU_ENC_DISABLED) { - DPU_ERROR("encoder already disabled\n"); - return -EWOULDBLOCK; - } - - DPU_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), wb_enc->frame_count); - - ret = wait_for_completion_timeout(&wb_enc->wbdone_complete, - msecs_to_jiffies(timeout)); - - if (!ret) { - DPU_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), - wb_enc->frame_count); - irq_status = dpu_core_irq_read(phys_enc->dpu_kms, - wb_enc->irq_idx, true); - if (irq_status) { - DPU_DEBUG("wb:%d done but irq not triggered\n", - wb_enc->wb_dev->wb_idx - WB_0); - dpu_encoder_phys_wb_done_irq(wb_enc, wb_enc->irq_idx); - } else { - DPU_ERROR("wb:%d kickoff timed out\n", - wb_enc->wb_dev->wb_idx - WB_0); - - event = DPU_ENCODER_FRAME_EVENT_ERROR; - if (phys_enc->parent_ops.handle_frame_done) - phys_enc->parent_ops.handle_frame_done( - phys_enc->parent, phys_enc, event); - rc = -ETIMEDOUT; - } - } - - dpu_encoder_phys_wb_unregister_irq(phys_enc); - - if (!rc) - wb_enc->end_time = ktime_get(); - - /* once operation is done, disable traffic shaper */ - if (wb_enc->wb_cfg.ts_cfg.en && wb_enc->hw_wb && - wb_enc->hw_wb->ops.setup_trafficshaper) { - wb_enc->wb_cfg.ts_cfg.en = false; - wb_enc->hw_wb->ops.setup_trafficshaper( - wb_enc->hw_wb, &wb_enc->wb_cfg); - } - - /* remove vote for iommu/clk/bus */ - wb_enc->frame_count++; - - if (!rc) { - wb_time = (u64)ktime_to_us(wb_enc->end_time) - - (u64)ktime_to_us(wb_enc->start_time); - DPU_DEBUG("wb:%d took %llu us\n", - wb_enc->wb_dev->wb_idx - WB_0, wb_time); - } - - /* cleanup writeback framebuffer */ - if (wb_enc->wb_fb) { - msm_framebuffer_cleanup(wb_enc->wb_fb, - phys_enc->dpu_kms->base.aspace); - wb_enc->wb_fb = NULL; - } - - DPU_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), wb_enc->frame_count, - wb_time, event, rc); - - return rc; -} - -/** - * dpu_encoder_phys_wb_prepare_for_kickoff - pre-kickoff processing - * @phys_enc: Pointer to physical encoder - * @params: kickoff parameters - */ -static void dpu_encoder_phys_wb_prepare_for_kickoff( - struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_kickoff_params *params) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - int ret; - - DPU_DEBUG("[wb:%d,%u]\n", wb_enc->hw_wb->idx - WB_0, - wb_enc->kickoff_count); - - reinit_completion(&wb_enc->wbdone_complete); - - ret = dpu_encoder_phys_wb_register_irq(phys_enc); - if (ret) { - DPU_ERROR("failed to register irq %d\n", ret); - return; - } - - wb_enc->kickoff_count++; - - /* set OT limit & enable traffic shaper */ - dpu_encoder_phys_wb_setup(phys_enc); - - _dpu_encoder_phys_wb_update_flush(phys_enc); - - /* vote for iommu/clk/bus */ - wb_enc->start_time = ktime_get(); - - DPU_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), wb_enc->kickoff_count); -} - -/** - * dpu_encoder_phys_wb_handle_post_kickoff - post-kickoff processing - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_handle_post_kickoff( - struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - - DPU_DEBUG("[wb:%d]\n", wb_enc->hw_wb->idx - WB_0); - - DPU_EVT32(DRMID(phys_enc->parent), WBID(wb_enc)); -} - -/** - * _dpu_encoder_phys_wb_init_internal_fb - create fb for internal commit - * @wb_enc: Pointer to writeback encoder - * @pixel_format: DRM pixel format - * @width: Desired fb width - * @height: Desired fb height - * @pitch: Desired fb pitch - */ -static int _dpu_encoder_phys_wb_init_internal_fb( - struct dpu_encoder_phys_wb *wb_enc, - uint32_t pixel_format, uint32_t width, - uint32_t height, uint32_t pitch) -{ - struct drm_device *dev; - struct drm_framebuffer *fb; - struct drm_mode_fb_cmd2 mode_cmd; - uint32_t size; - int nplanes, i, ret; - struct msm_gem_address_space *aspace; - - if (!wb_enc || !wb_enc->base.parent || !wb_enc->base.dpu_kms) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - aspace = wb_enc->base.dpu_kms->base.aspace; - if (!aspace) { - DPU_ERROR("invalid address space\n"); - return -EINVAL; - } - - dev = wb_enc->base.dpu_kms->dev; - if (!dev) { - DPU_ERROR("invalid dev\n"); - return -EINVAL; - } - - memset(&mode_cmd, 0, sizeof(mode_cmd)); - mode_cmd.pixel_format = pixel_format; - mode_cmd.width = width; - mode_cmd.height = height; - mode_cmd.pitches[0] = pitch; - - size = dpu_format_get_framebuffer_size(pixel_format, - mode_cmd.width, mode_cmd.height, - mode_cmd.pitches, 0); - if (!size) { - DPU_DEBUG("not creating zero size buffer\n"); - return -EINVAL; - } - - /* allocate gem tracking object */ - nplanes = drm_format_num_planes(pixel_format); - if (nplanes > DPU_MAX_PLANES) { - DPU_ERROR("requested format has too many planes\n"); - return -EINVAL; - } - mutex_lock(&dev->struct_mutex); - wb_enc->bo_disable[0] = msm_gem_new(dev, size, - MSM_BO_SCANOUT | MSM_BO_WC); - mutex_unlock(&dev->struct_mutex); - - if (IS_ERR_OR_NULL(wb_enc->bo_disable[0])) { - ret = PTR_ERR(wb_enc->bo_disable[0]); - wb_enc->bo_disable[0] = NULL; - - DPU_ERROR("failed to create bo, %d\n", ret); - return ret; - } - - for (i = 0; i < nplanes; ++i) { - wb_enc->bo_disable[i] = wb_enc->bo_disable[0]; - mode_cmd.pitches[i] = width * - drm_format_plane_cpp(pixel_format, i); - } - - fb = msm_framebuffer_init(dev, &mode_cmd, wb_enc->bo_disable); - if (IS_ERR_OR_NULL(fb)) { - ret = PTR_ERR(fb); - drm_gem_object_put(wb_enc->bo_disable[0]); - wb_enc->bo_disable[0] = NULL; - - DPU_ERROR("failed to init fb, %d\n", ret); - return ret; - } - - /* prepare the backing buffer now so that it's available later */ - ret = msm_framebuffer_prepare(fb, aspace); - if (!ret) - wb_enc->fb_disable = fb; - return ret; -} - -/** - * _dpu_encoder_phys_wb_destroy_internal_fb - deconstruct internal fb - * @wb_enc: Pointer to writeback encoder - */ -static void _dpu_encoder_phys_wb_destroy_internal_fb( - struct dpu_encoder_phys_wb *wb_enc) -{ - if (!wb_enc) - return; - - if (wb_enc->fb_disable) { - drm_framebuffer_unregister_private(wb_enc->fb_disable); - drm_framebuffer_remove(wb_enc->fb_disable); - wb_enc->fb_disable = NULL; - } - - if (wb_enc->bo_disable[0]) { - drm_gem_object_put(wb_enc->bo_disable[0]); - wb_enc->bo_disable[0] = NULL; - } -} - -/** - * dpu_encoder_phys_wb_enable - enable writeback encoder - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_enable(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - struct drm_device *dev; - struct drm_connector *connector; - - DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); - - if (!wb_enc->base.parent || !wb_enc->base.parent->dev) { - DPU_ERROR("invalid drm device\n"); - return; - } - dev = wb_enc->base.parent->dev; - - /* find associated writeback connector */ - connector = phys_enc->connector; - - if (!connector || connector->encoder != phys_enc->parent) { - DPU_ERROR("failed to find writeback connector\n"); - return; - } - wb_enc->wb_dev = dpu_wb_connector_get_wb(connector); - - phys_enc->enable_state = DPU_ENC_ENABLED; -} - -/** - * dpu_encoder_phys_wb_disable - disable writeback encoder - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_disable(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - - DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); - - if (phys_enc->enable_state == DPU_ENC_DISABLED) { - DPU_ERROR("encoder is already disabled\n"); - return; - } - - if (wb_enc->frame_count != wb_enc->kickoff_count) { - DPU_DEBUG("[wait_for_done: wb:%d, frame:%u, kickoff:%u]\n", - hw_wb->idx - WB_0, wb_enc->frame_count, - wb_enc->kickoff_count); - dpu_encoder_phys_wb_wait_for_commit_done(phys_enc); - } - - if (!phys_enc->hw_ctl || !phys_enc->parent || - !phys_enc->dpu_kms || !wb_enc->fb_disable) { - DPU_DEBUG("invalid enc, skipping extra commit\n"); - goto exit; - } - - /* reset h/w before final flush */ - if (dpu_encoder_helper_hw_release(phys_enc, wb_enc->fb_disable)) - goto exit; - - phys_enc->enable_state = DPU_ENC_DISABLING; - dpu_encoder_phys_wb_prepare_for_kickoff(phys_enc, NULL); - if (phys_enc->hw_ctl->ops.trigger_flush) - phys_enc->hw_ctl->ops.trigger_flush(phys_enc->hw_ctl); - dpu_encoder_helper_trigger_start(phys_enc); - dpu_encoder_phys_wb_wait_for_commit_done(phys_enc); -exit: - phys_enc->enable_state = DPU_ENC_DISABLED; -} - -/** - * dpu_encoder_phys_wb_get_hw_resources - get hardware resources - * @phys_enc: Pointer to physical encoder - * @hw_res: Pointer to encoder resources - */ -static void dpu_encoder_phys_wb_get_hw_resources( - struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_hw_resources *hw_res, - struct drm_connector_state *conn_state) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb; - struct drm_framebuffer *fb; - const struct dpu_format *fmt; - - if (!phys_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } - - fb = dpu_wb_connector_state_get_output_fb(conn_state); - if (!fb) { - DPU_ERROR("no output framebuffer\n"); - return; - } - - fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier); - if (!fmt) { - DPU_ERROR("unsupported output pixel format:%d\n", - fb->format->format); - return; - } - - hw_wb = wb_enc->hw_wb; - hw_res->wbs[hw_wb->idx - WB_0] = phys_enc->intf_mode; - hw_res->needs_cdm = DPU_FORMAT_IS_YUV(fmt); - DPU_DEBUG("[wb:%d] intf_mode=%d needs_cdm=%d\n", hw_wb->idx - WB_0, - hw_res->wbs[hw_wb->idx - WB_0], - hw_res->needs_cdm); -} - -#ifdef CONFIG_DEBUG_FS -/** - * dpu_encoder_phys_wb_init_debugfs - initialize writeback encoder debugfs - * @phys_enc: Pointer to physical encoder - * @debugfs_root: Pointer to virtual encoder's debugfs_root dir - */ -static int dpu_encoder_phys_wb_init_debugfs( - struct dpu_encoder_phys *phys_enc, struct dentry *debugfs_root) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - - if (!phys_enc || !wb_enc->hw_wb || !debugfs_root) - return -EINVAL; - - if (!debugfs_create_u32("wbdone_timeout", 0600, - debugfs_root, &wb_enc->wbdone_timeout)) { - DPU_ERROR("failed to create debugfs/wbdone_timeout\n"); - return -ENOMEM; - } - - if (!debugfs_create_u32("bypass_irqreg", 0600, - debugfs_root, &wb_enc->bypass_irqreg)) { - DPU_ERROR("failed to create debugfs/bypass_irqreg\n"); - return -ENOMEM; - } - - return 0; -} -#else -static int dpu_encoder_phys_wb_init_debugfs( - struct dpu_encoder_phys *phys_enc, struct dentry *debugfs_root) -{ - return 0; -} -#endif - -static int dpu_encoder_phys_wb_late_register(struct dpu_encoder_phys *phys_enc, - struct dentry *debugfs_root) -{ - return dpu_encoder_phys_wb_init_debugfs(phys_enc, debugfs_root); -} - -/** - * dpu_encoder_phys_wb_destroy - destroy writeback encoder - * @phys_enc: Pointer to physical encoder - */ -static void dpu_encoder_phys_wb_destroy(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct dpu_hw_wb *hw_wb = wb_enc->hw_wb; - - DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); - - if (!phys_enc) - return; - - _dpu_encoder_phys_wb_destroy_internal_fb(wb_enc); - - kfree(wb_enc); -} - -/** - * dpu_encoder_phys_wb_init_ops - initialize writeback operations - * @ops: Pointer to encoder operation table - */ -static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops) -{ - ops->late_register = dpu_encoder_phys_wb_late_register; - ops->is_master = dpu_encoder_phys_wb_is_master; - ops->mode_set = dpu_encoder_phys_wb_mode_set; - ops->enable = dpu_encoder_phys_wb_enable; - ops->disable = dpu_encoder_phys_wb_disable; - ops->destroy = dpu_encoder_phys_wb_destroy; - ops->atomic_check = dpu_encoder_phys_wb_atomic_check; - ops->get_hw_resources = dpu_encoder_phys_wb_get_hw_resources; - ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done; - ops->prepare_for_kickoff = dpu_encoder_phys_wb_prepare_for_kickoff; - ops->handle_post_kickoff = dpu_encoder_phys_wb_handle_post_kickoff; - ops->trigger_start = dpu_encoder_helper_trigger_start; - ops->hw_reset = dpu_encoder_helper_hw_reset; -} - -/** - * dpu_encoder_phys_wb_init - initialize writeback encoder - * @init: Pointer to init info structure with initialization params - */ -struct dpu_encoder_phys *dpu_encoder_phys_wb_init( - struct dpu_enc_phys_init_params *p) -{ - struct dpu_encoder_phys *phys_enc; - struct dpu_encoder_phys_wb *wb_enc; - struct dpu_hw_mdp *hw_mdp; - int ret = 0; - - DPU_DEBUG("\n"); - - if (!p || !p->parent) { - DPU_ERROR("invalid params\n"); - ret = -EINVAL; - goto fail_alloc; - } - - wb_enc = kzalloc(sizeof(*wb_enc), GFP_KERNEL); - if (!wb_enc) { - DPU_ERROR("failed to allocate wb enc\n"); - ret = -ENOMEM; - goto fail_alloc; - } - wb_enc->irq_idx = -EINVAL; - wb_enc->wbdone_timeout = KICKOFF_TIMEOUT_MS; - init_completion(&wb_enc->wbdone_complete); - - phys_enc = &wb_enc->base; - - hw_mdp = dpu_rm_get_mdp(&p->dpu_kms->rm); - if (IS_ERR_OR_NULL(hw_mdp)) { - ret = PTR_ERR(hw_mdp); - DPU_ERROR("failed to init hw_top: %d\n", ret); - goto fail_mdp_init; - } - phys_enc->hw_mdptop = hw_mdp; - - /** - * hw_wb resource permanently assigned to this encoder - * Other resources allocated at atomic commit time by use case - */ - if (p->wb_idx != DPU_NONE) { - struct dpu_rm_hw_iter iter; - - dpu_rm_init_hw_iter(&iter, 0, DPU_HW_BLK_WB); - while (dpu_rm_get_hw(&p->dpu_kms->rm, &iter)) { - struct dpu_hw_wb *hw_wb = (struct dpu_hw_wb *)iter.hw; - - if (hw_wb->idx == p->wb_idx) { - wb_enc->hw_wb = hw_wb; - break; - } - } - - if (!wb_enc->hw_wb) { - ret = -EINVAL; - DPU_ERROR("failed to init hw_wb%d\n", p->wb_idx - WB_0); - goto fail_wb_init; - } - } else { - ret = -EINVAL; - DPU_ERROR("invalid wb_idx\n"); - goto fail_wb_check; - } - - dpu_encoder_phys_wb_init_ops(&phys_enc->ops); - phys_enc->parent = p->parent; - phys_enc->parent_ops = p->parent_ops; - phys_enc->dpu_kms = p->dpu_kms; - phys_enc->split_role = p->split_role; - phys_enc->intf_mode = INTF_MODE_WB_LINE; - phys_enc->intf_idx = p->intf_idx; - phys_enc->enc_spinlock = p->enc_spinlock; - INIT_LIST_HEAD(&wb_enc->irq_cb.list); - - /* create internal buffer for disable logic */ - if (_dpu_encoder_phys_wb_init_internal_fb(wb_enc, - DRM_FORMAT_RGB888, 2, 1, 6)) { - DPU_ERROR("failed to init internal fb\n"); - goto fail_wb_init; - } - - DPU_DEBUG("Created dpu_encoder_phys_wb for wb %d\n", - wb_enc->hw_wb->idx - WB_0); - - return phys_enc; - -fail_wb_init: -fail_wb_check: -fail_mdp_init: - kfree(wb_enc); -fail_alloc: - return ERR_PTR(ret); -} - diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 7c1d84c..3da8c2d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -37,10 +37,6 @@ #define PINGPONG_SDM845_SPLIT_MASK \ (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) -#define WB2_SDM845_MASK \ - (BIT(DPU_WB_LINE_MODE) | BIT(DPU_WB_TRAFFIC_SHAPER) | BIT(DPU_WB_CDP) |\ - BIT(DPU_WB_YUV_CONFIG) | BIT(DPU_WB_QOS_8LVL) | BIT(DPU_WB_UBWC)) - #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024) #define DEFAULT_DPU_LINE_WIDTH 2048 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560 @@ -92,8 +88,6 @@ .reg_off = 0x2BC, .bit_off = 8}, .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x2C4, .bit_off = 8}, - .clk_ctrls[DPU_CLK_CTRL_WB2] = { - .reg_off = 0x3b8, .bit_off = 24}, }, }; @@ -339,33 +333,14 @@ }; /************************************************************* - * WB and CDM sub blocks config + * CDM sub blocks config *************************************************************/ -/* Writeback 2 capability */ -static const struct dpu_wb_sub_blocks sdm845_wb2_sblk = { - .maxlinewidth = 4096, -}; - -static struct dpu_wb_cfg sdm845_wb[] = { - { - .name = "wb_2", .id = WB_2, - .base = 0x65000, .len = 0x2c8, - .features = WB2_SDM845_MASK, - .sblk = &sdm845_wb2_sblk, - .format_list = wb2_formats, - .vbif_idx = VBIF_NRT, - .xin_id = 6, - .clk_ctrl = DPU_CLK_CTRL_WB2 - }, -}; - static struct dpu_cdm_cfg sdm845_cdm[] = { { .name = "cdm_0", .id = CDM_0, .base = 0x79200, .len = 0x224, .features = 0, - .intf_connect = BIT(INTF_3), - .wb_connect = BIT(WB_2) + .intf_connect = BIT(INTF_3) }, }; @@ -432,11 +407,6 @@ {.fl = 0, .lut = 0x0}, }; -static struct dpu_qos_lut_entry sdm845_qos_cwb[] = { - {.fl = 0, .lut = 0x7530000000000000}, -}; - - static struct dpu_perf_cfg sdm845_perf_data = { .max_bw_low = 6800000, .max_bw_high = 6800000, @@ -458,7 +428,7 @@ .downscaling_prefill_lines = 1, .amortizable_threshold = 25, .min_prefill_lines = 24, - .danger_lut_tbl = {0xf, 0xffff, 0x0, 0x0}, + .danger_lut_tbl = {0xf, 0xffff, 0x0}, .qos_lut_tbl = { {.nentry = ARRAY_SIZE(sdm845_qos_linear), .entries = sdm845_qos_linear @@ -469,9 +439,6 @@ {.nentry = ARRAY_SIZE(sdm845_qos_nrt), .entries = sdm845_qos_nrt }, - {.nentry = ARRAY_SIZE(sdm845_qos_cwb), - .entries = sdm845_qos_cwb - }, }, .cdp_cfg = { {.rd_enable = 1, .wr_enable = 1}, @@ -507,8 +474,6 @@ void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg) .cdm = sdm845_cdm, .intf_count = ARRAY_SIZE(sdm845_intf), .intf = sdm845_intf, - .wb_count = ARRAY_SIZE(sdm845_wb), - .wb = sdm845_wb, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, .reg_dma_count = 1, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 12c544b..f0cb0d4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -179,46 +179,6 @@ enum { }; /** - * WB sub-blocks and features - * @DPU_WB_LINE_MODE Writeback module supports line/linear mode - * @DPU_WB_BLOCK_MODE Writeback module supports block mode read - * @DPU_WB_ROTATE rotation support,this is available if writeback - * supports block mode read - * @DPU_WB_CSC Writeback color conversion block support - * @DPU_WB_CHROMA_DOWN, Writeback chroma down block, - * @DPU_WB_DOWNSCALE, Writeback integer downscaler, - * @DPU_WB_DITHER, Dither block - * @DPU_WB_TRAFFIC_SHAPER, Writeback traffic shaper bloc - * @DPU_WB_UBWC, Writeback Universal bandwidth compression - * @DPU_WB_YUV_CONFIG Writeback supports output of YUV colorspace - * @DPU_WB_PIPE_ALPHA Writeback supports pipe alpha - * @DPU_WB_XY_ROI_OFFSET Writeback supports x/y-offset of out ROI in - * the destination image - * @DPU_WB_QOS, Writeback supports QoS control, danger/safe/creq - * @DPU_WB_QOS_8LVL, Writeback supports 8-level QoS control - * @DPU_WB_CDP Writeback supports client driven prefetch - * @DPU_WB_MAX maximum value - */ -enum { - DPU_WB_LINE_MODE = 0x1, - DPU_WB_BLOCK_MODE, - DPU_WB_ROTATE = DPU_WB_BLOCK_MODE, - DPU_WB_CSC, - DPU_WB_CHROMA_DOWN, - DPU_WB_DOWNSCALE, - DPU_WB_DITHER, - DPU_WB_TRAFFIC_SHAPER, - DPU_WB_UBWC, - DPU_WB_YUV_CONFIG, - DPU_WB_PIPE_ALPHA, - DPU_WB_XY_ROI_OFFSET, - DPU_WB_QOS, - DPU_WB_QOS_8LVL, - DPU_WB_CDP, - DPU_WB_MAX -}; - -/** * VBIF sub-blocks and features * @DPU_VBIF_QOS_OTLIM VBIF supports OT Limit * @DPU_VBIF_QOS_REMAP VBIF supports QoS priority remap @@ -309,7 +269,6 @@ enum dpu_qos_lut_usage { DPU_QOS_LUT_USAGE_LINEAR, DPU_QOS_LUT_USAGE_MACROTILE, DPU_QOS_LUT_USAGE_NRT, - DPU_QOS_LUT_USAGE_CWB, DPU_QOS_LUT_USAGE_MAX, }; @@ -431,10 +390,6 @@ struct dpu_pingpong_sub_blks { struct dpu_pp_blk dither; }; -struct dpu_wb_sub_blocks { - u32 maxlinewidth; -}; - /** * dpu_clk_ctrl_type - Defines top level clock control signals */ @@ -453,11 +408,7 @@ enum dpu_clk_ctrl_type { DPU_CLK_CTRL_DMA1, DPU_CLK_CTRL_CURSOR0, DPU_CLK_CTRL_CURSOR1, - DPU_CLK_CTRL_WB0, - DPU_CLK_CTRL_WB1, - DPU_CLK_CTRL_WB2, DPU_CLK_CTRL_INLINE_ROT0_SSPP, - DPU_CLK_CTRL_INLINE_ROT0_WB, DPU_CLK_CTRL_MAX, }; @@ -584,12 +535,10 @@ struct dpu_pingpong_cfg { * @base register offset of this block * @features bit mask identifying sub-blocks/features * @intf_connect Bitmask of INTF IDs this CDM can connect to - * @wb_connect: Bitmask of Writeback IDs this CDM can connect to */ struct dpu_cdm_cfg { DPU_HW_BLK_INFO; unsigned long intf_connect; - unsigned long wb_connect; }; /** @@ -609,26 +558,6 @@ struct dpu_intf_cfg { }; /** - * struct dpu_wb_cfg - information of writeback blocks - * @id enum identifying this block - * @base register offset of this block - * @features bit mask identifying sub-blocks/features - * @sblk sub-block information - * @format_list: Pointer to list of supported formats - * @vbif_idx vbif identifier - * @xin_id client interface identifier - * @clk_ctrl clock control identifier - */ -struct dpu_wb_cfg { - DPU_HW_BLK_INFO; - const struct dpu_wb_sub_blocks *sblk; - const struct dpu_format_extended *format_list; - u32 vbif_idx; - u32 xin_id; - enum dpu_clk_ctrl_type clk_ctrl; -}; - -/** * struct dpu_vbif_dynamic_ot_cfg - dynamic OT setting * @pps pixel per seconds * @ot_limit OT limit to use up to specified pixel per second @@ -781,7 +710,6 @@ struct dpu_perf_cfg { * @dma_formats Supported formats for dma pipe * @cursor_formats Supported formats for cursor pipe * @vig_formats Supported formats for vig pipe - * @wb_formats Supported formats for wb */ struct dpu_mdss_cfg { u32 hwversion; @@ -812,9 +740,6 @@ struct dpu_mdss_cfg { u32 intf_count; struct dpu_intf_cfg *intf; - u32 wb_count; - struct dpu_wb_cfg *wb; - u32 vbif_count; struct dpu_vbif_cfg *vbif; @@ -829,7 +754,6 @@ struct dpu_mdss_cfg { struct dpu_format_extended *dma_formats; struct dpu_format_extended *cursor_formats; struct dpu_format_extended *vig_formats; - struct dpu_format_extended *wb_formats; }; struct dpu_mdss_hw_cfg_handler { @@ -851,7 +775,6 @@ struct dpu_mdss_hw_cfg_handler { #define BLK_PINGPONG(s) ((s)->pingpong) #define BLK_CDM(s) ((s)->cdm) #define BLK_INTF(s) ((s)->intf) -#define BLK_WB(s) ((s)->wb) #define BLK_AD(s) ((s)->ad) /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c index 771ffe4..24b0dbc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c @@ -235,9 +235,6 @@ int dpu_hw_cdm_enable(struct dpu_hw_cdm *ctx, opmode = BIT(0); opmode |= (fmt->chroma_sample << 1); cdm_cfg.intf_en = true; - } else { - opmode = 0; - cdm_cfg.wb_en = true; } csc |= BIT(2); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 4865427..ad02316 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -224,21 +224,6 @@ static inline int dpu_hw_ctl_get_bitmask_intf(struct dpu_hw_ctl *ctx, return 0; } -static inline int dpu_hw_ctl_get_bitmask_wb(struct dpu_hw_ctl *ctx, - u32 *flushbits, enum dpu_wb wb) -{ - switch (wb) { - case WB_0: - case WB_1: - case WB_2: - *flushbits |= BIT(16); - break; - default: - return -EINVAL; - } - return 0; -} - static inline int dpu_hw_ctl_get_bitmask_cdm(struct dpu_hw_ctl *ctx, u32 *flushbits, enum dpu_cdm cdm) { @@ -460,9 +445,6 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, intf_cfg |= (cfg->intf & 0xF) << 4; - if (cfg->wb) - intf_cfg |= (cfg->wb & 0x3) + 2; - if (cfg->mode_3d) { intf_cfg |= BIT(19); intf_cfg |= (cfg->mode_3d - 0x1) << 20; @@ -504,7 +486,6 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer; ops->get_bitmask_intf = dpu_hw_ctl_get_bitmask_intf; ops->get_bitmask_cdm = dpu_hw_ctl_get_bitmask_cdm; - ops->get_bitmask_wb = dpu_hw_ctl_get_bitmask_wb; }; static struct dpu_hw_blk_ops dpu_hw_ops = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index b773a5a..c66a71f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -44,14 +44,12 @@ struct dpu_hw_stage_cfg { /** * struct dpu_hw_intf_cfg :Describes how the DPU writes data to output interface * @intf : Interface id - * @wb: Writeback id * @mode_3d: 3d mux configuration * @intf_mode_sel: Interface mode, cmd / vid * @stream_sel: Stream selection for multi-stream interfaces */ struct dpu_hw_intf_cfg { enum dpu_intf intf; - enum dpu_wb wb; enum dpu_3d_blend_mode mode_3d; enum dpu_ctl_mode_sel intf_mode_sel; int stream_sel; @@ -148,10 +146,6 @@ struct dpu_hw_ctl_ops { u32 *flushbits, enum dpu_cdm blk); - int (*get_bitmask_wb)(struct dpu_hw_ctl *ctx, - u32 *flushbits, - enum dpu_wb blk); - /** * Set all blend stages to disabled * @ctx : ctl path ctx pointer diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index 8f7f932..115eeed 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -109,9 +109,7 @@ static void dpu_hw_setup_cdm_output(struct dpu_hw_mdp *mdp, c = &mdp->hw; - if (cfg->wb_en) - out_ctl |= BIT(24); - else if (cfg->intf_en) + if (cfg->intf_en) out_ctl |= BIT(19); DPU_REG_WRITE(c, MDP_OUT_CTL_0, out_ctl); @@ -178,10 +176,6 @@ static void dpu_hw_get_danger_status(struct dpu_hw_mdp *mdp, status->sspp[SSPP_DMA3] = (value >> 30) & 0x3; status->sspp[SSPP_CURSOR0] = (value >> 24) & 0x3; status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x3; - status->wb[WB_0] = 0; - status->wb[WB_1] = 0; - status->wb[WB_2] = (value >> 2) & 0x3; - status->wb[WB_3] = 0; } static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp, @@ -279,10 +273,6 @@ static void dpu_hw_get_safe_status(struct dpu_hw_mdp *mdp, status->sspp[SSPP_DMA3] = (value >> 30) & 0x1; status->sspp[SSPP_CURSOR0] = (value >> 24) & 0x1; status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x1; - status->wb[WB_0] = 0; - status->wb[WB_1] = 0; - status->wb[WB_2] = (value >> 2) & 0x1; - status->wb[WB_3] = 0; } void dpu_hw_reset_ubwc(struct dpu_hw_mdp *mdp, struct dpu_mdss_cfg *m) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h index 5429cd5..899925a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h @@ -53,11 +53,9 @@ struct split_pipe_cfg { /** * struct cdm_output_cfg: output configuration for cdm - * @wb_en : enable/disable writeback output * @intf_en : enable/disable interface output */ struct cdm_output_cfg { - bool wb_en; bool intf_en; }; @@ -65,12 +63,10 @@ struct cdm_output_cfg { * struct dpu_danger_safe_status: danger and safe status signals * @mdp: top level status * @sspp: source pipe status - * @wb: writebck output status */ struct dpu_danger_safe_status { u8 mdp; u8 sspp[SSPP_MAX]; - u8 wb[WB_MAX]; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c deleted file mode 100644 index 90b2aae..0000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ /dev/null @@ -1,321 +0,0 @@ -/* Copyright (c) 2015-2018, 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. - */ - -#include "dpu_hw_mdss.h" -#include "dpu_hwio.h" -#include "dpu_hw_catalog.h" -#include "dpu_hw_wb.h" -#include "dpu_formats.h" -#include "dpu_dbg.h" -#include "dpu_kms.h" - -#define WB_DST_FORMAT 0x000 -#define WB_DST_OP_MODE 0x004 -#define WB_DST_PACK_PATTERN 0x008 -#define WB_DST0_ADDR 0x00C -#define WB_DST1_ADDR 0x010 -#define WB_DST2_ADDR 0x014 -#define WB_DST3_ADDR 0x018 -#define WB_DST_YSTRIDE0 0x01C -#define WB_DST_YSTRIDE1 0x020 -#define WB_DST_YSTRIDE1 0x020 -#define WB_DST_DITHER_BITDEPTH 0x024 -#define WB_DST_MATRIX_ROW0 0x030 -#define WB_DST_MATRIX_ROW1 0x034 -#define WB_DST_MATRIX_ROW2 0x038 -#define WB_DST_MATRIX_ROW3 0x03C -#define WB_DST_WRITE_CONFIG 0x048 -#define WB_ROTATION_DNSCALER 0x050 -#define WB_ROTATOR_PIPE_DOWNSCALER 0x054 -#define WB_N16_INIT_PHASE_X_C03 0x060 -#define WB_N16_INIT_PHASE_X_C12 0x064 -#define WB_N16_INIT_PHASE_Y_C03 0x068 -#define WB_N16_INIT_PHASE_Y_C12 0x06C -#define WB_OUT_SIZE 0x074 -#define WB_ALPHA_X_VALUE 0x078 -#define WB_DANGER_LUT 0x084 -#define WB_SAFE_LUT 0x088 -#define WB_QOS_CTRL 0x090 -#define WB_CREQ_LUT_0 0x098 -#define WB_CREQ_LUT_1 0x09C -#define WB_UBWC_STATIC_CTRL 0x144 -#define WB_CSC_BASE 0x260 -#define WB_DST_ADDR_SW_STATUS 0x2B0 -#define WB_CDP_CNTL 0x2B4 -#define WB_OUT_IMAGE_SIZE 0x2C0 -#define WB_OUT_XY 0x2C4 - -/* WB_QOS_CTRL */ -#define WB_QOS_CTRL_DANGER_SAFE_EN BIT(0) - -static struct dpu_wb_cfg *_wb_offset(enum dpu_wb wb, - struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->wb_count; i++) { - if (wb == m->wb[i].id) { - b->base_off = addr; - b->blk_off = m->wb[i].base; - b->length = m->wb[i].len; - b->hwversion = m->hwversion; - b->log_mask = DPU_DBG_MASK_WB; - return &m->wb[i]; - } - } - return ERR_PTR(-EINVAL); -} - -static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *data) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - - DPU_REG_WRITE(c, WB_DST0_ADDR, data->dest.plane_addr[0]); - DPU_REG_WRITE(c, WB_DST1_ADDR, data->dest.plane_addr[1]); - DPU_REG_WRITE(c, WB_DST2_ADDR, data->dest.plane_addr[2]); - DPU_REG_WRITE(c, WB_DST3_ADDR, data->dest.plane_addr[3]); -} - -static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *data) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - const struct dpu_format *fmt = data->dest.format; - u32 dst_format, pattern, ystride0, ystride1, outsize, chroma_samp; - u32 write_config = 0; - u32 opmode = 0; - u32 dst_addr_sw = 0; - - chroma_samp = fmt->chroma_sample; - - dst_format = (chroma_samp << 23) | - (fmt->fetch_planes << 19) | - (fmt->bits[C3_ALPHA] << 6) | - (fmt->bits[C2_R_Cr] << 4) | - (fmt->bits[C1_B_Cb] << 2) | - (fmt->bits[C0_G_Y] << 0); - - if (fmt->bits[C3_ALPHA] || fmt->alpha_enable) { - dst_format |= BIT(8); /* DSTC3_EN */ - if (!fmt->alpha_enable || - !(ctx->caps->features & BIT(DPU_WB_PIPE_ALPHA))) - dst_format |= BIT(14); /* DST_ALPHA_X */ - } - - if (DPU_FORMAT_IS_YUV(fmt) && - (ctx->caps->features & BIT(DPU_WB_YUV_CONFIG))) - dst_format |= BIT(15); - - if (DPU_FORMAT_IS_DX(fmt)) - dst_format |= BIT(21); - - pattern = (fmt->element[3] << 24) | - (fmt->element[2] << 16) | - (fmt->element[1] << 8) | - (fmt->element[0] << 0); - - dst_format |= (fmt->unpack_align_msb << 18) | - (fmt->unpack_tight << 17) | - ((fmt->unpack_count - 1) << 12) | - ((fmt->bpp - 1) << 9); - - ystride0 = data->dest.plane_pitch[0] | - (data->dest.plane_pitch[1] << 16); - ystride1 = data->dest.plane_pitch[2] | - (data->dest.plane_pitch[3] << 16); - - if (data->roi.h && data->roi.w) - outsize = (data->roi.h << 16) | data->roi.w; - else - outsize = (data->dest.height << 16) | data->dest.width; - - if (DPU_FORMAT_IS_UBWC(fmt)) { - opmode |= BIT(0); - dst_format |= BIT(31); - write_config |= (ctx->mdp->highest_bank_bit << 8); - if (fmt->base.pixel_format == DRM_FORMAT_RGB565) - write_config |= 0x8; - if (IS_UBWC_20_SUPPORTED(ctx->catalog->caps->ubwc_version)) - DPU_REG_WRITE(c, WB_UBWC_STATIC_CTRL, - (ctx->mdp->ubwc_swizzle << 0) | - (ctx->mdp->highest_bank_bit << 4)); - } - - DPU_REG_WRITE(c, WB_ALPHA_X_VALUE, 0xFF); - DPU_REG_WRITE(c, WB_DST_FORMAT, dst_format); - DPU_REG_WRITE(c, WB_DST_OP_MODE, opmode); - DPU_REG_WRITE(c, WB_DST_PACK_PATTERN, pattern); - DPU_REG_WRITE(c, WB_DST_YSTRIDE0, ystride0); - DPU_REG_WRITE(c, WB_DST_YSTRIDE1, ystride1); - DPU_REG_WRITE(c, WB_OUT_SIZE, outsize); - DPU_REG_WRITE(c, WB_DST_WRITE_CONFIG, write_config); - DPU_REG_WRITE(c, WB_DST_ADDR_SW_STATUS, dst_addr_sw); -} - -static void dpu_hw_wb_roi(struct dpu_hw_wb *ctx, struct dpu_hw_wb_cfg *wb) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - u32 image_size, out_size, out_xy; - - image_size = (wb->dest.height << 16) | wb->dest.width; - out_xy = (wb->roi.y << 16) | wb->roi.x; - out_size = (wb->roi.h << 16) | wb->roi.w; - - DPU_REG_WRITE(c, WB_OUT_IMAGE_SIZE, image_size); - DPU_REG_WRITE(c, WB_OUT_XY, out_xy); - DPU_REG_WRITE(c, WB_OUT_SIZE, out_size); -} - -static void dpu_hw_wb_setup_danger_safe_lut(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_qos_cfg *cfg) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - - if (!ctx || !cfg) - return; - - DPU_REG_WRITE(c, WB_DANGER_LUT, cfg->danger_lut); - DPU_REG_WRITE(c, WB_SAFE_LUT, cfg->safe_lut); -} - -static void dpu_hw_wb_setup_creq_lut(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_qos_cfg *cfg) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - - if (!ctx || !cfg) - return; - - if (ctx->caps && test_bit(DPU_WB_QOS_8LVL, &ctx->caps->features)) { - DPU_REG_WRITE(c, WB_CREQ_LUT_0, cfg->creq_lut); - DPU_REG_WRITE(c, WB_CREQ_LUT_1, cfg->creq_lut >> 32); - } -} - -static void dpu_hw_wb_setup_qos_ctrl(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_qos_cfg *cfg) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - u32 qos_ctrl = 0; - - if (!ctx || !cfg) - return; - - if (cfg->danger_safe_en) - qos_ctrl |= WB_QOS_CTRL_DANGER_SAFE_EN; - - DPU_REG_WRITE(c, WB_QOS_CTRL, qos_ctrl); -} - -static void dpu_hw_wb_setup_cdp(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cdp_cfg *cfg) -{ - struct dpu_hw_blk_reg_map *c; - u32 cdp_cntl = 0; - - if (!ctx || !cfg) - return; - - c = &ctx->hw; - - if (cfg->enable) - cdp_cntl |= BIT(0); - if (cfg->ubwc_meta_enable) - cdp_cntl |= BIT(1); - if (cfg->preload_ahead == DPU_WB_CDP_PRELOAD_AHEAD_64) - cdp_cntl |= BIT(3); - - DPU_REG_WRITE(c, WB_CDP_CNTL, cdp_cntl); -} - -static void _setup_wb_ops(struct dpu_hw_wb_ops *ops, - unsigned long features) -{ - ops->setup_outaddress = dpu_hw_wb_setup_outaddress; - ops->setup_outformat = dpu_hw_wb_setup_format; - - if (test_bit(DPU_WB_XY_ROI_OFFSET, &features)) - ops->setup_roi = dpu_hw_wb_roi; - - if (test_bit(DPU_WB_QOS, &features)) { - ops->setup_danger_safe_lut = - dpu_hw_wb_setup_danger_safe_lut; - ops->setup_creq_lut = dpu_hw_wb_setup_creq_lut; - ops->setup_qos_ctrl = dpu_hw_wb_setup_qos_ctrl; - } - - if (test_bit(DPU_WB_CDP, &features)) - ops->setup_cdp = dpu_hw_wb_setup_cdp; -} - -static struct dpu_hw_blk_ops dpu_hw_ops = { - .start = NULL, - .stop = NULL, -}; - -struct dpu_hw_wb *dpu_hw_wb_init(enum dpu_wb idx, - void __iomem *addr, - struct dpu_mdss_cfg *m, - struct dpu_hw_mdp *hw_mdp) -{ - struct dpu_hw_wb *c; - struct dpu_wb_cfg *cfg; - int rc; - - if (!addr || !m || !hw_mdp) - return ERR_PTR(-EINVAL); - - c = kzalloc(sizeof(*c), GFP_KERNEL); - if (!c) - return ERR_PTR(-ENOMEM); - - cfg = _wb_offset(idx, m, addr, &c->hw); - if (IS_ERR(cfg)) { - WARN(1, "Unable to find wb idx=%d\n", idx); - kfree(c); - return ERR_PTR(-EINVAL); - } - - /* Assign ops */ - c->catalog = m; - c->mdp = &m->mdp[0]; - c->idx = idx; - c->caps = cfg; - _setup_wb_ops(&c->ops, c->caps->features); - c->hw_mdp = hw_mdp; - - rc = dpu_hw_blk_init(&c->base, DPU_HW_BLK_WB, idx, &dpu_hw_ops); - if (rc) { - DPU_ERROR("failed to init hw blk %d\n", rc); - goto blk_init_error; - } - - dpu_dbg_reg_register_dump_range(DPU_DBG_NAME, cfg->name, c->hw.blk_off, - c->hw.blk_off + c->hw.length, c->hw.xin_id); - - return c; - -blk_init_error: - kzfree(c); - - return ERR_PTR(rc); -} - -void dpu_hw_wb_destroy(struct dpu_hw_wb *hw_wb) -{ - if (hw_wb) - dpu_hw_blk_destroy(&hw_wb->base); - kfree(hw_wb); -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h deleted file mode 100644 index 145ebbc..0000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright (c) 2015-2018, 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 _DPU_HW_WB_H -#define _DPU_HW_WB_H - -#include "dpu_hw_catalog.h" -#include "dpu_hw_mdss.h" -#include "dpu_hw_top.h" -#include "dpu_hw_util.h" - -struct dpu_hw_wb; - -struct dpu_hw_wb_cfg { - struct dpu_hw_fmt_layout dest; - enum dpu_intf_mode intf_mode; - struct traffic_shaper_cfg ts_cfg; - struct dpu_rect roi; -}; - -/** - * enum CDP preload ahead address size - */ -enum { - DPU_WB_CDP_PRELOAD_AHEAD_32, - DPU_WB_CDP_PRELOAD_AHEAD_64 -}; - -/** - * struct dpu_hw_wb_cdp_cfg : CDP configuration - * @enable: true to enable CDP - * @ubwc_meta_enable: true to enable ubwc metadata preload - * @tile_amortize_enable: true to enable amortization control for tile format - * @preload_ahead: number of request to preload ahead - * DPU_WB_CDP_PRELOAD_AHEAD_32, - * DPU_WB_CDP_PRELOAD_AHEAD_64 - */ -struct dpu_hw_wb_cdp_cfg { - bool enable; - bool ubwc_meta_enable; - bool tile_amortize_enable; - u32 preload_ahead; -}; - -/** - * struct dpu_hw_wb_qos_cfg : Writeback pipe QoS configuration - * @danger_lut: LUT for generate danger level based on fill level - * @safe_lut: LUT for generate safe level based on fill level - * @creq_lut: LUT for generate creq level based on fill level - * @danger_safe_en: enable danger safe generation - */ -struct dpu_hw_wb_qos_cfg { - u32 danger_lut; - u32 safe_lut; - u64 creq_lut; - bool danger_safe_en; -}; - -/** - * - * struct dpu_hw_wb_ops : Interface to the wb Hw driver functions - * Assumption is these functions will be called after clocks are enabled - */ -struct dpu_hw_wb_ops { - void (*setup_csc_data)(struct dpu_hw_wb *ctx, - struct dpu_csc_cfg *data); - - void (*setup_outaddress)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *wb); - - void (*setup_outformat)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *wb); - - void (*setup_rotator)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *wb); - - void (*setup_dither)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *wb); - - void (*setup_cdwn)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *wb); - - void (*setup_trafficshaper)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *wb); - - void (*setup_roi)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *wb); - - /** - * setup_danger_safe_lut - setup danger safe LUTs - * @ctx: Pointer to pipe context - * @cfg: Pointer to pipe QoS configuration - */ - void (*setup_danger_safe_lut)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_qos_cfg *cfg); - - /** - * setup_creq_lut - setup CREQ LUT - * @ctx: Pointer to pipe context - * @cfg: Pointer to pipe QoS configuration - */ - void (*setup_creq_lut)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_qos_cfg *cfg); - - /** - * setup_qos_ctrl - setup QoS control - * @ctx: Pointer to pipe context - * @cfg: Pointer to pipe QoS configuration - */ - void (*setup_qos_ctrl)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_qos_cfg *cfg); - - /** - * setup_cdp - setup CDP - * @ctx: Pointer to pipe context - * @cfg: Pointer to pipe CDP configuration - */ - void (*setup_cdp)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cdp_cfg *cfg); -}; - -/** - * struct dpu_hw_wb : WB driver object - * @base: hardware block base structure - * @hw: block hardware details - * @catalog: back pointer to catalog - * @mdp: pointer to associated mdp portion of the catalog - * @idx: hardware index number within type - * @wb_hw_caps: hardware capabilities - * @ops: function pointers - * @hw_mdp: MDP top level hardware block - */ -struct dpu_hw_wb { - struct dpu_hw_blk base; - struct dpu_hw_blk_reg_map hw; - struct dpu_mdss_cfg *catalog; - struct dpu_mdp_cfg *mdp; - - /* wb path */ - int idx; - const struct dpu_wb_cfg *caps; - - /* ops */ - struct dpu_hw_wb_ops ops; - - struct dpu_hw_mdp *hw_mdp; -}; - -/** - * dpu_hw_wb - convert base object dpu_hw_base to container - * @hw: Pointer to base hardware block - * return: Pointer to hardware block container - */ -static inline struct dpu_hw_wb *to_dpu_hw_wb(struct dpu_hw_blk *hw) -{ - return container_of(hw, struct dpu_hw_wb, base); -} - -/** - * dpu_hw_wb_init(): Initializes and return writeback hw driver object. - * @idx: wb_path index for which driver object is required - * @addr: mapped register io address of MDP - * @m : pointer to mdss catalog data - * @hw_mdp: pointer to mdp top hw driver object - */ -struct dpu_hw_wb *dpu_hw_wb_init(enum dpu_wb idx, - void __iomem *addr, - struct dpu_mdss_cfg *m, - struct dpu_hw_mdp *hw_mdp); - -/** - * dpu_hw_wb_destroy(): Destroy writeback hw driver object. - * @hw_wb: Pointer to writeback hw driver object - */ -void dpu_hw_wb_destroy(struct dpu_hw_wb *hw_wb); - -#endif /*_DPU_HW_WB_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 16629af..369eaeb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -120,11 +120,6 @@ static int _dpu_danger_signal_status(struct seq_file *s, status.sspp[i]); seq_puts(s, "\n"); - for (i = WB_0; i < WB_MAX; i++) - seq_printf(s, "WB%d : 0x%x \t", i - WB_0, - status.wb[i]); - seq_puts(s, "\n"); - return 0; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index c48ed4e..a5468ed 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -31,7 +31,6 @@ #include "dpu_hw_ctl.h" #include "dpu_hw_lm.h" #include "dpu_hw_interrupts.h" -#include "dpu_hw_wb.h" #include "dpu_hw_top.h" #include "dpu_rm.h" #include "dpu_power_handle.h" diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 38714c9..6090ace 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1374,7 +1374,7 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane, cdp_cfg->tile_amortize_enable = DPU_FORMAT_IS_UBWC(fmt) || DPU_FORMAT_IS_TILE(fmt); - cdp_cfg->preload_ahead = DPU_WB_CDP_PRELOAD_AHEAD_64; + cdp_cfg->preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64; pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, cdp_cfg); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 0af2996..ab12d89 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -19,7 +19,6 @@ #include "dpu_hw_cdm.h" #include "dpu_hw_pingpong.h" #include "dpu_hw_intf.h" -#include "dpu_hw_wb.h" #include "dpu_encoder.h" #define RESERVED_BY_OTHER(h, r) \ @@ -246,9 +245,6 @@ static void _dpu_rm_hw_destroy(enum dpu_hw_blk_type type, void *hw) case DPU_HW_BLK_INTF: dpu_hw_intf_destroy(hw); break; - case DPU_HW_BLK_WB: - dpu_hw_wb_destroy(hw); - break; case DPU_HW_BLK_SSPP: /* SSPPs are not managed by the resource manager */ case DPU_HW_BLK_TOP: @@ -325,9 +321,6 @@ static int _dpu_rm_hw_blk_create( case DPU_HW_BLK_INTF: hw = dpu_hw_intf_init(id, mmio, cat); break; - case DPU_HW_BLK_WB: - hw = dpu_hw_wb_init(id, mmio, cat, hw_mdp); - break; case DPU_HW_BLK_SSPP: /* SSPPs are not managed by the resource manager */ case DPU_HW_BLK_TOP: @@ -443,15 +436,6 @@ int dpu_rm_init(struct dpu_rm *rm, } } - for (i = 0; i < cat->wb_count; i++) { - rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_WB, - cat->wb[i].id, &cat->wb[i]); - if (rc) { - DPU_ERROR("failed: wb hw not available\n"); - goto fail; - } - } - for (i = 0; i < cat->ctl_count; i++) { rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_CTL, cat->ctl[i].id, &cat->ctl[i]); @@ -683,12 +667,9 @@ static int _dpu_rm_reserve_cdm( if (type == DPU_HW_BLK_INTF && id != INTF_MAX) match = test_bit(id, &caps->intf_connect); - else if (type == DPU_HW_BLK_WB && id != WB_MAX) - match = test_bit(id, &caps->wb_connect); - DPU_DEBUG("type %d id %d, cdm intfs %lu wbs %lu match %d\n", - type, id, caps->intf_connect, caps->wb_connect, - match); + DPU_DEBUG("type %d id %d, cdm intfs %lu match %d\n", + type, id, caps->intf_connect, match); if (!match) continue; @@ -706,7 +687,7 @@ static int _dpu_rm_reserve_cdm( return 0; } -static int _dpu_rm_reserve_intf_or_wb( +static int _dpu_rm_reserve_intf( struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp, uint32_t id, @@ -732,13 +713,12 @@ static int _dpu_rm_reserve_intf_or_wb( break; } - /* Shouldn't happen since wbs / intfs are fixed at probe */ + /* Shouldn't happen since intfs are fixed at probe */ if (!iter.hw) { DPU_ERROR("couldn't find type %d id %d\n", type, id); return -EINVAL; } - /* Expected only one intf or wb will request cdm */ if (needs_cdm) ret = _dpu_rm_reserve_cdm(rm, rsvp, id, type); @@ -757,22 +737,12 @@ static int _dpu_rm_reserve_intf_related_hw( if (hw_res->intfs[i] == INTF_MODE_NONE) continue; id = i + INTF_0; - ret = _dpu_rm_reserve_intf_or_wb(rm, rsvp, id, + ret = _dpu_rm_reserve_intf(rm, rsvp, id, DPU_HW_BLK_INTF, hw_res->needs_cdm); if (ret) return ret; } - for (i = 0; i < ARRAY_SIZE(hw_res->wbs); i++) { - if (hw_res->wbs[i] == INTF_MODE_NONE) - continue; - id = i + WB_0; - ret = _dpu_rm_reserve_intf_or_wb(rm, rsvp, id, - DPU_HW_BLK_WB, hw_res->needs_cdm); - if (ret) - return ret; - } - return ret; } @@ -815,7 +785,7 @@ static int _dpu_rm_make_next_rsvp( return ret; } - /* Assign INTFs, WBs, and blks whose usage is tied to them: CTL & CDM */ + /* Assign INTFs and blks whose usage is tied to them: CTL & CDM */ ret = _dpu_rm_reserve_intf_related_hw(rm, rsvp, &reqs->hw_res); if (ret) return ret; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_wb.c deleted file mode 100644 index 9b47bb2..0000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_wb.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Copyright (c) 2015-2018, 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 "msm_kms.h" -#include "dpu_kms.h" -#include "dpu_wb.h" -#include "dpu_formats.h" - -/* maximum display mode resolution if not available from catalog */ -#define DPU_WB_MODE_MAX_WIDTH 4096 -#define DPU_WB_MODE_MAX_HEIGHT 4096 - -/* Serialization lock for dpu_wb_list */ -static DEFINE_MUTEX(dpu_wb_list_lock); - -/* List of all writeback devices installed */ -static LIST_HEAD(dpu_wb_list); - -/** - * dpu_wb_is_format_valid - check if given format/modifier is supported - * @wb_dev: Pointer to writeback device - * @pixel_format: Fourcc pixel format - * @format_modifier: Format modifier - * Returns: true if valid; false otherwise - */ -static int dpu_wb_is_format_valid(struct dpu_wb_device *wb_dev, - u32 pixel_format, u64 format_modifier) -{ - const struct dpu_format_extended *fmts = wb_dev->wb_cfg->format_list; - int i; - - if (!fmts) - return false; - - for (i = 0; fmts[i].fourcc_format; i++) - if ((fmts[i].modifier == format_modifier) && - (fmts[i].fourcc_format == pixel_format)) - return true; - - return false; -} - -enum drm_connector_status -dpu_wb_connector_detect(struct drm_connector *connector, - bool force, - void *display) -{ - enum drm_connector_status rc = connector_status_unknown; - - DPU_DEBUG("\n"); - - if (display) - rc = ((struct dpu_wb_device *)display)->detect_status; - - return rc; -} - -int dpu_wb_connector_get_modes(struct drm_connector *connector, void *display) -{ - struct dpu_wb_device *wb_dev; - int num_modes = 0; - - if (!connector || !display) - return 0; - - wb_dev = display; - - DPU_DEBUG("\n"); - - mutex_lock(&wb_dev->wb_lock); - if (wb_dev->count_modes && wb_dev->modes) { - struct drm_display_mode *mode; - int i, ret; - - for (i = 0; i < wb_dev->count_modes; i++) { - mode = drm_mode_create(connector->dev); - if (!mode) { - DPU_ERROR("failed to create mode\n"); - break; - } - ret = drm_mode_convert_umode(mode, - &wb_dev->modes[i]); - if (ret) { - DPU_ERROR("failed to convert mode %d\n", ret); - break; - } - - drm_mode_probed_add(connector, mode); - num_modes++; - } - } else { - u32 max_width = (wb_dev->wb_cfg && wb_dev->wb_cfg->sblk) ? - wb_dev->wb_cfg->sblk->maxlinewidth : - DPU_WB_MODE_MAX_WIDTH; - - num_modes = drm_add_modes_noedid(connector, max_width, - DPU_WB_MODE_MAX_HEIGHT); - } - mutex_unlock(&wb_dev->wb_lock); - return num_modes; -} - -struct drm_framebuffer * -dpu_wb_connector_state_get_output_fb(struct drm_connector_state *state) -{ - if (!state || !state->connector || - (state->connector->connector_type != - DRM_MODE_CONNECTOR_VIRTUAL)) { - DPU_ERROR("invalid params\n"); - return NULL; - } - - DPU_DEBUG("\n"); - - return dpu_connector_get_out_fb(state); -} - -int dpu_wb_connector_state_get_output_roi(struct drm_connector_state *state, - struct dpu_rect *roi) -{ - if (!state || !roi || !state->connector || - (state->connector->connector_type != - DRM_MODE_CONNECTOR_VIRTUAL)) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - roi->x = dpu_connector_get_property(state, CONNECTOR_PROP_DST_X); - roi->y = dpu_connector_get_property(state, CONNECTOR_PROP_DST_Y); - roi->w = dpu_connector_get_property(state, CONNECTOR_PROP_DST_W); - roi->h = dpu_connector_get_property(state, CONNECTOR_PROP_DST_H); - - return 0; -} - -/** - * dpu_wb_connector_set_modes - set writeback modes and connection status - * @wb_dev: Pointer to write back device - * @count_modes: Count of modes - * @modes: Pointer to writeback mode requested - * @connected: Connection status requested - * Returns: 0 if success; error code otherwise - */ -static -int dpu_wb_connector_set_modes(struct dpu_wb_device *wb_dev, - u32 count_modes, struct drm_mode_modeinfo __user *modes, - bool connected) -{ - int ret = 0; - - if (!wb_dev || !wb_dev->connector || - (wb_dev->connector->connector_type != - DRM_MODE_CONNECTOR_VIRTUAL)) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - if (connected) { - DPU_DEBUG("connect\n"); - - if (wb_dev->modes) { - wb_dev->count_modes = 0; - - kfree(wb_dev->modes); - wb_dev->modes = NULL; - } - - if (count_modes && modes) { - wb_dev->modes = kcalloc(count_modes, - sizeof(struct drm_mode_modeinfo), - GFP_KERNEL); - if (!wb_dev->modes) { - DPU_ERROR("invalid params\n"); - ret = -ENOMEM; - goto error; - } - - if (copy_from_user(wb_dev->modes, modes, - count_modes * - sizeof(struct drm_mode_modeinfo))) { - DPU_ERROR("failed to copy modes\n"); - kfree(wb_dev->modes); - wb_dev->modes = NULL; - ret = -EFAULT; - goto error; - } - - wb_dev->count_modes = count_modes; - } - - wb_dev->detect_status = connector_status_connected; - } else { - DPU_DEBUG("disconnect\n"); - - if (wb_dev->modes) { - wb_dev->count_modes = 0; - - kfree(wb_dev->modes); - wb_dev->modes = NULL; - } - - wb_dev->detect_status = connector_status_disconnected; - } - -error: - return ret; -} - -int dpu_wb_connector_set_property(struct drm_connector *connector, - struct drm_connector_state *state, - int property_index, - uint64_t value, - void *display) -{ - struct dpu_wb_device *wb_dev = display; - struct drm_framebuffer *out_fb; - int rc = 0; - - DPU_DEBUG("\n"); - - if (state && (property_index == CONNECTOR_PROP_OUT_FB)) { - const struct dpu_format *dpu_format; - - out_fb = dpu_connector_get_out_fb(state); - if (!out_fb) - goto done; - - dpu_format = dpu_get_dpu_format_ext(out_fb->format->format, - out_fb->modifier); - if (!dpu_format) { - DPU_ERROR("failed to get dpu format\n"); - rc = -EINVAL; - goto done; - } - - if (!dpu_wb_is_format_valid(wb_dev, out_fb->format->format, - out_fb->modifier)) { - DPU_ERROR("unsupported writeback format 0x%x/0x%llx\n", - out_fb->format->format, - out_fb->modifier); - rc = -EINVAL; - goto done; - } - } - -done: - return rc; -} - -int dpu_wb_get_info(struct msm_display_info *info, void *display) -{ - struct dpu_wb_device *wb_dev = display; - - if (!info || !wb_dev) { - pr_err("invalid params\n"); - return -EINVAL; - } - - memset(info, 0, sizeof(struct msm_display_info)); - info->intf_type = DRM_MODE_CONNECTOR_VIRTUAL; - info->num_of_h_tiles = 1; - info->h_tile_instance[0] = dpu_wb_get_index(display); - info->is_connected = true; - info->capabilities = MSM_DISPLAY_CAP_HOT_PLUG | MSM_DISPLAY_CAP_EDID; - info->max_width = (wb_dev->wb_cfg && wb_dev->wb_cfg->sblk) ? - wb_dev->wb_cfg->sblk->maxlinewidth : - DPU_WB_MODE_MAX_WIDTH; - info->max_height = DPU_WB_MODE_MAX_HEIGHT; - return 0; -} - -int dpu_wb_get_mode_info(const struct drm_display_mode *drm_mode, - struct msm_mode_info *mode_info, u32 max_mixer_width) -{ - const u32 dual_lm = 2; - const u32 single_lm = 1; - const u32 single_intf = 1; - const u32 no_enc = 0; - struct msm_display_topology *topology; - - if (!drm_mode || !mode_info || !max_mixer_width) { - pr_err("invalid params\n"); - return -EINVAL; - } - - topology = &mode_info->topology; - topology->num_lm = (max_mixer_width <= drm_mode->hdisplay) ? - dual_lm : single_lm; - topology->num_enc = no_enc; - topology->num_intf = single_intf; - - return 0; -} - -int dpu_wb_connector_post_init(struct drm_connector *connector, - void *info, - void *display) -{ - struct dpu_connector *c_conn; - struct dpu_wb_device *wb_dev = display; - const struct dpu_format_extended *format_list; - - if (!connector || !info || !display || !wb_dev->wb_cfg) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - c_conn = to_dpu_connector(connector); - wb_dev->connector = connector; - wb_dev->detect_status = connector_status_connected; - format_list = wb_dev->wb_cfg->format_list; - - /* - * Add extra connector properties - */ - msm_property_install_range(&c_conn->property_info, "FB_ID", - 0x0, 0, ~0, ~0, CONNECTOR_PROP_OUT_FB); - msm_property_install_range(&c_conn->property_info, "DST_X", - 0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_DST_X); - msm_property_install_range(&c_conn->property_info, "DST_Y", - 0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_DST_Y); - msm_property_install_range(&c_conn->property_info, "DST_W", - 0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_DST_W); - msm_property_install_range(&c_conn->property_info, "DST_H", - 0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_DST_H); - - /* - * Populate info buffer - */ - if (format_list) { - dpu_kms_info_start(info, "pixel_formats"); - while (format_list->fourcc_format) { - dpu_kms_info_append_format(info, - format_list->fourcc_format, - format_list->modifier); - ++format_list; - } - dpu_kms_info_stop(info); - } - - dpu_kms_info_add_keyint(info, - "wb_intf_index", - wb_dev->wb_idx - WB_0); - - dpu_kms_info_add_keyint(info, - "maxlinewidth", - wb_dev->wb_cfg->sblk->maxlinewidth); - - dpu_kms_info_start(info, "features"); - if (wb_dev->wb_cfg && (wb_dev->wb_cfg->features & DPU_WB_UBWC)) - dpu_kms_info_append(info, "wb_ubwc"); - dpu_kms_info_stop(info); - - return 0; -} - -struct drm_framebuffer *dpu_wb_get_output_fb(struct dpu_wb_device *wb_dev) -{ - struct drm_framebuffer *fb; - - if (!wb_dev || !wb_dev->connector) { - DPU_ERROR("invalid params\n"); - return NULL; - } - - DPU_DEBUG("\n"); - - mutex_lock(&wb_dev->wb_lock); - fb = dpu_wb_connector_state_get_output_fb(wb_dev->connector->state); - mutex_unlock(&wb_dev->wb_lock); - - return fb; -} - -int dpu_wb_get_output_roi(struct dpu_wb_device *wb_dev, struct dpu_rect *roi) -{ - int rc; - - if (!wb_dev || !wb_dev->connector || !roi) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - mutex_lock(&wb_dev->wb_lock); - rc = dpu_wb_connector_state_get_output_roi( - wb_dev->connector->state, roi); - mutex_unlock(&wb_dev->wb_lock); - - return rc; -} - -u32 dpu_wb_get_num_of_displays(void) -{ - u32 count = 0; - struct dpu_wb_device *wb_dev; - - DPU_DEBUG("\n"); - - mutex_lock(&dpu_wb_list_lock); - list_for_each_entry(wb_dev, &dpu_wb_list, wb_list) { - count++; - } - mutex_unlock(&dpu_wb_list_lock); - - return count; -} - -int wb_display_get_displays(void **display_array, u32 max_display_count) -{ - struct dpu_wb_device *curr; - int i = 0; - - DPU_DEBUG("\n"); - - if (!display_array || !max_display_count) { - if (!display_array) - DPU_ERROR("invalid param\n"); - return 0; - } - - mutex_lock(&dpu_wb_list_lock); - list_for_each_entry(curr, &dpu_wb_list, wb_list) { - if (i >= max_display_count) - break; - display_array[i++] = curr; - } - mutex_unlock(&dpu_wb_list_lock); - - return i; -} - -int dpu_wb_config(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv) -{ - struct dpu_drm_wb_cfg *config = data; - struct msm_drm_private *priv; - struct dpu_wb_device *wb_dev = NULL; - struct dpu_wb_device *curr; - struct drm_connector *connector; - uint32_t flags; - uint32_t connector_id; - uint32_t count_modes; - uint64_t modes; - int rc; - - if (!drm_dev || !data) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - flags = config->flags; - connector_id = config->connector_id; - count_modes = config->count_modes; - modes = config->modes; - - priv = drm_dev->dev_private; - - connector = drm_connector_lookup(drm_dev, NULL, connector_id); - if (!connector) { - DPU_ERROR("failed to find connector\n"); - rc = -ENOENT; - goto fail; - } - - mutex_lock(&dpu_wb_list_lock); - list_for_each_entry(curr, &dpu_wb_list, wb_list) { - if (curr->connector == connector) { - wb_dev = curr; - break; - } - } - mutex_unlock(&dpu_wb_list_lock); - - if (!wb_dev) { - DPU_ERROR("failed to find wb device\n"); - rc = -ENOENT; - goto fail; - } - - mutex_lock(&wb_dev->wb_lock); - - rc = dpu_wb_connector_set_modes(wb_dev, count_modes, - (struct drm_mode_modeinfo __user *) (uintptr_t) modes, - (flags & DPU_DRM_WB_CFG_FLAGS_CONNECTED) ? true : false); - - mutex_unlock(&wb_dev->wb_lock); - drm_helper_hpd_irq_event(drm_dev); -fail: - return rc; -} - -/** - * _dpu_wb_dev_init - perform device initialization - * @wb_dev: Pointer to writeback device - */ -static int _dpu_wb_dev_init(struct dpu_wb_device *wb_dev) -{ - int rc = 0; - - if (!wb_dev) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - return rc; -} - -/** - * _dpu_wb_dev_deinit - perform device de-initialization - * @wb_dev: Pointer to writeback device - */ -static int _dpu_wb_dev_deinit(struct dpu_wb_device *wb_dev) -{ - int rc = 0; - - if (!wb_dev) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - return rc; -} - -/** - * dpu_wb_bind - bind writeback device with controlling device - * @dev: Pointer to base of platform device - * @master: Pointer to container of drm device - * @data: Pointer to private data - * Returns: Zero on success - */ -static int dpu_wb_bind(struct device *dev, struct device *master, void *data) -{ - struct dpu_wb_device *wb_dev; - - if (!dev || !master) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - wb_dev = platform_get_drvdata(to_platform_device(dev)); - if (!wb_dev) { - DPU_ERROR("invalid wb device\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - mutex_lock(&wb_dev->wb_lock); - wb_dev->drm_dev = dev_get_drvdata(master); - mutex_unlock(&wb_dev->wb_lock); - - return 0; -} - -/** - * dpu_wb_unbind - unbind writeback from controlling device - * @dev: Pointer to base of platform device - * @master: Pointer to container of drm device - * @data: Pointer to private data - */ -static void dpu_wb_unbind(struct device *dev, - struct device *master, void *data) -{ - struct dpu_wb_device *wb_dev; - - if (!dev) { - DPU_ERROR("invalid params\n"); - return; - } - - wb_dev = platform_get_drvdata(to_platform_device(dev)); - if (!wb_dev) { - DPU_ERROR("invalid wb device\n"); - return; - } - - DPU_DEBUG("\n"); - - mutex_lock(&wb_dev->wb_lock); - wb_dev->drm_dev = NULL; - mutex_unlock(&wb_dev->wb_lock); -} - -static const struct component_ops dpu_wb_comp_ops = { - .bind = dpu_wb_bind, - .unbind = dpu_wb_unbind, -}; - -/** - * dpu_wb_drm_init - perform DRM initialization - * @wb_dev: Pointer to writeback device - * @encoder: Pointer to associated encoder - */ -int dpu_wb_drm_init(struct dpu_wb_device *wb_dev, struct drm_encoder *encoder) -{ - int rc = 0; - - if (!wb_dev || !wb_dev->drm_dev || !encoder) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - mutex_lock(&wb_dev->wb_lock); - - if (wb_dev->drm_dev->dev_private) { - struct msm_drm_private *priv = wb_dev->drm_dev->dev_private; - struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); - - if (wb_dev->index < dpu_kms->catalog->wb_count) { - wb_dev->wb_idx = dpu_kms->catalog->wb[wb_dev->index].id; - wb_dev->wb_cfg = &dpu_kms->catalog->wb[wb_dev->index]; - } - } - - wb_dev->drm_dev = encoder->dev; - wb_dev->encoder = encoder; - mutex_unlock(&wb_dev->wb_lock); - return rc; -} - -int dpu_wb_drm_deinit(struct dpu_wb_device *wb_dev) -{ - int rc = 0; - - if (!wb_dev) { - DPU_ERROR("invalid params\n"); - return -EINVAL; - } - - DPU_DEBUG("\n"); - - return rc; -} - -/** - * dpu_wb_probe - load writeback module - * @pdev: Pointer to platform device - */ -static int dpu_wb_probe(struct platform_device *pdev) -{ - struct dpu_wb_device *wb_dev; - int ret; - - wb_dev = devm_kzalloc(&pdev->dev, sizeof(*wb_dev), GFP_KERNEL); - if (!wb_dev) - return -ENOMEM; - - DPU_DEBUG("\n"); - - ret = of_property_read_u32(pdev->dev.of_node, "cell-index", - &wb_dev->index); - if (ret) { - DPU_DEBUG("cell index not set, default to 0\n"); - wb_dev->index = 0; - } - - wb_dev->name = of_get_property(pdev->dev.of_node, "label", NULL); - if (!wb_dev->name) { - DPU_DEBUG("label not set, default to unknown\n"); - wb_dev->name = "unknown"; - } - - wb_dev->wb_idx = DPU_NONE; - - mutex_init(&wb_dev->wb_lock); - platform_set_drvdata(pdev, wb_dev); - - mutex_lock(&dpu_wb_list_lock); - list_add(&wb_dev->wb_list, &dpu_wb_list); - mutex_unlock(&dpu_wb_list_lock); - - if (!_dpu_wb_dev_init(wb_dev)) { - ret = component_add(&pdev->dev, &dpu_wb_comp_ops); - if (ret) - pr_err("component add failed\n"); - } - - return ret; -} - -/** - * dpu_wb_remove - unload writeback module - * @pdev: Pointer to platform device - */ -static int dpu_wb_remove(struct platform_device *pdev) -{ - struct dpu_wb_device *wb_dev; - struct dpu_wb_device *curr, *next; - - wb_dev = platform_get_drvdata(pdev); - if (!wb_dev) - return 0; - - DPU_DEBUG("\n"); - - (void)_dpu_wb_dev_deinit(wb_dev); - - mutex_lock(&dpu_wb_list_lock); - list_for_each_entry_safe(curr, next, &dpu_wb_list, wb_list) { - if (curr == wb_dev) { - list_del(&wb_dev->wb_list); - break; - } - } - mutex_unlock(&dpu_wb_list_lock); - - kfree(wb_dev->modes); - mutex_destroy(&wb_dev->wb_lock); - - platform_set_drvdata(pdev, NULL); - devm_kfree(&pdev->dev, wb_dev); - - return 0; -} - -static const struct of_device_id dt_match[] = { - { .compatible = "qcom,wb-display"}, - {} -}; - -static struct platform_driver dpu_wb_driver = { - .probe = dpu_wb_probe, - .remove = dpu_wb_remove, - .driver = { - .name = "dpu_wb", - .of_match_table = dt_match, - }, -}; - -static int __init dpu_wb_register(void) -{ - return platform_driver_register(&dpu_wb_driver); -} - -static void __exit dpu_wb_unregister(void) -{ - platform_driver_unregister(&dpu_wb_driver); -} - -module_init(dpu_wb_register); -module_exit(dpu_wb_unregister); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_wb.h deleted file mode 100644 index a6063e0..0000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_wb.h +++ /dev/null @@ -1,232 +0,0 @@ -/* Copyright (c) 2015-2018, 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 __DPU_WB_H__ -#define __DPU_WB_H__ - -#include <linux/platform_device.h> - -#include "msm_kms.h" -#include "dpu_kms.h" -#include "dpu_connector.h" - -/** - * struct dpu_wb_device - Writeback device context - * @drm_dev: Pointer to controlling DRM device - * @index: Index of hardware instance from device tree - * @wb_idx: Writeback identifier of enum dpu_wb - * @wb_cfg: Writeback configuration catalog - * @name: Name of writeback device from device tree - * @display_type: Display type from device tree - * @wb_list List of all writeback devices - * @wb_lock Serialization lock for writeback context structure - * @connector: Connector associated with writeback device - * @encoder: Encoder associated with writeback device - * @max_mixer_width: Max width supported by DPU LM HW block - * @count_modes: Length of writeback connector modes array - * @modes: Writeback connector modes array - */ -struct dpu_wb_device { - struct drm_device *drm_dev; - - u32 index; - u32 wb_idx; - struct dpu_wb_cfg *wb_cfg; - const char *name; - - struct list_head wb_list; - struct mutex wb_lock; - - struct drm_connector *connector; - struct drm_encoder *encoder; - - enum drm_connector_status detect_status; - u32 max_mixer_width; - - u32 count_modes; - struct drm_mode_modeinfo *modes; -}; - -/** - * dpu_wb_get_index - get device index of the given writeback device - * @wb_dev: Pointer to writeback device - * Returns: Index of hardware instance - */ -static inline -int dpu_wb_get_index(struct dpu_wb_device *wb_dev) -{ - return wb_dev ? wb_dev->index : -1; -} - -/** - * dpu_wb_get_output_fb - get framebuffer in current atomic state - * @wb_dev: Pointer to writeback device - * Returns: Pointer to framebuffer - */ -struct drm_framebuffer *dpu_wb_get_output_fb(struct dpu_wb_device *wb_dev); - -/** - * dpu_wb_get_output_roi - get region-of-interest in current atomic state - * @wb_dev: Pointer to writeback device - * @roi: Pointer to region of interest - * Returns: 0 if success; error code otherwise - */ -int dpu_wb_get_output_roi(struct dpu_wb_device *wb_dev, struct dpu_rect *roi); - -/** - * dpu_wb_get_num_of_displays - get total number of writeback devices - * Returns: Number of writeback devices - */ -u32 dpu_wb_get_num_of_displays(void); - -/** - * wb_display_get_displays - returns pointers for supported display devices - * @display_array: Pointer to display array to be filled - * @max_display_count: Size of display_array - * @Returns: Number of display entries filled - */ -int wb_display_get_displays(void **display_array, u32 max_display_count); - -void dpu_wb_set_active_state(struct dpu_wb_device *wb_dev, bool is_active); -bool dpu_wb_is_active(struct dpu_wb_device *wb_dev); - -/** - * dpu_wb_drm_init - perform DRM initialization - * @wb_dev: Pointer to writeback device - * @encoder: Pointer to associated encoder - * Returns: 0 if success; error code otherwise - */ -int dpu_wb_drm_init(struct dpu_wb_device *wb_dev, struct drm_encoder *encoder); - -/** - * dpu_wb_drm_deinit - perform DRM de-initialization - * @wb_dev: Pointer to writeback device - * Returns: 0 if success; error code otherwise - */ -int dpu_wb_drm_deinit(struct dpu_wb_device *wb_dev); - -/** - * dpu_wb_config - setup connection status and available drm modes of the - * given writeback connector - * @drm_dev: Pointer to DRM device - * @data: Pointer to writeback configuration - * @file_priv: Pointer file private data - * Returns: 0 if success; error code otherwise - * - * This function will initiate hot-plug detection event. - */ -int dpu_wb_config(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv); - -/** - * dpu_wb_connector_post_init - perform writeback specific initialization - * @connector: Pointer to drm connector structure - * @info: Pointer to connector info - * @display: Pointer to private display structure - * Returns: Zero on success - */ -int dpu_wb_connector_post_init(struct drm_connector *connector, - void *info, - void *display); - -/** - * dpu_wb_connector_detect - perform writeback connection status detection - * @connector: Pointer to connector - * @force: Indicate force detection - * @display: Pointer to writeback device - * Returns: connector status - */ -enum drm_connector_status -dpu_wb_connector_detect(struct drm_connector *connector, - bool force, - void *display); - -/** - * dpu_wb_connector_get_modes - get display modes of connector - * @connector: Pointer to connector - * @display: Pointer to writeback device - * Returns: Number of modes - * - * If display modes are not specified in writeback configuration IOCTL, this - * function will install default EDID modes up to maximum resolution support. - */ -int dpu_wb_connector_get_modes(struct drm_connector *connector, void *display); - -/** - * dpu_wb_connector_set_property - set atomic connector property - * @connector: Pointer to drm connector structure - * @state: Pointer to drm connector state structure - * @property_index: DRM property index - * @value: Incoming property value - * @display: Pointer to private display structure - * Returns: Zero on success - */ -int dpu_wb_connector_set_property(struct drm_connector *connector, - struct drm_connector_state *state, - int property_index, - uint64_t value, - void *display); - -/** - * dpu_wb_get_info - retrieve writeback 'display' information - * @info: Pointer to display info structure - * @display: Pointer to private display structure - * Returns: Zero on success - */ -int dpu_wb_get_info(struct msm_display_info *info, void *display); - -/** - * dpu_wb_get_mode_info - retrieve information of the mode selected - * @drm_mode: Display mode set for the display - * @mode_info: Out parameter. information of the mode. - * @max_mixer_width: max width supported by HW layer mixer - * Returns: zero on success - */ -int dpu_wb_get_mode_info(const struct drm_display_mode *drm_mode, - struct msm_mode_info *mode_info, u32 max_mixer_width); - -/** - * dpu_wb_connector_get_wb - retrieve writeback device of the given connector - * @connector: Pointer to drm connector - * Returns: Pointer to writeback device on success; NULL otherwise - */ -static inline -struct dpu_wb_device *dpu_wb_connector_get_wb(struct drm_connector *connector) -{ - if (!connector || - (connector->connector_type != DRM_MODE_CONNECTOR_VIRTUAL)) { - DPU_ERROR("invalid params\n"); - return NULL; - } - - return dpu_connector_get_display(connector); -} - -/** - * dpu_wb_connector_state_get_output_fb - get framebuffer of given state - * @state: Pointer to connector state - * Returns: Pointer to framebuffer - */ -struct drm_framebuffer * -dpu_wb_connector_state_get_output_fb(struct drm_connector_state *state); - -/** - * dpu_wb_connector_state_get_output_roi - get roi from given atomic state - * @state: Pointer to atomic state - * @roi: Pointer to region of interest - * Returns: 0 if success; error code otherwise - */ -int dpu_wb_connector_state_get_output_roi(struct drm_connector_state *state, - struct dpu_rect *roi); - -#endif /* __DPU_WB_H__ */ - -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno