diff --git a/Makefile b/Makefile index 8c638b4d3b6a..83cbd7e89da3 100644 --- a/Makefile +++ b/Makefile @@ -50,4 +50,12 @@ ifeq ($(CONFIG_ARCH_BENGAL), y) LINUXINCLUDE += -include $(srctree)/techpack/display/config/bengaldispconf.h endif +ifeq ($(CONFIG_ARCH_MONACO), y) +include $(srctree)/techpack/display/config/monacodisp.conf +endif + +ifeq ($(CONFIG_ARCH_MONACO), y) +LINUXINCLUDE += -include $(srctree)/techpack/display/config/monacodispconf.h +endif + obj-$(CONFIG_DRM_MSM) += msm/ diff --git a/config/gki_holidisp.conf b/config/gki_holidisp.conf index ce2c475e51fd..67c345ba521d 100644 --- a/config/gki_holidisp.conf +++ b/config/gki_holidisp.conf @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -# Copyright (c) 2020, The Linux Foundation. All rights reserved. +# Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. export CONFIG_DRM_MSM=y export CONFIG_DRM_MSM_SDE=y @@ -15,4 +15,3 @@ export CONFIG_DRM_SDE_RSC=n export CONFIG_DISPLAY_BUILD=m export CONFIG_MSM_SDE_ROTATOR=y export CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y -export CONFIG_MSM_SDE_ROTATOR_INIT_ONLY=y diff --git a/config/gki_holidispconf.h b/config/gki_holidispconf.h index 535c20d5187b..bc9764945323 100644 --- a/config/gki_holidispconf.h +++ b/config/gki_holidispconf.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #define CONFIG_DRM_MSM 1 @@ -14,4 +14,3 @@ #define CONFIG_GKI_DISPLAY 1 #define CONFIG_MSM_SDE_ROTATOR 1 #define CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG 1 -#define CONFIG_MSM_SDE_ROTATOR_INIT_ONLY 1 diff --git a/config/monacodisp.conf b/config/monacodisp.conf new file mode 100644 index 000000000000..96ac3bf08911 --- /dev/null +++ b/config/monacodisp.conf @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2021, The Linux Foundation. All rights reserved. + +export CONFIG_DRM_MSM=y +export CONFIG_DRM_MSM_SDE=y +export CONFIG_SYNC_FILE=y +export CONFIG_DRM_MSM_DSI=y +export CONFIG_DSI_PARSER=y +export CONFIG_DRM_SDE_WB=n +export CONFIG_DRM_MSM_REGISTER_LOGGING=y +export CONFIG_QCOM_MDSS_PLL=y +export CONFIG_MSM_SDE_ROTATOR=n +export CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=n +export CONFIG_DRM_SDE_RSC=n +export CONFIG_DISPLAY_BUILD=y diff --git a/config/monacodispconf.h b/config/monacodispconf.h new file mode 100644 index 000000000000..1f6d125fa419 --- /dev/null +++ b/config/monacodispconf.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_DRM_MSM 1 +#define CONFIG_DRM_MSM_SDE 1 +#define CONFIG_SYNC_FILE 1 +#define CONFIG_DRM_MSM_DSI 1 +#define CONFIG_DSI_PARSER 1 +#define CONFIG_DRM_MSM_REGISTER_LOGGING 1 +#define CONFIG_QCOM_MDSS_PLL 1 diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h index 3db835574ea1..7ac0c8ba8feb 100644 --- a/msm/dsi/dsi_display.h +++ b/msm/dsi/dsi_display.h @@ -426,6 +426,14 @@ int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm); */ int dsi_display_get_qsync_min_fps(void *dsi_display, u32 mode_fps); +/** + * dsi_conn_get_lm_from_mode() - retrieves LM count from dsi mode priv info + * @display: Handle to display. + * @mode: Pointer to DRM mode structure + * + * Return: LM count from dsi panel topology + */ +int dsi_conn_get_lm_from_mode(void *dsi_display, const struct drm_display_mode *mode); /** * dsi_display_find_mode() - retrieve cached DSI mode given relevant params diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index d93d3867eee6..64549d570428 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -511,6 +511,29 @@ u64 dsi_drm_find_bit_clk_rate(void *display, return bit_clk_rate; } +int dsi_conn_get_lm_from_mode(void *display, const struct drm_display_mode *drm_mode) +{ + struct dsi_display *dsi_display = display; + struct dsi_display_mode dsi_mode, *panel_dsi_mode; + int rc = -EINVAL; + + if (!dsi_display || !drm_mode) { + DSI_ERR("Invalid params %d %d\n", !display, !drm_mode); + return rc; + } + + convert_to_dsi_mode(drm_mode, &dsi_mode); + + rc = dsi_display_find_mode(dsi_display, &dsi_mode, &panel_dsi_mode); + if (rc) { + DSI_ERR("mode not found %d\n", rc); + drm_mode_debug_printmodeline(drm_mode); + return rc; + } + + return panel_dsi_mode->priv_info->topology.num_lm; +} + int dsi_conn_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, diff --git a/msm/dsi/dsi_pll_5nm.c b/msm/dsi/dsi_pll_5nm.c index 8ecd31353610..332290ea8b42 100644 --- a/msm/dsi/dsi_pll_5nm.c +++ b/msm/dsi/dsi_pll_5nm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -565,11 +565,11 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_5nm *pll, switch (rsc->pll_revision) { case DSI_PLL_5NM: default: - if (pll_freq <= 1000000000) + if (pll_freq <= 1000000000ULL) regs->pll_clock_inverters = 0xA0; - else if (pll_freq <= 2500000000) + else if (pll_freq <= 2500000000ULL) regs->pll_clock_inverters = 0x20; - else if (pll_freq <= 3500000000) + else if (pll_freq <= 3500000000ULL) regs->pll_clock_inverters = 0x00; else regs->pll_clock_inverters = 0x40; @@ -664,16 +664,16 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_5nm *pll, switch (rsc->pll_revision) { case DSI_PLL_5NM: default: - if (vco_rate < 3100000000) + if (vco_rate < 3100000000ULL) DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE_1, 0x01); else DSI_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FIVE_1, 0x03); - if (vco_rate < 1520000000) + if (vco_rate < 1520000000ULL) DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x08); - else if (vco_rate < 2990000000) + else if (vco_rate < 2990000000ULL) DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x00); else DSI_PLL_REG_W(pll_base, PLL_VCO_CONFIG_1, 0x01); diff --git a/msm/msm_atomic.c b/msm/msm_atomic.c index 953fd3b174e1..412d8b3bda05 100644 --- a/msm/msm_atomic.c +++ b/msm/msm_atomic.c @@ -34,13 +34,17 @@ struct msm_commit { struct kthread_work commit_work; }; -static inline bool _msm_seamless_for_crtc(struct drm_atomic_state *state, +static inline bool _msm_seamless_for_crtc(struct drm_device *dev, + struct drm_atomic_state *state, struct drm_crtc_state *crtc_state, bool enable) { struct drm_connector *connector = NULL; struct drm_connector_state *conn_state = NULL; + struct msm_drm_private *priv = dev->dev_private; + struct msm_kms *kms = priv->kms; int i = 0; int conn_cnt = 0; + bool splash_en = false; if (msm_is_mode_seamless(&crtc_state->mode) || msm_is_mode_seamless_vrr(&crtc_state->adjusted_mode) || @@ -59,7 +63,11 @@ static inline bool _msm_seamless_for_crtc(struct drm_atomic_state *state, crtc_state->crtc)) conn_cnt++; - if (MULTIPLE_CONN_DETECTED(conn_cnt)) + if (kms && kms->funcs && kms->funcs->check_for_splash) + splash_en = kms->funcs->check_for_splash(kms, + crtc_state->crtc); + + if (MULTIPLE_CONN_DETECTED(conn_cnt) && !splash_en) return true; } } @@ -214,7 +222,7 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) if (!old_crtc_state->active) continue; - if (_msm_seamless_for_crtc(old_state, crtc->state, false)) + if (_msm_seamless_for_crtc(dev, old_state, crtc->state, false)) continue; funcs = crtc->helper_private; @@ -362,7 +370,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, if (!new_crtc_state->active) continue; - if (_msm_seamless_for_crtc(old_state, crtc->state, true)) + if (_msm_seamless_for_crtc(dev, old_state, crtc->state, true)) continue; funcs = crtc->helper_private; diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 9c6ad1aa60e8..40b5e1064d96 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -1030,7 +1030,7 @@ static void msm_lastclose(struct drm_device *dev) * commit then ignore the last close call */ if (kms->funcs && kms->funcs->check_for_splash - && kms->funcs->check_for_splash(kms)) + && kms->funcs->check_for_splash(kms, NULL)) return; /* diff --git a/msm/msm_kms.h b/msm/msm_kms.h index 3e70dcf2e588..e56407afb241 100644 --- a/msm/msm_kms.h +++ b/msm/msm_kms.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -124,7 +124,7 @@ struct msm_kms_funcs { int (*cont_splash_config)(struct msm_kms *kms, struct drm_atomic_state *state); /* check for continuous splash status */ - bool (*check_for_splash)(struct msm_kms *kms); + bool (*check_for_splash)(struct msm_kms *kms, struct drm_crtc *crtc); /* topology lm information */ int (*get_mixer_count)(const struct msm_kms *kms, const struct drm_display_mode *mode, diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index 188fde70df11..28e23b304693 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -1840,6 +1840,8 @@ int sde_cp_crtc_check_properties(struct drm_crtc *crtc, if (ret) { DRM_ERROR("failed check on prop_node %u\n", prop_node->property_id); + /* remove invalid feature from dirty list */ + list_del_init(&prop_node->dirty_list); goto exit; } } diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index b2baee1bf4ab..eeda022f1da7 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -421,6 +421,20 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn, avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width; } +int sde_connector_get_lm_cnt_from_topology(struct drm_connector *conn, + const struct drm_display_mode *drm_mode) +{ + struct sde_connector *c_conn; + + c_conn = to_sde_connector(conn); + + if (!c_conn || c_conn->connector_type != DRM_MODE_CONNECTOR_DSI || + !c_conn->ops.get_num_lm_from_mode) + return -EINVAL; + + return c_conn->ops.get_num_lm_from_mode(c_conn->display, drm_mode); +} + int sde_connector_get_mode_info(struct drm_connector *conn, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info) diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index aad04d29f2f4..94f868ccff29 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef _SDE_CONNECTOR_H_ @@ -382,6 +382,14 @@ struct sde_connector_ops { * Returns: Qsync min fps value on success */ int (*get_qsync_min_fps)(void *display, u32 mode_fps); + + /** + * get_num_lm_from_mode - Get LM count from topology for this drm mode + * @display: Pointer to private display structure + * @mode: Pointer to drm mode info structure + */ + int (*get_num_lm_from_mode)(void *display, const struct drm_display_mode *mode); + }; /** @@ -981,6 +989,15 @@ int sde_connector_helper_reset_custom_properties( int sde_connector_state_get_mode_info(struct drm_connector_state *conn_state, struct msm_mode_info *mode_info); +/** + * sde_connector_get_lm_cnt_from_topology - retrieves the topology info + * from the panel mode and returns the lm count. + * conn: Pointer to DRM connector object + * drm_mode: Pointer to the drm mode structure + */ +int sde_connector_get_lm_cnt_from_topology(struct drm_connector *conn, + const struct drm_display_mode *drm_mode); + /** * sde_connector_state_get_topology - get topology from given connector state * conn_state: Pointer to the DRM connector state object diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index a54e222a81b8..5f04f8e19188 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -2295,7 +2295,7 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc, dev = crtc->dev; sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); - SDE_EVT32_VERBOSE(DRMID(crtc)); + SDE_EVT32_VERBOSE(DRMID(crtc), cstate->cwb_enc_mask); SDE_ATRACE_BEGIN("sde_crtc_prepare_commit"); @@ -2315,6 +2315,7 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc, cstate->connectors[cstate->num_connectors++] = conn; sde_connector_prepare_fence(conn); + sde_encoder_set_clone_mode(encoder, crtc->state); } drm_connector_list_iter_end(&conn_iter); @@ -2377,7 +2378,7 @@ enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc, drm_for_each_encoder_mask(encoder, crtc->dev, cstate->encoder_mask) { /* continue if copy encoder is encountered */ - if (sde_encoder_in_clone_mode(encoder)) + if (sde_crtc_state_in_clone_mode(encoder, cstate)) continue; return sde_encoder_get_intf_mode(encoder); @@ -5075,40 +5076,57 @@ end: } /** - * sde_crtc_get_num_datapath - get the number of datapath active - * of primary connector + * sde_crtc_get_num_datapath - get the number of layermixers active + * on primary connector * @crtc: Pointer to DRM crtc object - * @connector: Pointer to DRM connector object of WB in CWB case + * @virtual_conn: Pointer to DRM connector object of WB in CWB case + * @crtc_state: Pointer to DRM crtc state */ int sde_crtc_get_num_datapath(struct drm_crtc *crtc, - struct drm_connector *connector) + struct drm_connector *virtual_conn, struct drm_crtc_state *crtc_state) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); + struct drm_connector *conn, *primary_conn = NULL; struct sde_connector_state *sde_conn_state = NULL; - struct drm_connector *conn; struct drm_connector_list_iter conn_iter; + int num_lm = 0; - if (!sde_crtc || !connector) { + if (!sde_crtc || !virtual_conn || !crtc_state) { SDE_DEBUG("Invalid argument\n"); return 0; } + /* return num_mixers used for primary when available in sde_crtc */ if (sde_crtc->num_mixers) return sde_crtc->num_mixers; drm_connector_list_iter_begin(crtc->dev, &conn_iter); drm_for_each_connector_iter(conn, &conn_iter) { - if (conn->state && conn->state->crtc == crtc && - conn != connector) + if ((drm_connector_mask(conn) & crtc_state->connector_mask) + && conn != virtual_conn) { sde_conn_state = to_sde_connector_state(conn->state); + primary_conn = conn; + break; + } } - drm_connector_list_iter_end(&conn_iter); + /* if primary sde_conn_state has mode info available, return num_lm from here */ if (sde_conn_state) - return sde_conn_state->mode_info.topology.num_lm; + num_lm = sde_conn_state->mode_info.topology.num_lm; - return 0; + /* if PM resume occurs with CWB enabled, retrieve num_lm from primary dsi panel mode */ + if (primary_conn && !num_lm) { + num_lm = sde_connector_get_lm_cnt_from_topology(primary_conn, + &crtc_state->adjusted_mode); + if (num_lm < 0) { + SDE_DEBUG("lm cnt fail for conn:%d num_lm:%d\n", + primary_conn->base.id, num_lm); + num_lm = 0; + } + } + + return num_lm; } int sde_crtc_vblank(struct drm_crtc *crtc, bool en) diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index c325097eeba8..98ee9a46090c 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -423,6 +423,7 @@ enum sde_crtc_dirty_flags { * @property_values: Current crtc property values * @input_fence_timeout_ns : Cached input fence timeout, in ns * @num_dim_layers: Number of dim layers + * @cwb_enc_mask : encoder mask populated during atomic_check if CWB is enabled * @dim_layer: Dim layer configs * @num_ds: Number of destination scalers to be configured * @num_ds_enabled: Number of destination scalers enabled @@ -451,6 +452,7 @@ struct sde_crtc_state { DECLARE_BITMAP(dirty, SDE_CRTC_DIRTY_MAX); uint64_t input_fence_timeout_ns; uint32_t num_dim_layers; + uint32_t cwb_enc_mask; struct sde_hw_dim_layer dim_layer[SDE_MAX_DIM_LAYERS]; uint32_t num_ds; uint32_t num_ds_enabled; @@ -804,6 +806,22 @@ static inline bool sde_crtc_atomic_check_has_modeset( return (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state)); } +static inline bool sde_crtc_state_in_clone_mode(struct drm_encoder *encoder, + struct drm_crtc_state *state) +{ + struct sde_crtc_state *cstate; + + if (!state || !encoder) + return false; + + cstate = to_sde_crtc_state(state); + if (sde_encoder_in_clone_mode(encoder) || + (cstate->cwb_enc_mask & drm_encoder_mask(encoder))) + return true; + + return false; +} + /** * sde_crtc_get_secure_transition - determines the operations to be * performed before transitioning to secure state @@ -927,9 +945,10 @@ void sde_crtc_static_cache_read_kickoff(struct drm_crtc *crtc); * of primary connector * @crtc: Pointer to DRM crtc object * @connector: Pointer to DRM connector object of WB in CWB case + * @crtc_state: Pointer to DRM crtc state */ int sde_crtc_get_num_datapath(struct drm_crtc *crtc, - struct drm_connector *connector); + struct drm_connector *connector, struct drm_crtc_state *crtc_state); /** * sde_crtc_reset_sw_state - reset dirty proerties on crtc and diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index e4cd09ba4d53..c4d7c021d311 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -783,6 +783,34 @@ bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc, return false; } +void sde_encoder_set_clone_mode(struct drm_encoder *drm_enc, + struct drm_crtc_state *crtc_state) +{ + struct sde_encoder_virt *sde_enc; + struct sde_crtc_state *sde_crtc_state; + int i = 0; + + if (!drm_enc || !crtc_state) { + SDE_DEBUG("invalid params\n"); + return; + } + sde_enc = to_sde_encoder_virt(drm_enc); + sde_crtc_state = to_sde_crtc_state(crtc_state); + + if ((sde_enc->disp_info.intf_type != DRM_MODE_CONNECTOR_VIRTUAL) || + (!(sde_crtc_state->cwb_enc_mask & drm_encoder_mask(drm_enc)))) + return; + + for (i = 0; i < sde_enc->num_phys_encs; i++) { + struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; + + if (phys) { + phys->in_clone_mode = true; + SDE_DEBUG("enc:%d phys state:%d\n", DRMID(drm_enc), phys->enable_state); + } + } +} + static int _sde_encoder_atomic_check_phys_enc(struct sde_encoder_virt *sde_enc, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index b5d791ae96ca..8e90c1408483 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -499,6 +499,14 @@ void sde_encoder_enable_recovery_event(struct drm_encoder *encoder); */ bool sde_encoder_in_clone_mode(struct drm_encoder *enc); +/** + * sde_encoder_set_clone_mode - cwb in wb phys enc is enabled. + * drm_enc: Pointer to drm encoder structure + * drm_crtc_state: Pointer to drm_crtc_state + */ +void sde_encoder_set_clone_mode(struct drm_encoder *drm_enc, + struct drm_crtc_state *crtc_state); + /* * sde_encoder_is_cwb_disabling - check if cwb encoder disable is pending * @drm_enc: Pointer to drm encoder structure diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 944a2c7e9eed..58ba064f73ec 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -604,6 +604,7 @@ static void _sde_enc_phys_wb_detect_cwb(struct sde_encoder_phys *phys_enc, struct drm_crtc_state *crtc_state) { struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); + struct sde_crtc_state *cstate = to_sde_crtc_state(crtc_state); const struct sde_wb_cfg *wb_cfg = wb_enc->hw_wb->caps; u32 encoder_mask = 0; @@ -612,9 +613,11 @@ static void _sde_enc_phys_wb_detect_cwb(struct sde_encoder_phys *phys_enc, encoder_mask = crtc_state->encoder_mask; encoder_mask &= ~drm_encoder_mask(phys_enc->parent); } - phys_enc->in_clone_mode = encoder_mask ? true : false; - SDE_DEBUG("detect CWB - status:%d\n", phys_enc->in_clone_mode); + cstate->cwb_enc_mask = encoder_mask ? drm_encoder_mask(phys_enc->parent) : 0; + + SDE_DEBUG("detect CWB - status:%d, phys state:%d in_clone_mode:%d\n", + cstate->cwb_enc_mask, phys_enc->enable_state, phys_enc->in_clone_mode); } static int _sde_enc_phys_wb_validate_cwb(struct sde_encoder_phys *phys_enc, @@ -755,6 +758,7 @@ static int sde_encoder_phys_wb_atomic_check( struct drm_connector_state *conn_state) { struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); + struct sde_crtc_state *cstate = to_sde_crtc_state(crtc_state); struct sde_hw_wb *hw_wb = wb_enc->hw_wb; const struct sde_wb_cfg *wb_cfg = hw_wb->caps; struct drm_framebuffer *fb; @@ -782,7 +786,7 @@ static int sde_encoder_phys_wb_atomic_check( _sde_enc_phys_wb_detect_cwb(phys_enc, crtc_state); - if (clone_mode_curr && !phys_enc->in_clone_mode) { + if (clone_mode_curr && !cstate->cwb_enc_mask) { SDE_ERROR("WB commit before CWB disable\n"); return -EINVAL; } @@ -841,7 +845,7 @@ static int sde_encoder_phys_wb_atomic_check( crtc_state->mode_changed = true; /* if in clone mode, return after cwb validation */ - if (phys_enc->in_clone_mode) { + if (cstate->cwb_enc_mask) { rc = _sde_enc_phys_wb_validate_cwb(phys_enc, crtc_state, conn_state); if (rc) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 6032d6fe5ec8..74896a8edb2c 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -4770,7 +4770,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->mdss_hw_block_size = 0x158; sde_cfg->has_trusted_vm_support = true; sde_cfg->syscache_supported = true; - } else if (IS_HOLI_TARGET(hw_rev)) { + } else if (IS_HOLI_TARGET(hw_rev) || IS_BLAIR_TARGET(hw_rev)) { sde_cfg->has_cwb_support = false; sde_cfg->has_qsync = true; sde_cfg->perf.min_prefill_lines = 24; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 593b52ca6eba..6bfaf2bf5080 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -46,6 +46,7 @@ #define SDE_HW_VER_650 SDE_HW_VER(6, 5, 0) /* scuba */ #define SDE_HW_VER_660 SDE_HW_VER(6, 6, 0) /* holi */ #define SDE_HW_VER_670 SDE_HW_VER(6, 7, 0) /* shima */ +#define SDE_HW_VER_690 SDE_HW_VER(6, 9, 0) /* blair */ #define SDE_HW_VER_700 SDE_HW_VER(7, 0, 0) /* lahaina */ #define SDE_HW_VER_720 SDE_HW_VER(7, 2, 0) /* yupik */ @@ -71,6 +72,7 @@ #define IS_SCUBA_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_650) #define IS_HOLI_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_660) #define IS_SHIMA_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_670) +#define IS_BLAIR_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_690) #define IS_LAHAINA_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_700) #define IS_YUPIK_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_720) diff --git a/msm/sde/sde_hw_color_proc_v4.c b/msm/sde/sde_hw_color_proc_v4.c index 2bf3e1930ac7..2aa305324e1a 100644 --- a/msm/sde/sde_hw_color_proc_v4.c +++ b/msm/sde/sde_hw_color_proc_v4.c @@ -423,8 +423,8 @@ void sde_demura_backlight_cfg(struct sde_hw_dspp *dspp, u64 val) return; } demura_base = dspp->cap->sblk->demura.base; - backlight = (val & REG_MASK(11)); - backlight |= ((val & REG_MASK_SHIFT(11, 32)) >> 16); + backlight = (val & REG_MASK_ULL(11)); + backlight |= ((val & REG_MASK_SHIFT_ULL(11, 32)) >> 16); SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->demura.base + 0x8, backlight); } diff --git a/msm/sde/sde_hw_reg_dma_v1.c b/msm/sde/sde_hw_reg_dma_v1.c index 464d154f4a95..7b73dafecddc 100644 --- a/msm/sde/sde_hw_reg_dma_v1.c +++ b/msm/sde/sde_hw_reg_dma_v1.c @@ -880,7 +880,8 @@ static int check_support_v1(enum sde_reg_dma_features feature, if (!is_supported) return -EINVAL; - if (feature >= REG_DMA_FEATURES_MAX || blk >= BIT(REG_DMA_BLK_MAX)) { + if (feature >= REG_DMA_FEATURES_MAX + || blk >= BIT_ULL(REG_DMA_BLK_MAX)) { *is_supported = false; return ret; } diff --git a/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/msm/sde/sde_hw_reg_dma_v1_color_proc.c index 93d9b58729a1..199550c078d1 100644 --- a/msm/sde/sde_hw_reg_dma_v1_color_proc.c +++ b/msm/sde/sde_hw_reg_dma_v1_color_proc.c @@ -12,6 +12,7 @@ #include "sde_hwio.h" #include "sde_hw_lm.h" #include "sde_dbg.h" +#include "sde_hw_util.h" /* Reserve space of 128 words for LUT dma payload set-up */ #define REG_DMA_HEADERS_BUFFER_SZ (sizeof(u32) * 128) @@ -84,8 +85,6 @@ #define DEMURA_MEM_SIZE ((sizeof(struct drm_msm_dem_cfg)) + \ REG_DMA_HEADERS_BUFFER_SZ) -#define REG_MASK(n) ((BIT(n)) - 1) -#define REG_MASK_SHIFT(n, shift) ((REG_MASK(n)) << (shift)) #define APPLY_MASK_AND_SHIFT(x, n, shift) ((x & (REG_MASK(n))) << (shift)) #define REG_DMA_VIG_GAMUT_OP_MASK 0x300 #define REG_DMA_VIG_IGC_OP_MASK 0x1001F @@ -4926,8 +4925,8 @@ static int __reg_dmav1_setup_demurav1_cfg0_c_params( } for (i = 0; i < len; i++) { - temp[i * 2] = p[i] & REG_MASK(32); - temp[i * 2 + 1] = (p[i] & REG_MASK_SHIFT(10, 32)) >> 32; + temp[i * 2] = p[i] & REG_MASK_ULL(32); + temp[i * 2 + 1] = (p[i] & REG_MASK_SHIFT_ULL(10, 32)) >> 32; DRM_DEBUG_DRIVER("0x6c: index %d value %x\n", i * 2, temp[i * 2]); DRM_DEBUG_DRIVER("0x6c: index %d value %x\n", diff --git a/msm/sde/sde_hw_util.h b/msm/sde/sde_hw_util.h index 38c0106181b6..668fe833a498 100644 --- a/msm/sde/sde_hw_util.h +++ b/msm/sde/sde_hw_util.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #ifndef _SDE_HW_UTIL_H @@ -12,7 +12,9 @@ #include "sde_hw_catalog.h" #define REG_MASK(n) ((BIT(n)) - 1) -#define REG_MASK_SHIFT(n, shift) ((REG_MASK(n)) << (shift)) +#define REG_MASK_SHIFT(n, shift) ((REG_MASK(n)) << (shift)) +#define REG_MASK_ULL(n) ((BIT_ULL(n)) - 1) +#define REG_MASK_SHIFT_ULL(n, shift) ((REG_MASK_ULL(n)) << (shift)) #define LP_DDR4_TYPE 0x7 struct sde_format_extended; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index df3e6a41b341..e48a1e20f8b3 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1748,6 +1748,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .set_allowed_mode_switch = dsi_conn_set_allowed_mode_switch, .get_qsync_min_fps = dsi_display_get_qsync_min_fps, .prepare_commit = dsi_conn_prepare_commit, + .get_num_lm_from_mode = dsi_conn_get_lm_from_mode, }; static const struct sde_connector_ops wb_ops = { .post_init = sde_wb_connector_post_init, @@ -3253,9 +3254,10 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms, return rc; } -static bool sde_kms_check_for_splash(struct msm_kms *kms) +static bool sde_kms_check_for_splash(struct msm_kms *kms, struct drm_crtc *crtc) { struct sde_kms *sde_kms; + struct drm_encoder *encoder; if (!kms) { SDE_ERROR("invalid kms\n"); @@ -3263,7 +3265,16 @@ static bool sde_kms_check_for_splash(struct msm_kms *kms) } sde_kms = to_sde_kms(kms); - return sde_kms->splash_data.num_splash_displays; + if (!crtc || !sde_kms->splash_data.num_splash_displays) + return sde_kms->splash_data.num_splash_displays; + + drm_for_each_encoder_mask(encoder, crtc->dev, + crtc->state->encoder_mask) { + if (sde_encoder_in_cont_splash(encoder)) + return true; + } + + return false; } static int sde_kms_get_mixer_count(const struct msm_kms *kms, diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index cb3d589bd072..f5221aae3f26 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -2040,7 +2040,7 @@ static int _sde_rm_populate_requirements( * Set the requirement for LM which has CWB support if CWB is * found enabled. */ - if (!RM_RQ_CWB(reqs) && sde_encoder_in_clone_mode(enc)) { + if (!RM_RQ_CWB(reqs) && sde_crtc_state_in_clone_mode(enc, crtc_state)) { reqs->top_ctrl |= BIT(SDE_RM_TOPCTL_CWB); /* @@ -2054,7 +2054,7 @@ static int _sde_rm_populate_requirements( &rm->topology_tbl[SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE]; num_lm = sde_crtc_get_num_datapath(crtc_state->crtc, - conn_state->connector); + conn_state->connector, crtc_state); if (num_lm == 1) reqs->topology = diff --git a/msm/sde_power_handle.c b/msm/sde_power_handle.c index c0f3774fa399..88d945bc3e11 100644 --- a/msm/sde_power_handle.c +++ b/msm/sde_power_handle.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d]: " fmt, __func__, __LINE__ @@ -299,8 +299,8 @@ static int _sde_power_data_bus_set_quota( for (i = 0; i < paths; i++) { if (pdbus->data_bus_hdl[i]) { rc = icc_set_bw(pdbus->data_bus_hdl[i], - Bps_to_icc(in_ab_quota), - Bps_to_icc(in_ib_quota)); + kBps_to_icc(div_u64(in_ab_quota, 1000)), + kBps_to_icc(div_u64(in_ib_quota, 1000))); if (rc) goto err; } @@ -316,8 +316,8 @@ err: for (; i >= 0; --i) if (pdbus->data_bus_hdl[i]) icc_set_bw(pdbus->data_bus_hdl[i], - Bps_to_icc(pdbus->curr_val.ab), - Bps_to_icc(pdbus->curr_val.ib)); + kBps_to_icc(div_u64(pdbus->curr_val.ab, 1000)), + kBps_to_icc(div_u64(pdbus->curr_val.ib, 1000))); SDE_ATRACE_END("msm_bus_scale_req"); pr_err("failed to set data bus vote ab=%llu ib=%llu rc=%d\n", @@ -530,8 +530,9 @@ static int sde_power_reg_bus_update(struct sde_power_reg_bus_handle *reg_bus, if (reg_bus->reg_bus_hdl) { SDE_ATRACE_BEGIN("msm_bus_scale_req"); - rc = icc_set_bw(reg_bus->reg_bus_hdl, Bps_to_icc(ab_quota), - Bps_to_icc(ib_quota)); + rc = icc_set_bw(reg_bus->reg_bus_hdl, + kBps_to_icc(div_u64(ab_quota, 1000)), + kBps_to_icc(div_u64(ib_quota, 1000))); SDE_ATRACE_END("msm_bus_scale_req"); } diff --git a/msm/sde_vdc_helper.c b/msm/sde_vdc_helper.c index 3101a7ea7aad..379a07e164bb 100644 --- a/msm/sde_vdc_helper.c +++ b/msm/sde_vdc_helper.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include "msm_drv.h" @@ -550,7 +550,7 @@ static int sde_vdc_populate_core_params(struct msm_display_vdc_info *vdc_info, temp = temp << 16; vdc_info->ramp_bits = temp; - temp = vdc_info->ramp_bits / vdc_info->ramp_blocks; + temp = div_u64(vdc_info->ramp_bits, vdc_info->ramp_blocks); vdc_info->rc_fullness_offset_slope = temp; temp = (2 * SSM_MAX_SE_SIZE) - 2; diff --git a/rotator/sde_rotator_base.h b/rotator/sde_rotator_base.h index 620bf94ade4a..ece09b8edf06 100644 --- a/rotator/sde_rotator_base.h +++ b/rotator/sde_rotator_base.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #ifndef __SDE_ROTATOR_BASE_H__ @@ -48,6 +48,7 @@ #define SDE_MDP_HW_REV_600 SDE_MDP_REV(6, 0, 0) /* msmnile+ v1.0 */ #define SDE_MDP_HW_REV_630 SDE_MDP_REV(6, 3, 0) /* bengal v1.0 */ #define SDE_MDP_HW_REV_660 SDE_MDP_REV(6, 6, 0) /* holi */ +#define SDE_MDP_HW_REV_690 SDE_MDP_REV(6, 9, 0) /* blair */ #define SDE_MDP_VBIF_4_LEVEL_REMAPPER 4 #define SDE_MDP_VBIF_8_LEVEL_REMAPPER 8 diff --git a/rotator/sde_rotator_r3.c b/rotator/sde_rotator_r3.c index 5a1f4ebae7d4..19100a5bcd49 100644 --- a/rotator/sde_rotator_r3.c +++ b/rotator/sde_rotator_r3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s:%d: " fmt, __func__, __LINE__ @@ -3501,7 +3501,8 @@ static int sde_rotator_hw_rev_init(struct sde_hw_rotator *rot) rot->downscale_caps = "LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2"; } else if (IS_SDE_MAJOR_MINOR_SAME(mdata->mdss_version, - SDE_MDP_HW_REV_660)) { + SDE_MDP_HW_REV_660) || IS_SDE_MAJOR_MINOR_SAME( + mdata->mdss_version, SDE_MDP_HW_REV_690)) { SDEROT_DBG("Sys cache inline rotation not supported\n"); set_bit(SDE_CAPS_PARTIALWR, mdata->sde_caps_map); set_bit(SDE_CAPS_HW_TIMESTAMP, mdata->sde_caps_map);