Commit 2470e932 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov

Merge branch 'msm-next-lumag-dpu' into msm-next-lumag

Merge DPU changes, resolving conflicts between branches. Full changelog
will be present in the final merge commit.

DPU:
 - DSPP sub-block flush on sc7280
 - support AR30 in addition to XR30 format
 - Allow using REC_0 and REC_1 to handle wide (4k) RGB planes
Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
parents 6ec59381 c6c65568
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8550-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8550 Display DPU
maintainers:
- Neil Armstrong <neil.armstrong@linaro.org>
$ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
const: qcom,sm8550-dpu
reg:
items:
- description: Address offset and size for mdp register set
- description: Address offset and size for vbif register set
reg-names:
items:
- const: mdp
- const: vbif
clocks:
items:
- description: Display AHB
- description: Display hf axi
- description: Display MDSS ahb
- description: Display lut
- description: Display core
- description: Display vsync
clock-names:
items:
- const: bus
- const: nrt_bus
- const: iface
- const: lut
- const: core
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,sm8550-dispcc.h>
#include <dt-bindings/clock/qcom,sm8550-gcc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8550-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc GCC_DISP_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>,
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "bus",
"nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8550_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpu_intf1_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
port@1 {
reg = <1>;
dpu_intf2_out: endpoint {
remote-endpoint = <&dsi1_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-325000000 {
opp-hz = /bits/ 64 <325000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-375000000 {
opp-hz = /bits/ 64 <375000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-514000000 {
opp-hz = /bits/ 64 <514000000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
};
...
This diff is collapsed.
...@@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) ...@@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
static struct msm_display_topology dpu_encoder_get_topology( static struct msm_display_topology dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc, struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms, struct dpu_kms *dpu_kms,
struct drm_display_mode *mode) struct drm_display_mode *mode,
struct drm_crtc_state *crtc_state)
{ {
struct msm_display_topology topology = {0}; struct msm_display_topology topology = {0};
int i, intf_count = 0; int i, intf_count = 0;
...@@ -563,8 +564,7 @@ static struct msm_display_topology dpu_encoder_get_topology( ...@@ -563,8 +564,7 @@ static struct msm_display_topology dpu_encoder_get_topology(
* 1 LM, 1 INTF * 1 LM, 1 INTF
* 2 LM, 1 INTF (stream merge to support high resolution interfaces) * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
* *
* Adding color blocks only to primary interface if available in * Add dspps to the reservation requirements if ctm is requested
* sufficient number
*/ */
if (intf_count == 2) if (intf_count == 2)
topology.num_lm = 2; topology.num_lm = 2;
...@@ -573,11 +573,8 @@ static struct msm_display_topology dpu_encoder_get_topology( ...@@ -573,11 +573,8 @@ static struct msm_display_topology dpu_encoder_get_topology(
else else
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { if (crtc_state->ctm)
if (dpu_kms->catalog->dspp && topology.num_dspp = topology.num_lm;
(dpu_kms->catalog->dspp_count >= topology.num_lm))
topology.num_dspp = topology.num_lm;
}
topology.num_intf = intf_count; topology.num_intf = intf_count;
...@@ -638,25 +635,22 @@ static int dpu_encoder_virt_atomic_check( ...@@ -638,25 +635,22 @@ static int dpu_encoder_virt_atomic_check(
if (ret) { if (ret) {
DPU_ERROR_ENC(dpu_enc, DPU_ERROR_ENC(dpu_enc,
"mode unsupported, phys idx %d\n", i); "mode unsupported, phys idx %d\n", i);
break; return ret;
} }
} }
topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state);
/* Reserve dynamic resources now. */ /*
if (!ret) { * Release and Allocate resources on every modeset
/* * Dont allocate when active is false.
* Release and Allocate resources on every modeset */
* Dont allocate when active is false. if (drm_atomic_crtc_needs_modeset(crtc_state)) {
*/ dpu_rm_release(global_state, drm_enc);
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
dpu_rm_release(global_state, drm_enc);
if (!crtc_state->active_changed || crtc_state->enable) if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state, ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
drm_enc, crtc_state, topology); drm_enc, crtc_state, topology);
}
} }
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
...@@ -2094,25 +2088,6 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) ...@@ -2094,25 +2088,6 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
ctl->ops.clear_pending_flush(ctl); ctl->ops.clear_pending_flush(ctl);
} }
void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc)
{
struct dpu_encoder_virt *dpu_enc;
struct dpu_encoder_phys *phys;
int i;
if (!drm_enc) {
DPU_ERROR("invalid encoder\n");
return;
}
dpu_enc = to_dpu_encoder_virt(drm_enc);
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
phys = dpu_enc->phys_encs[i];
if (phys->ops.prepare_commit)
phys->ops.prepare_commit(phys);
}
}
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
static int _dpu_encoder_status_show(struct seq_file *s, void *data) static int _dpu_encoder_status_show(struct seq_file *s, void *data)
{ {
......
...@@ -146,13 +146,6 @@ struct drm_encoder *dpu_encoder_init( ...@@ -146,13 +146,6 @@ struct drm_encoder *dpu_encoder_init(
int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
struct msm_display_info *disp_info); struct msm_display_info *disp_info);
/**
* dpu_encoder_prepare_commit - prepare encoder at the very beginning of an
* atomic commit, before any registers are written
* @drm_enc: Pointer to previously created drm encoder structure
*/
void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc);
/** /**
* dpu_encoder_set_idle_timeout - set the idle timeout for video * dpu_encoder_set_idle_timeout - set the idle timeout for video
* and command mode encoders. * and command mode encoders.
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#define DPU_ENC_MAX_POLL_TIMEOUT_US 2000 #define DPU_ENC_MAX_POLL_TIMEOUT_US 2000
static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc);
static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc) static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc)
{ {
return (phys_enc->split_role != ENC_ROLE_SLAVE); return (phys_enc->split_role != ENC_ROLE_SLAVE);
...@@ -565,6 +567,8 @@ static void dpu_encoder_phys_cmd_prepare_for_kickoff( ...@@ -565,6 +567,8 @@ static void dpu_encoder_phys_cmd_prepare_for_kickoff(
phys_enc->hw_pp->idx - PINGPONG_0); phys_enc->hw_pp->idx - PINGPONG_0);
} }
dpu_encoder_phys_cmd_enable_te(phys_enc);
DPU_DEBUG_CMDENC(cmd_enc, "pp:%d pending_cnt %d\n", DPU_DEBUG_CMDENC(cmd_enc, "pp:%d pending_cnt %d\n",
phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->hw_pp->idx - PINGPONG_0,
atomic_read(&phys_enc->pending_kickoff_cnt)); atomic_read(&phys_enc->pending_kickoff_cnt));
...@@ -586,8 +590,7 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx( ...@@ -586,8 +590,7 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
return false; return false;
} }
static void dpu_encoder_phys_cmd_prepare_commit( static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc)
struct dpu_encoder_phys *phys_enc)
{ {
struct dpu_encoder_phys_cmd *cmd_enc = struct dpu_encoder_phys_cmd *cmd_enc =
to_dpu_encoder_phys_cmd(phys_enc); to_dpu_encoder_phys_cmd(phys_enc);
...@@ -732,7 +735,6 @@ static void dpu_encoder_phys_cmd_trigger_start( ...@@ -732,7 +735,6 @@ static void dpu_encoder_phys_cmd_trigger_start(
static void dpu_encoder_phys_cmd_init_ops( static void dpu_encoder_phys_cmd_init_ops(
struct dpu_encoder_phys_ops *ops) struct dpu_encoder_phys_ops *ops)
{ {
ops->prepare_commit = dpu_encoder_phys_cmd_prepare_commit;
ops->is_master = dpu_encoder_phys_cmd_is_master; ops->is_master = dpu_encoder_phys_cmd_is_master;
ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set; ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set;
ops->enable = dpu_encoder_phys_cmd_enable; ops->enable = dpu_encoder_phys_cmd_enable;
......
...@@ -536,6 +536,16 @@ static const struct dpu_format dpu_format_map_ubwc[] = { ...@@ -536,6 +536,16 @@ static const struct dpu_format dpu_format_map_ubwc[] = {
true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED, true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC), DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
/* XRGB2101010 and ARGB2101010 purposely have the same color
* ordering. The hardware only supports ARGB2101010 UBWC
* natively.
*/
INTERLEAVED_RGB_FMT_TILED(ARGB2101010,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
PSEUDO_YUV_FMT_TILED(NV12, PSEUDO_YUV_FMT_TILED(NV12,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C2_R_Cr, C1_B_Cb, C2_R_Cr,
...@@ -591,6 +601,7 @@ static int _dpu_format_get_media_color_ubwc(const struct dpu_format *fmt) ...@@ -591,6 +601,7 @@ static int _dpu_format_get_media_color_ubwc(const struct dpu_format *fmt)
{DRM_FORMAT_XBGR8888, COLOR_FMT_RGBA8888_UBWC}, {DRM_FORMAT_XBGR8888, COLOR_FMT_RGBA8888_UBWC},
{DRM_FORMAT_XRGB8888, COLOR_FMT_RGBA8888_UBWC}, {DRM_FORMAT_XRGB8888, COLOR_FMT_RGBA8888_UBWC},
{DRM_FORMAT_ABGR2101010, COLOR_FMT_RGBA1010102_UBWC}, {DRM_FORMAT_ABGR2101010, COLOR_FMT_RGBA1010102_UBWC},
{DRM_FORMAT_ARGB2101010, COLOR_FMT_RGBA1010102_UBWC},
{DRM_FORMAT_XRGB2101010, COLOR_FMT_RGBA1010102_UBWC}, {DRM_FORMAT_XRGB2101010, COLOR_FMT_RGBA1010102_UBWC},
{DRM_FORMAT_XBGR2101010, COLOR_FMT_RGBA1010102_UBWC}, {DRM_FORMAT_XBGR2101010, COLOR_FMT_RGBA1010102_UBWC},
{DRM_FORMAT_BGR565, COLOR_FMT_RGB565_UBWC}, {DRM_FORMAT_BGR565, COLOR_FMT_RGB565_UBWC},
...@@ -918,8 +929,7 @@ int dpu_format_populate_layout( ...@@ -918,8 +929,7 @@ int dpu_format_populate_layout(
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
struct dpu_hw_fmt_layout *layout) struct dpu_hw_fmt_layout *layout)
{ {
uint32_t plane_addr[DPU_MAX_PLANES]; int ret;
int i, ret;
if (!fb || !layout) { if (!fb || !layout) {
DRM_ERROR("invalid arguments\n"); DRM_ERROR("invalid arguments\n");
...@@ -940,9 +950,6 @@ int dpu_format_populate_layout( ...@@ -940,9 +950,6 @@ int dpu_format_populate_layout(
if (ret) if (ret)
return ret; return ret;
for (i = 0; i < DPU_MAX_PLANES; ++i)
plane_addr[i] = layout->plane_addr[i];
/* Populate the addresses given the fb */ /* Populate the addresses given the fb */
if (DPU_FORMAT_IS_UBWC(layout->format) || if (DPU_FORMAT_IS_UBWC(layout->format) ||
DPU_FORMAT_IS_TILE(layout->format)) DPU_FORMAT_IS_TILE(layout->format))
...@@ -950,10 +957,6 @@ int dpu_format_populate_layout( ...@@ -950,10 +957,6 @@ int dpu_format_populate_layout(
else else
ret = _dpu_format_populate_addrs_linear(aspace, fb, layout); ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
/* check if anything changed */
if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
ret = -EAGAIN;
return ret; return ret;
} }
......
...@@ -19,8 +19,9 @@ ...@@ -19,8 +19,9 @@
*/ */
#define MAX_BLOCKS 12 #define MAX_BLOCKS 12
#define DPU_HW_VER(MAJOR, MINOR, STEP) (((MAJOR & 0xF) << 28) |\ #define DPU_HW_VER(MAJOR, MINOR, STEP) \
((MINOR & 0xFFF) << 16) |\ ((((unsigned int)MAJOR & 0xF) << 28) | \
((MINOR & 0xFFF) << 16) | \
(STEP & 0xFFFF)) (STEP & 0xFFFF))
#define DPU_HW_MAJOR(rev) ((rev) >> 28) #define DPU_HW_MAJOR(rev) ((rev) >> 28)
...@@ -169,10 +170,12 @@ enum { ...@@ -169,10 +170,12 @@ enum {
* DSPP sub-blocks * DSPP sub-blocks
* @DPU_DSPP_PCC Panel color correction block * @DPU_DSPP_PCC Panel color correction block
* @DPU_DSPP_GC Gamma correction block * @DPU_DSPP_GC Gamma correction block
* @DPU_DSPP_IGC Inverse gamma correction block
*/ */
enum { enum {
DPU_DSPP_PCC = 0x1, DPU_DSPP_PCC = 0x1,
DPU_DSPP_GC, DPU_DSPP_GC,
DPU_DSPP_IGC,
DPU_DSPP_MAX DPU_DSPP_MAX
}; };
...@@ -200,6 +203,7 @@ enum { ...@@ -200,6 +203,7 @@ enum {
* @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs) * @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs)
* @DPU_CTL_VM_CFG: CTL config to support multiple VMs * @DPU_CTL_VM_CFG: CTL config to support multiple VMs
* @DPU_CTL_HAS_LAYER_EXT4: CTL has the CTL_LAYER_EXT4 register * @DPU_CTL_HAS_LAYER_EXT4: CTL has the CTL_LAYER_EXT4 register
* @DPU_CTL_DSPP_BLOCK_FLUSH: CTL config to support dspp sub-block flush
* @DPU_CTL_MAX * @DPU_CTL_MAX
*/ */
enum { enum {
...@@ -208,6 +212,7 @@ enum { ...@@ -208,6 +212,7 @@ enum {
DPU_CTL_FETCH_ACTIVE, DPU_CTL_FETCH_ACTIVE,
DPU_CTL_VM_CFG, DPU_CTL_VM_CFG,
DPU_CTL_HAS_LAYER_EXT4, DPU_CTL_HAS_LAYER_EXT4,
DPU_CTL_DSPP_SUB_BLOCK_FLUSH,
DPU_CTL_MAX DPU_CTL_MAX
}; };
...@@ -395,7 +400,6 @@ struct dpu_rotation_cfg { ...@@ -395,7 +400,6 @@ struct dpu_rotation_cfg {
* @max_mixer_blendstages max layer mixer blend stages or * @max_mixer_blendstages max layer mixer blend stages or
* supported z order * supported z order
* @qseed_type qseed2 or qseed3 support. * @qseed_type qseed2 or qseed3 support.
* @smart_dma_rev Supported version of SmartDMA feature.
* @ubwc_version UBWC feature version (0x0 for not supported) * @ubwc_version UBWC feature version (0x0 for not supported)
* @has_src_split source split feature status * @has_src_split source split feature status
* @has_dim_layer dim layer feature status * @has_dim_layer dim layer feature status
...@@ -410,7 +414,6 @@ struct dpu_caps { ...@@ -410,7 +414,6 @@ struct dpu_caps {
u32 max_mixer_width; u32 max_mixer_width;
u32 max_mixer_blendstages; u32 max_mixer_blendstages;
u32 qseed_type; u32 qseed_type;
u32 smart_dma_rev;
u32 ubwc_version; u32 ubwc_version;
bool has_src_split; bool has_src_split;
bool has_dim_layer; bool has_dim_layer;
......
...@@ -26,15 +26,16 @@ ...@@ -26,15 +26,16 @@
#define CTL_SW_RESET 0x030 #define CTL_SW_RESET 0x030
#define CTL_LAYER_EXTN_OFFSET 0x40 #define CTL_LAYER_EXTN_OFFSET 0x40
#define CTL_MERGE_3D_ACTIVE 0x0E4 #define CTL_MERGE_3D_ACTIVE 0x0E4
#define CTL_DSC_ACTIVE 0x0E8
#define CTL_WB_ACTIVE 0x0EC #define CTL_WB_ACTIVE 0x0EC
#define CTL_INTF_ACTIVE 0x0F4 #define CTL_INTF_ACTIVE 0x0F4
#define CTL_FETCH_PIPE_ACTIVE 0x0FC
#define CTL_MERGE_3D_FLUSH 0x100 #define CTL_MERGE_3D_FLUSH 0x100
#define CTL_DSC_ACTIVE 0x0E8
#define CTL_DSC_FLUSH 0x104 #define CTL_DSC_FLUSH 0x104
#define CTL_WB_FLUSH 0x108 #define CTL_WB_FLUSH 0x108
#define CTL_INTF_FLUSH 0x110 #define CTL_INTF_FLUSH 0x110
#define CTL_INTF_MASTER 0x134 #define CTL_INTF_MASTER 0x134
#define CTL_FETCH_PIPE_ACTIVE 0x0FC #define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4))
#define CTL_MIXER_BORDER_OUT BIT(24) #define CTL_MIXER_BORDER_OUT BIT(24)
#define CTL_FLUSH_MASK_CTL BIT(17) #define CTL_FLUSH_MASK_CTL BIT(17)
...@@ -44,6 +45,7 @@ ...@@ -44,6 +45,7 @@
#define DSC_IDX 22 #define DSC_IDX 22
#define INTF_IDX 31 #define INTF_IDX 31
#define WB_IDX 16 #define WB_IDX 16
#define DSPP_IDX 29 /* From DPU hw rev 7.x.x */
#define CTL_INVALID_BIT 0xffff #define CTL_INVALID_BIT 0xffff
#define CTL_DEFAULT_GROUP_ID 0xf #define CTL_DEFAULT_GROUP_ID 0xf
...@@ -115,6 +117,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) ...@@ -115,6 +117,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask, trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask,
dpu_hw_ctl_get_flush_register(ctx)); dpu_hw_ctl_get_flush_register(ctx));
ctx->pending_flush_mask = 0x0; ctx->pending_flush_mask = 0x0;
memset(ctx->pending_dspp_flush_mask, 0,
sizeof(ctx->pending_dspp_flush_mask));
} }
static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx, static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx,
...@@ -132,6 +137,8 @@ static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx) ...@@ -132,6 +137,8 @@ static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx)
static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
{ {
int dspp;
if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX)) if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX))
DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH, DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH,
ctx->pending_merge_3d_flush_mask); ctx->pending_merge_3d_flush_mask);
...@@ -142,6 +149,13 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) ...@@ -142,6 +149,13 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH, DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH,
ctx->pending_wb_flush_mask); ctx->pending_wb_flush_mask);
if (ctx->pending_flush_mask & BIT(DSPP_IDX))
for (dspp = DSPP_0; dspp < DSPP_MAX; dspp++) {
if (ctx->pending_dspp_flush_mask[dspp - DSPP_0])
DPU_REG_WRITE(&ctx->hw,
CTL_DSPP_n_FLUSH(dspp - DSPP_0),
ctx->pending_dspp_flush_mask[dspp - DSPP_0]);
}
DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
} }
...@@ -289,7 +303,7 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx, ...@@ -289,7 +303,7 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
} }
static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
enum dpu_dspp dspp) enum dpu_dspp dspp, u32 dspp_sub_blk)
{ {
switch (dspp) { switch (dspp) {
case DSPP_0: case DSPP_0:
...@@ -309,6 +323,29 @@ static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, ...@@ -309,6 +323,29 @@ static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
} }
} }
static void dpu_hw_ctl_update_pending_flush_dspp_sub_blocks(
struct dpu_hw_ctl *ctx, enum dpu_dspp dspp, u32 dspp_sub_blk)
{
if (dspp >= DSPP_MAX)
return;
switch (dspp_sub_blk) {
case DPU_DSPP_IGC:
ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(2);
break;
case DPU_DSPP_PCC:
ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(4);
break;
case DPU_DSPP_GC:
ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(5);
break;
default:
return;
}
ctx->pending_flush_mask |= BIT(DSPP_IDX);
}
static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us) static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
{ {
struct dpu_hw_blk_reg_map *c = &ctx->hw; struct dpu_hw_blk_reg_map *c = &ctx->hw;
...@@ -630,7 +667,11 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ...@@ -630,7 +667,11 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->setup_blendstage = dpu_hw_ctl_setup_blendstage; ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp; ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp;
ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer; ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer;
ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp; if (cap & BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH))
ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp_sub_blocks;
else
ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;
if (cap & BIT(DPU_CTL_FETCH_ACTIVE)) if (cap & BIT(DPU_CTL_FETCH_ACTIVE))
ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
}; };
......
...@@ -152,9 +152,11 @@ struct dpu_hw_ctl_ops { ...@@ -152,9 +152,11 @@ struct dpu_hw_ctl_ops {
* No effect on hardware * No effect on hardware
* @ctx : ctl path ctx pointer * @ctx : ctl path ctx pointer
* @blk : DSPP block index * @blk : DSPP block index
* @dspp_sub_blk : DSPP sub-block index
*/ */
void (*update_pending_flush_dspp)(struct dpu_hw_ctl *ctx, void (*update_pending_flush_dspp)(struct dpu_hw_ctl *ctx,
enum dpu_dspp blk); enum dpu_dspp blk, u32 dspp_sub_blk);
/** /**
* Write the value of the pending_flush_mask to hardware * Write the value of the pending_flush_mask to hardware
* @ctx : ctl path ctx pointer * @ctx : ctl path ctx pointer
...@@ -242,6 +244,7 @@ struct dpu_hw_ctl { ...@@ -242,6 +244,7 @@ struct dpu_hw_ctl {
u32 pending_intf_flush_mask; u32 pending_intf_flush_mask;
u32 pending_wb_flush_mask; u32 pending_wb_flush_mask;
u32 pending_merge_3d_flush_mask; u32 pending_merge_3d_flush_mask;
u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
/* ops */ /* ops */
struct dpu_hw_ctl_ops ops; struct dpu_hw_ctl_ops ops;
......
This diff is collapsed.
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "dpu_hw_util.h" #include "dpu_hw_util.h"
#include "dpu_formats.h" #include "dpu_formats.h"
struct dpu_hw_pipe; struct dpu_hw_sspp;
/** /**
* Flags * Flags
...@@ -153,20 +153,14 @@ struct dpu_hw_pixel_ext { ...@@ -153,20 +153,14 @@ struct dpu_hw_pixel_ext {
}; };
/** /**
* struct dpu_hw_pipe_cfg : Pipe description * struct dpu_sw_pipe_cfg : software pipe configuration
* @layout: format layout information for programming buffer to hardware
* @src_rect: src ROI, caller takes into account the different operations * @src_rect: src ROI, caller takes into account the different operations
* such as decimation, flip etc to program this field * such as decimation, flip etc to program this field
* @dest_rect: destination ROI. * @dest_rect: destination ROI.
* @index: index of the rectangle of SSPP
* @mode: parallel or time multiplex multirect mode
*/ */
struct dpu_hw_pipe_cfg { struct dpu_sw_pipe_cfg {
struct dpu_hw_fmt_layout layout;
struct drm_rect src_rect; struct drm_rect src_rect;
struct drm_rect dst_rect; struct drm_rect dst_rect;
enum dpu_sspp_multirect_index index;
enum dpu_sspp_multirect_mode mode;
}; };
/** /**
...@@ -201,6 +195,18 @@ struct dpu_hw_pipe_ts_cfg { ...@@ -201,6 +195,18 @@ struct dpu_hw_pipe_ts_cfg {
u64 time; u64 time;
}; };
/**
* struct dpu_sw_pipe - software pipe description
* @sspp: backing SSPP pipe
* @index: index of the rectangle of SSPP
* @mode: parallel or time multiplex multirect mode
*/
struct dpu_sw_pipe {
struct dpu_hw_sspp *sspp;
enum dpu_sspp_multirect_index multirect_index;
enum dpu_sspp_multirect_mode multirect_mode;
};
/** /**
* struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
* Caller must call the init function to get the pipe context for each pipe * Caller must call the init function to get the pipe context for each pipe
...@@ -209,77 +215,65 @@ struct dpu_hw_pipe_ts_cfg { ...@@ -209,77 +215,65 @@ struct dpu_hw_pipe_ts_cfg {
struct dpu_hw_sspp_ops { struct dpu_hw_sspp_ops {
/** /**
* setup_format - setup pixel format cropping rectangle, flip * setup_format - setup pixel format cropping rectangle, flip
* @ctx: Pointer to pipe context * @pipe: Pointer to software pipe context
* @cfg: Pointer to pipe config structure * @cfg: Pointer to pipe config structure
* @flags: Extra flags for format config * @flags: Extra flags for format config
* @index: rectangle index in multirect
*/ */
void (*setup_format)(struct dpu_hw_pipe *ctx, void (*setup_format)(struct dpu_sw_pipe *pipe,
const struct dpu_format *fmt, u32 flags, const struct dpu_format *fmt, u32 flags);
enum dpu_sspp_multirect_index index);
/** /**
* setup_rects - setup pipe ROI rectangles * setup_rects - setup pipe ROI rectangles
* @ctx: Pointer to pipe context * @pipe: Pointer to software pipe context
* @cfg: Pointer to pipe config structure * @cfg: Pointer to pipe config structure
* @index: rectangle index in multirect
*/ */
void (*setup_rects)(struct dpu_hw_pipe *ctx, void (*setup_rects)(struct dpu_sw_pipe *pipe,
struct dpu_hw_pipe_cfg *cfg, struct dpu_sw_pipe_cfg *cfg);
enum dpu_sspp_multirect_index index);
/** /**
* setup_pe - setup pipe pixel extension * setup_pe - setup pipe pixel extension
* @ctx: Pointer to pipe context * @ctx: Pointer to pipe context
* @pe_ext: Pointer to pixel ext settings * @pe_ext: Pointer to pixel ext settings
*/ */
void (*setup_pe)(struct dpu_hw_pipe *ctx, void (*setup_pe)(struct dpu_hw_sspp *ctx,
struct dpu_hw_pixel_ext *pe_ext); struct dpu_hw_pixel_ext *pe_ext);
/** /**
* setup_sourceaddress - setup pipe source addresses * setup_sourceaddress - setup pipe source addresses
* @ctx: Pointer to pipe context * @pipe: Pointer to software pipe context
* @cfg: Pointer to pipe config structure * @layout: format layout information for programming buffer to hardware
* @index: rectangle index in multirect
*/ */
void (*setup_sourceaddress)(struct dpu_hw_pipe *ctx, void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
struct dpu_hw_pipe_cfg *cfg, struct dpu_hw_fmt_layout *layout);
enum dpu_sspp_multirect_index index);
/** /**
* setup_csc - setup color space coversion * setup_csc - setup color space coversion
* @ctx: Pointer to pipe context * @ctx: Pointer to pipe context
* @data: Pointer to config structure * @data: Pointer to config structure
*/ */
void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data); void (*setup_csc)(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data);
/** /**
* setup_solidfill - enable/disable colorfill * setup_solidfill - enable/disable colorfill
* @ctx: Pointer to pipe context * @pipe: Pointer to software pipe context
* @const_color: Fill color value * @const_color: Fill color value
* @flags: Pipe flags * @flags: Pipe flags
* @index: rectangle index in multirect
*/ */
void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color, void (*setup_solidfill)(struct dpu_sw_pipe *pipe, u32 color);
enum dpu_sspp_multirect_index index);
/** /**
* setup_multirect - setup multirect configuration * setup_multirect - setup multirect configuration
* @ctx: Pointer to pipe context * @pipe: Pointer to software pipe context
* @index: rectangle index in multirect
* @mode: parallel fetch / time multiplex multirect mode
*/ */
void (*setup_multirect)(struct dpu_hw_pipe *ctx, void (*setup_multirect)(struct dpu_sw_pipe *pipe);
enum dpu_sspp_multirect_index index,
enum dpu_sspp_multirect_mode mode);
/** /**
* setup_sharpening - setup sharpening * setup_sharpening - setup sharpening
* @ctx: Pointer to pipe context * @ctx: Pointer to pipe context
* @cfg: Pointer to config structure * @cfg: Pointer to config structure
*/ */
void (*setup_sharpening)(struct dpu_hw_pipe *ctx, void (*setup_sharpening)(struct dpu_hw_sspp *ctx,
struct dpu_hw_sharp_cfg *cfg); struct dpu_hw_sharp_cfg *cfg);
/** /**
...@@ -289,7 +283,7 @@ struct dpu_hw_sspp_ops { ...@@ -289,7 +283,7 @@ struct dpu_hw_sspp_ops {
* @safe_lut: LUT for generate safe level based on fill level * @safe_lut: LUT for generate safe level based on fill level
* *
*/ */
void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx, void (*setup_danger_safe_lut)(struct dpu_hw_sspp *ctx,
u32 danger_lut, u32 danger_lut,
u32 safe_lut); u32 safe_lut);
...@@ -299,7 +293,7 @@ struct dpu_hw_sspp_ops { ...@@ -299,7 +293,7 @@ struct dpu_hw_sspp_ops {
* @creq_lut: LUT for generate creq level based on fill level * @creq_lut: LUT for generate creq level based on fill level
* *
*/ */
void (*setup_creq_lut)(struct dpu_hw_pipe *ctx, void (*setup_creq_lut)(struct dpu_hw_sspp *ctx,
u64 creq_lut); u64 creq_lut);
/** /**
...@@ -308,7 +302,7 @@ struct dpu_hw_sspp_ops { ...@@ -308,7 +302,7 @@ struct dpu_hw_sspp_ops {
* @cfg: Pointer to pipe QoS configuration * @cfg: Pointer to pipe QoS configuration
* *
*/ */
void (*setup_qos_ctrl)(struct dpu_hw_pipe *ctx, void (*setup_qos_ctrl)(struct dpu_hw_sspp *ctx,
struct dpu_hw_pipe_qos_cfg *cfg); struct dpu_hw_pipe_qos_cfg *cfg);
/** /**
...@@ -316,38 +310,35 @@ struct dpu_hw_sspp_ops { ...@@ -316,38 +310,35 @@ struct dpu_hw_sspp_ops {
* @ctx: Pointer to pipe context * @ctx: Pointer to pipe context
* @cfg: Pointer to histogram configuration * @cfg: Pointer to histogram configuration
*/ */
void (*setup_histogram)(struct dpu_hw_pipe *ctx, void (*setup_histogram)(struct dpu_hw_sspp *ctx,
void *cfg); void *cfg);
/** /**
* setup_scaler - setup scaler * setup_scaler - setup scaler
* @ctx: Pointer to pipe context * @scaler3_cfg: Pointer to scaler configuration
* @pipe_cfg: Pointer to pipe configuration * @format: pixel format parameters
* @scaler_cfg: Pointer to scaler configuration
*/ */
void (*setup_scaler)(struct dpu_hw_pipe *ctx, void (*setup_scaler)(struct dpu_hw_sspp *ctx,
struct dpu_hw_pipe_cfg *pipe_cfg, struct dpu_hw_scaler3_cfg *scaler3_cfg,
void *scaler_cfg); const struct dpu_format *format);
/** /**
* get_scaler_ver - get scaler h/w version * get_scaler_ver - get scaler h/w version
* @ctx: Pointer to pipe context * @ctx: Pointer to pipe context
*/ */
u32 (*get_scaler_ver)(struct dpu_hw_pipe *ctx); u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx);
/** /**
* setup_cdp - setup client driven prefetch * setup_cdp - setup client driven prefetch
* @ctx: Pointer to pipe context * @pipe: Pointer to software pipe context
* @cfg: Pointer to cdp configuration * @cfg: Pointer to cdp configuration
* @index: rectangle index in multirect
*/ */
void (*setup_cdp)(struct dpu_hw_pipe *ctx, void (*setup_cdp)(struct dpu_sw_pipe *pipe,
struct dpu_hw_cdp_cfg *cfg, struct dpu_hw_cdp_cfg *cfg);
enum dpu_sspp_multirect_index index);
}; };
/** /**
* struct dpu_hw_pipe - pipe description * struct dpu_hw_sspp - pipe description
* @base: hardware block base structure * @base: hardware block base structure
* @hw: block hardware details * @hw: block hardware details
* @catalog: back pointer to catalog * @catalog: back pointer to catalog
...@@ -356,7 +347,7 @@ struct dpu_hw_sspp_ops { ...@@ -356,7 +347,7 @@ struct dpu_hw_sspp_ops {
* @cap: pointer to layer_cfg * @cap: pointer to layer_cfg
* @ops: pointer to operations possible for this pipe * @ops: pointer to operations possible for this pipe
*/ */
struct dpu_hw_pipe { struct dpu_hw_sspp {
struct dpu_hw_blk base; struct dpu_hw_blk base;
struct dpu_hw_blk_reg_map hw; struct dpu_hw_blk_reg_map hw;
const struct dpu_mdss_cfg *catalog; const struct dpu_mdss_cfg *catalog;
...@@ -378,7 +369,7 @@ struct dpu_kms; ...@@ -378,7 +369,7 @@ struct dpu_kms;
* @addr: Mapped register io address of MDP * @addr: Mapped register io address of MDP
* @catalog : Pointer to mdss catalog data * @catalog : Pointer to mdss catalog data
*/ */
struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
void __iomem *addr, const struct dpu_mdss_cfg *catalog); void __iomem *addr, const struct dpu_mdss_cfg *catalog);
/** /**
...@@ -386,10 +377,10 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, ...@@ -386,10 +377,10 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
* should be called during Hw pipe cleanup. * should be called during Hw pipe cleanup.
* @ctx: Pointer to SSPP driver context returned by dpu_hw_sspp_init * @ctx: Pointer to SSPP driver context returned by dpu_hw_sspp_init
*/ */
void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx); void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root); int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry); struct dentry *entry);
#endif /*_DPU_HW_SSPP_H */ #endif /*_DPU_HW_SSPP_H */
...@@ -250,6 +250,24 @@ void dpu_debugfs_create_regset32(const char *name, umode_t mode, ...@@ -250,6 +250,24 @@ void dpu_debugfs_create_regset32(const char *name, umode_t mode,
debugfs_create_file(name, mode, parent, regset, &dpu_regset32_fops); debugfs_create_file(name, mode, parent, regset, &dpu_regset32_fops);
} }
static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root)
{
struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
int i;
if (IS_ERR(entry))
return;
for (i = SSPP_NONE; i < SSPP_MAX; i++) {
struct dpu_hw_sspp *hw = dpu_rm_get_sspp(&dpu_kms->rm, i);
if (!hw)
continue;
_dpu_hw_sspp_init_debugfs(hw, dpu_kms, entry);
}
}
static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
{ {
struct dpu_kms *dpu_kms = to_dpu_kms(kms); struct dpu_kms *dpu_kms = to_dpu_kms(kms);
...@@ -411,26 +429,6 @@ static void dpu_kms_disable_commit(struct msm_kms *kms) ...@@ -411,26 +429,6 @@ static void dpu_kms_disable_commit(struct msm_kms *kms)
pm_runtime_put_sync(&dpu_kms->pdev->dev); pm_runtime_put_sync(&dpu_kms->pdev->dev);
} }
static void dpu_kms_prepare_commit(struct msm_kms *kms,
struct drm_atomic_state *state)
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
struct drm_encoder *encoder;
int i;
if (!kms)
return;
/* Call prepare_commit for all affected encoders */
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
drm_for_each_encoder_mask(encoder, crtc->dev,
crtc_state->encoder_mask) {
dpu_encoder_prepare_commit(encoder);
}
}
}
static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask) static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
{ {
struct dpu_kms *dpu_kms = to_dpu_kms(kms); struct dpu_kms *dpu_kms = to_dpu_kms(kms);
...@@ -939,7 +937,6 @@ static const struct msm_kms_funcs kms_funcs = { ...@@ -939,7 +937,6 @@ static const struct msm_kms_funcs kms_funcs = {
.irq = dpu_core_irq, .irq = dpu_core_irq,
.enable_commit = dpu_kms_enable_commit, .enable_commit = dpu_kms_enable_commit,
.disable_commit = dpu_kms_disable_commit, .disable_commit = dpu_kms_disable_commit,
.prepare_commit = dpu_kms_prepare_commit,
.flush_commit = dpu_kms_flush_commit, .flush_commit = dpu_kms_flush_commit,
.wait_flush = dpu_kms_wait_flush, .wait_flush = dpu_kms_wait_flush,
.complete_commit = dpu_kms_complete_commit, .complete_commit = dpu_kms_complete_commit,
......
This diff is collapsed.
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
* struct dpu_plane_state: Define dpu extension of drm plane state object * struct dpu_plane_state: Define dpu extension of drm plane state object
* @base: base drm plane state object * @base: base drm plane state object
* @aspace: pointer to address space for input/output buffers * @aspace: pointer to address space for input/output buffers
* @pipe: software pipe description
* @r_pipe: software pipe description of the second pipe
* @pipe_cfg: software pipe configuration
* @r_pipe_cfg: software pipe configuration for the second pipe
* @stage: assigned by crtc blender * @stage: assigned by crtc blender
* @needs_qos_remap: qos remap settings need to be updated * @needs_qos_remap: qos remap settings need to be updated
* @multirect_index: index of the rectangle of SSPP * @multirect_index: index of the rectangle of SSPP
...@@ -31,10 +35,12 @@ ...@@ -31,10 +35,12 @@
struct dpu_plane_state { struct dpu_plane_state {
struct drm_plane_state base; struct drm_plane_state base;
struct msm_gem_address_space *aspace; struct msm_gem_address_space *aspace;
struct dpu_sw_pipe pipe;
struct dpu_sw_pipe r_pipe;
struct dpu_sw_pipe_cfg pipe_cfg;
struct dpu_sw_pipe_cfg r_pipe_cfg;
enum dpu_stage stage; enum dpu_stage stage;
bool needs_qos_remap; bool needs_qos_remap;
uint32_t multirect_index;
uint32_t multirect_mode;
bool pending; bool pending;
u64 plane_fetch_bw; u64 plane_fetch_bw;
...@@ -44,26 +50,9 @@ struct dpu_plane_state { ...@@ -44,26 +50,9 @@ struct dpu_plane_state {
unsigned int rotation; unsigned int rotation;
}; };
/**
* struct dpu_multirect_plane_states: Defines multirect pair of drm plane states
* @r0: drm plane configured on rect 0
* @r1: drm plane configured on rect 1
*/
struct dpu_multirect_plane_states {
const struct drm_plane_state *r0;
const struct drm_plane_state *r1;
};
#define to_dpu_plane_state(x) \ #define to_dpu_plane_state(x) \
container_of(x, struct dpu_plane_state, base) container_of(x, struct dpu_plane_state, base)
/**
* dpu_plane_pipe - return sspp identifier for the given plane
* @plane: Pointer to DRM plane object
* Returns: sspp identifier of the given plane
*/
enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
/** /**
* dpu_plane_flush - final plane operations before commit flush * dpu_plane_flush - final plane operations before commit flush
* @plane: Pointer to drm plane structure * @plane: Pointer to drm plane structure
...@@ -88,19 +77,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, ...@@ -88,19 +77,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
uint32_t pipe, enum drm_plane_type type, uint32_t pipe, enum drm_plane_type type,
unsigned long possible_crtcs); unsigned long possible_crtcs);
/**
* dpu_plane_validate_multirecti_v2 - validate the multirect planes
* against hw limitations
* @plane: drm plate states of the multirect pair
*/
int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane);
/**
* dpu_plane_clear_multirect - clear multirect bits for the given pipe
* @drm_state: Pointer to DRM plane state
*/
void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
/** /**
* dpu_plane_color_fill - enables color fill on plane * dpu_plane_color_fill - enables color fill on plane
* @plane: Pointer to DRM plane object * @plane: Pointer to DRM plane object
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "dpu_hw_lm.h" #include "dpu_hw_lm.h"
#include "dpu_hw_ctl.h" #include "dpu_hw_ctl.h"
#include "dpu_hw_pingpong.h" #include "dpu_hw_pingpong.h"
#include "dpu_hw_sspp.h"
#include "dpu_hw_intf.h" #include "dpu_hw_intf.h"
#include "dpu_hw_wb.h" #include "dpu_hw_wb.h"
#include "dpu_hw_dspp.h" #include "dpu_hw_dspp.h"
...@@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm) ...@@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++) for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
dpu_hw_wb_destroy(rm->hw_wb[i]); dpu_hw_wb_destroy(rm->hw_wb[i]);
for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
dpu_hw_sspp_destroy(rm->hw_sspp[i]);
return 0; return 0;
} }
...@@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm, ...@@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm,
rm->dsc_blks[dsc->id - DSC_0] = &hw->base; rm->dsc_blks[dsc->id - DSC_0] = &hw->base;
} }
for (i = 0; i < cat->sspp_count; i++) {
struct dpu_hw_sspp *hw;
const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
if (sspp->id < SSPP_NONE || sspp->id >= SSPP_MAX) {
DPU_ERROR("skip intf %d with invalid id\n", sspp->id);
continue;
}
hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed sspp object creation: err %d\n", rc);
goto fail;
}
rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
}
return 0; return 0;
fail: fail:
......
...@@ -21,6 +21,7 @@ struct dpu_global_state; ...@@ -21,6 +21,7 @@ struct dpu_global_state;
* @hw_intf: array of intf hardware resources * @hw_intf: array of intf hardware resources
* @hw_wb: array of wb hardware resources * @hw_wb: array of wb hardware resources
* @dspp_blks: array of dspp hardware resources * @dspp_blks: array of dspp hardware resources
* @hw_sspp: array of sspp hardware resources
*/ */
struct dpu_rm { struct dpu_rm {
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
...@@ -31,6 +32,7 @@ struct dpu_rm { ...@@ -31,6 +32,7 @@ struct dpu_rm {
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0]; struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0]; struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
}; };
/** /**
...@@ -108,5 +110,15 @@ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_wb wb_ ...@@ -108,5 +110,15 @@ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_wb wb_
return rm->hw_wb[wb_idx - WB_0]; return rm->hw_wb[wb_idx - WB_0];
} }
/**
* dpu_rm_get_sspp - Return a struct dpu_hw_sspp instance given it's index.
* @rm: DPU Resource Manager handle
* @sspp_idx: SSPP index
*/
static inline struct dpu_hw_sspp *dpu_rm_get_sspp(struct dpu_rm *rm, enum dpu_sspp sspp_idx)
{
return rm->hw_sspp[sspp_idx - SSPP_NONE];
}
#endif /* __DPU_RM_H__ */ #endif /* __DPU_RM_H__ */
...@@ -633,9 +633,9 @@ TRACE_EVENT(dpu_enc_phys_vid_irq_ctrl, ...@@ -633,9 +633,9 @@ TRACE_EVENT(dpu_enc_phys_vid_irq_ctrl,
TRACE_EVENT(dpu_crtc_setup_mixer, TRACE_EVENT(dpu_crtc_setup_mixer,
TP_PROTO(uint32_t crtc_id, uint32_t plane_id, TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
struct drm_plane_state *state, struct dpu_plane_state *pstate, struct drm_plane_state *state, struct dpu_plane_state *pstate,
uint32_t stage_idx, enum dpu_sspp sspp, uint32_t pixel_format, uint32_t stage_idx, uint32_t pixel_format,
uint64_t modifier), uint64_t modifier),
TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx, sspp, TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
pixel_format, modifier), pixel_format, modifier),
TP_STRUCT__entry( TP_STRUCT__entry(
__field( uint32_t, crtc_id ) __field( uint32_t, crtc_id )
...@@ -659,9 +659,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer, ...@@ -659,9 +659,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
__entry->dst_rect = drm_plane_state_dest(state); __entry->dst_rect = drm_plane_state_dest(state);
__entry->stage_idx = stage_idx; __entry->stage_idx = stage_idx;
__entry->stage = pstate->stage; __entry->stage = pstate->stage;
__entry->sspp = sspp; __entry->sspp = pstate->pipe.sspp->idx;
__entry->multirect_idx = pstate->multirect_index; __entry->multirect_idx = pstate->pipe.multirect_index;
__entry->multirect_mode = pstate->multirect_mode; __entry->multirect_mode = pstate->pipe.multirect_mode;
__entry->pixel_format = pixel_format; __entry->pixel_format = pixel_format;
__entry->modifier = modifier; __entry->modifier = modifier;
), ),
...@@ -762,18 +762,17 @@ TRACE_EVENT(dpu_crtc_disable_frame_pending, ...@@ -762,18 +762,17 @@ TRACE_EVENT(dpu_crtc_disable_frame_pending,
); );
TRACE_EVENT(dpu_plane_set_scanout, TRACE_EVENT(dpu_plane_set_scanout,
TP_PROTO(enum dpu_sspp index, struct dpu_hw_fmt_layout *layout, TP_PROTO(struct dpu_sw_pipe *pipe, struct dpu_hw_fmt_layout *layout),
enum dpu_sspp_multirect_index multirect_index), TP_ARGS(pipe, layout),
TP_ARGS(index, layout, multirect_index),
TP_STRUCT__entry( TP_STRUCT__entry(
__field( enum dpu_sspp, index ) __field( enum dpu_sspp, index )
__field_struct( struct dpu_hw_fmt_layout, layout ) __field_struct( struct dpu_hw_fmt_layout, layout )
__field( enum dpu_sspp_multirect_index, multirect_index) __field( enum dpu_sspp_multirect_index, multirect_index)
), ),
TP_fast_assign( TP_fast_assign(
__entry->index = index; __entry->index = pipe->sspp->idx;
__entry->layout = *layout; __entry->layout = *layout;
__entry->multirect_index = multirect_index; __entry->multirect_index = pipe->multirect_index;
), ),
TP_printk("index:%d layout:{%ux%u @ [%u/%u, %u/%u, %u/%u, %u/%u]} " TP_printk("index:%d layout:{%ux%u @ [%u/%u, %u/%u, %u/%u, %u/%u]} "
"multirect_index:%d", __entry->index, __entry->layout.width, "multirect_index:%d", __entry->index, __entry->layout.width,
......
...@@ -179,6 +179,24 @@ static unsigned get_crtc_mask(struct drm_atomic_state *state) ...@@ -179,6 +179,24 @@ static unsigned get_crtc_mask(struct drm_atomic_state *state)
return mask; return mask;
} }
int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
{
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_crtc *crtc;
int i;
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
if ((old_crtc_state->ctm && !new_crtc_state->ctm) ||
(!old_crtc_state->ctm && new_crtc_state->ctm)) {
new_crtc_state->mode_changed = true;
state->allow_modeset = true;
}
}
return drm_atomic_helper_check(dev, state);
}
void msm_atomic_commit_tail(struct drm_atomic_state *state) void msm_atomic_commit_tail(struct drm_atomic_state *state)
{ {
struct drm_device *dev = state->dev; struct drm_device *dev = state->dev;
......
...@@ -58,7 +58,7 @@ static void msm_deinit_vram(struct drm_device *ddev); ...@@ -58,7 +58,7 @@ static void msm_deinit_vram(struct drm_device *ddev);
static const struct drm_mode_config_funcs mode_config_funcs = { static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = msm_framebuffer_create, .fb_create = msm_framebuffer_create,
.atomic_check = drm_atomic_helper_check, .atomic_check = msm_atomic_check,
.atomic_commit = drm_atomic_helper_commit, .atomic_commit = drm_atomic_helper_commit,
}; };
......
...@@ -258,6 +258,7 @@ int msm_atomic_init_pending_timer(struct msm_pending_timer *timer, ...@@ -258,6 +258,7 @@ int msm_atomic_init_pending_timer(struct msm_pending_timer *timer,
struct msm_kms *kms, int crtc_idx); struct msm_kms *kms, int crtc_idx);
void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer); void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer);
void msm_atomic_commit_tail(struct drm_atomic_state *state); void msm_atomic_commit_tail(struct drm_atomic_state *state);
int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state);
struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev); struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev);
void msm_atomic_state_clear(struct drm_atomic_state *state); void msm_atomic_state_clear(struct drm_atomic_state *state);
void msm_atomic_state_free(struct drm_atomic_state *state); void msm_atomic_state_free(struct drm_atomic_state *state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment