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)
static struct msm_display_topology dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc,
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};
int i, intf_count = 0;
......@@ -563,8 +564,7 @@ static struct msm_display_topology dpu_encoder_get_topology(
* 1 LM, 1 INTF
* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
*
* Adding color blocks only to primary interface if available in
* sufficient number
* Add dspps to the reservation requirements if ctm is requested
*/
if (intf_count == 2)
topology.num_lm = 2;
......@@ -573,11 +573,8 @@ static struct msm_display_topology dpu_encoder_get_topology(
else
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) {
if (dpu_kms->catalog->dspp &&
(dpu_kms->catalog->dspp_count >= topology.num_lm))
topology.num_dspp = topology.num_lm;
}
if (crtc_state->ctm)
topology.num_dspp = topology.num_lm;
topology.num_intf = intf_count;
......@@ -638,25 +635,22 @@ static int dpu_encoder_virt_atomic_check(
if (ret) {
DPU_ERROR_ENC(dpu_enc,
"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.
*/
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
dpu_rm_release(global_state, drm_enc);
/*
* 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 (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
drm_enc, crtc_state, topology);
}
if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
drm_enc, crtc_state, topology);
}
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)
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
static int _dpu_encoder_status_show(struct seq_file *s, void *data)
{
......
......@@ -146,13 +146,6 @@ struct drm_encoder *dpu_encoder_init(
int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
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
* and command mode encoders.
......
......@@ -40,6 +40,8 @@
#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)
{
return (phys_enc->split_role != ENC_ROLE_SLAVE);
......@@ -565,6 +567,8 @@ static void dpu_encoder_phys_cmd_prepare_for_kickoff(
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",
phys_enc->hw_pp->idx - PINGPONG_0,
atomic_read(&phys_enc->pending_kickoff_cnt));
......@@ -586,8 +590,7 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
return false;
}
static void dpu_encoder_phys_cmd_prepare_commit(
struct dpu_encoder_phys *phys_enc)
static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc)
{
struct dpu_encoder_phys_cmd *cmd_enc =
to_dpu_encoder_phys_cmd(phys_enc);
......@@ -732,7 +735,6 @@ static void dpu_encoder_phys_cmd_trigger_start(
static void dpu_encoder_phys_cmd_init_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->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set;
ops->enable = dpu_encoder_phys_cmd_enable;
......
......@@ -536,6 +536,16 @@ static const struct dpu_format dpu_format_map_ubwc[] = {
true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
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,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C2_R_Cr,
......@@ -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_XRGB8888, COLOR_FMT_RGBA8888_UBWC},
{DRM_FORMAT_ABGR2101010, COLOR_FMT_RGBA1010102_UBWC},
{DRM_FORMAT_ARGB2101010, COLOR_FMT_RGBA1010102_UBWC},
{DRM_FORMAT_XRGB2101010, COLOR_FMT_RGBA1010102_UBWC},
{DRM_FORMAT_XBGR2101010, COLOR_FMT_RGBA1010102_UBWC},
{DRM_FORMAT_BGR565, COLOR_FMT_RGB565_UBWC},
......@@ -918,8 +929,7 @@ int dpu_format_populate_layout(
struct drm_framebuffer *fb,
struct dpu_hw_fmt_layout *layout)
{
uint32_t plane_addr[DPU_MAX_PLANES];
int i, ret;
int ret;
if (!fb || !layout) {
DRM_ERROR("invalid arguments\n");
......@@ -940,9 +950,6 @@ int dpu_format_populate_layout(
if (ret)
return ret;
for (i = 0; i < DPU_MAX_PLANES; ++i)
plane_addr[i] = layout->plane_addr[i];
/* Populate the addresses given the fb */
if (DPU_FORMAT_IS_UBWC(layout->format) ||
DPU_FORMAT_IS_TILE(layout->format))
......@@ -950,10 +957,6 @@ int dpu_format_populate_layout(
else
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;
}
......
......@@ -19,8 +19,9 @@
*/
#define MAX_BLOCKS 12
#define DPU_HW_VER(MAJOR, MINOR, STEP) (((MAJOR & 0xF) << 28) |\
((MINOR & 0xFFF) << 16) |\
#define DPU_HW_VER(MAJOR, MINOR, STEP) \
((((unsigned int)MAJOR & 0xF) << 28) | \
((MINOR & 0xFFF) << 16) | \
(STEP & 0xFFFF))
#define DPU_HW_MAJOR(rev) ((rev) >> 28)
......@@ -169,10 +170,12 @@ enum {
* DSPP sub-blocks
* @DPU_DSPP_PCC Panel color correction block
* @DPU_DSPP_GC Gamma correction block
* @DPU_DSPP_IGC Inverse gamma correction block
*/
enum {
DPU_DSPP_PCC = 0x1,
DPU_DSPP_GC,
DPU_DSPP_IGC,
DPU_DSPP_MAX
};
......@@ -200,6 +203,7 @@ enum {
* @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs)
* @DPU_CTL_VM_CFG: CTL config to support multiple VMs
* @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
*/
enum {
......@@ -208,6 +212,7 @@ enum {
DPU_CTL_FETCH_ACTIVE,
DPU_CTL_VM_CFG,
DPU_CTL_HAS_LAYER_EXT4,
DPU_CTL_DSPP_SUB_BLOCK_FLUSH,
DPU_CTL_MAX
};
......@@ -395,7 +400,6 @@ struct dpu_rotation_cfg {
* @max_mixer_blendstages max layer mixer blend stages or
* supported z order
* @qseed_type qseed2 or qseed3 support.
* @smart_dma_rev Supported version of SmartDMA feature.
* @ubwc_version UBWC feature version (0x0 for not supported)
* @has_src_split source split feature status
* @has_dim_layer dim layer feature status
......@@ -410,7 +414,6 @@ struct dpu_caps {
u32 max_mixer_width;
u32 max_mixer_blendstages;
u32 qseed_type;
u32 smart_dma_rev;
u32 ubwc_version;
bool has_src_split;
bool has_dim_layer;
......
......@@ -26,15 +26,16 @@
#define CTL_SW_RESET 0x030
#define CTL_LAYER_EXTN_OFFSET 0x40
#define CTL_MERGE_3D_ACTIVE 0x0E4
#define CTL_DSC_ACTIVE 0x0E8
#define CTL_WB_ACTIVE 0x0EC
#define CTL_INTF_ACTIVE 0x0F4
#define CTL_FETCH_PIPE_ACTIVE 0x0FC
#define CTL_MERGE_3D_FLUSH 0x100
#define CTL_DSC_ACTIVE 0x0E8
#define CTL_DSC_FLUSH 0x104
#define CTL_WB_FLUSH 0x108
#define CTL_INTF_FLUSH 0x110
#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_FLUSH_MASK_CTL BIT(17)
......@@ -44,6 +45,7 @@
#define DSC_IDX 22
#define INTF_IDX 31
#define WB_IDX 16
#define DSPP_IDX 29 /* From DPU hw rev 7.x.x */
#define CTL_INVALID_BIT 0xffff
#define CTL_DEFAULT_GROUP_ID 0xf
......@@ -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,
dpu_hw_ctl_get_flush_register(ctx));
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,
......@@ -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)
{
int dspp;
if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX))
DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH,
ctx->pending_merge_3d_flush_mask);
......@@ -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,
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);
}
......@@ -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,
enum dpu_dspp dspp)
enum dpu_dspp dspp, u32 dspp_sub_blk)
{
switch (dspp) {
case DSPP_0:
......@@ -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)
{
struct dpu_hw_blk_reg_map *c = &ctx->hw;
......@@ -630,7 +667,11 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
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_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))
ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
};
......
......@@ -152,9 +152,11 @@ struct dpu_hw_ctl_ops {
* No effect on hardware
* @ctx : ctl path ctx pointer
* @blk : DSPP block index
* @dspp_sub_blk : DSPP sub-block index
*/
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
* @ctx : ctl path ctx pointer
......@@ -242,6 +244,7 @@ struct dpu_hw_ctl {
u32 pending_intf_flush_mask;
u32 pending_wb_flush_mask;
u32 pending_merge_3d_flush_mask;
u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
/* ops */
struct dpu_hw_ctl_ops ops;
......
This diff is collapsed.
......@@ -10,7 +10,7 @@
#include "dpu_hw_util.h"
#include "dpu_formats.h"
struct dpu_hw_pipe;
struct dpu_hw_sspp;
/**
* Flags
......@@ -153,20 +153,14 @@ struct dpu_hw_pixel_ext {
};
/**
* struct dpu_hw_pipe_cfg : Pipe description
* @layout: format layout information for programming buffer to hardware
* struct dpu_sw_pipe_cfg : software pipe configuration
* @src_rect: src ROI, caller takes into account the different operations
* such as decimation, flip etc to program this field
* @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_hw_fmt_layout layout;
struct dpu_sw_pipe_cfg {
struct drm_rect src_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 {
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
* Caller must call the init function to get the pipe context for each pipe
......@@ -209,77 +215,65 @@ struct dpu_hw_pipe_ts_cfg {
struct dpu_hw_sspp_ops {
/**
* 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
* @flags: Extra flags for format config
* @index: rectangle index in multirect
*/
void (*setup_format)(struct dpu_hw_pipe *ctx,
const struct dpu_format *fmt, u32 flags,
enum dpu_sspp_multirect_index index);
void (*setup_format)(struct dpu_sw_pipe *pipe,
const struct dpu_format *fmt, u32 flags);
/**
* setup_rects - setup pipe ROI rectangles
* @ctx: Pointer to pipe context
* @pipe: Pointer to software pipe context
* @cfg: Pointer to pipe config structure
* @index: rectangle index in multirect
*/
void (*setup_rects)(struct dpu_hw_pipe *ctx,
struct dpu_hw_pipe_cfg *cfg,
enum dpu_sspp_multirect_index index);
void (*setup_rects)(struct dpu_sw_pipe *pipe,
struct dpu_sw_pipe_cfg *cfg);
/**
* setup_pe - setup pipe pixel extension
* @ctx: Pointer to pipe context
* @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);
/**
* setup_sourceaddress - setup pipe source addresses
* @ctx: Pointer to pipe context
* @cfg: Pointer to pipe config structure
* @index: rectangle index in multirect
* @pipe: Pointer to software pipe context
* @layout: format layout information for programming buffer to hardware
*/
void (*setup_sourceaddress)(struct dpu_hw_pipe *ctx,
struct dpu_hw_pipe_cfg *cfg,
enum dpu_sspp_multirect_index index);
void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
struct dpu_hw_fmt_layout *layout);
/**
* setup_csc - setup color space coversion
* @ctx: Pointer to pipe context
* @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
* @ctx: Pointer to pipe context
* @pipe: Pointer to software pipe context
* @const_color: Fill color value
* @flags: Pipe flags
* @index: rectangle index in multirect
*/
void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color,
enum dpu_sspp_multirect_index index);
void (*setup_solidfill)(struct dpu_sw_pipe *pipe, u32 color);
/**
* setup_multirect - setup multirect configuration
* @ctx: Pointer to pipe context
* @index: rectangle index in multirect
* @mode: parallel fetch / time multiplex multirect mode
* @pipe: Pointer to software pipe context
*/
void (*setup_multirect)(struct dpu_hw_pipe *ctx,
enum dpu_sspp_multirect_index index,
enum dpu_sspp_multirect_mode mode);
void (*setup_multirect)(struct dpu_sw_pipe *pipe);
/**
* setup_sharpening - setup sharpening
* @ctx: Pointer to pipe context
* @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);
/**
......@@ -289,7 +283,7 @@ struct dpu_hw_sspp_ops {
* @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 safe_lut);
......@@ -299,7 +293,7 @@ struct dpu_hw_sspp_ops {
* @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);
/**
......@@ -308,7 +302,7 @@ struct dpu_hw_sspp_ops {
* @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);
/**
......@@ -316,38 +310,35 @@ struct dpu_hw_sspp_ops {
* @ctx: Pointer to pipe context
* @cfg: Pointer to histogram configuration
*/
void (*setup_histogram)(struct dpu_hw_pipe *ctx,
void (*setup_histogram)(struct dpu_hw_sspp *ctx,
void *cfg);
/**
* setup_scaler - setup scaler
* @ctx: Pointer to pipe context
* @pipe_cfg: Pointer to pipe configuration
* @scaler_cfg: Pointer to scaler configuration
* @scaler3_cfg: Pointer to scaler configuration
* @format: pixel format parameters
*/
void (*setup_scaler)(struct dpu_hw_pipe *ctx,
struct dpu_hw_pipe_cfg *pipe_cfg,
void *scaler_cfg);
void (*setup_scaler)(struct dpu_hw_sspp *ctx,
struct dpu_hw_scaler3_cfg *scaler3_cfg,
const struct dpu_format *format);
/**
* get_scaler_ver - get scaler h/w version
* @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
* @ctx: Pointer to pipe context
* @pipe: Pointer to software pipe context
* @cfg: Pointer to cdp configuration
* @index: rectangle index in multirect
*/
void (*setup_cdp)(struct dpu_hw_pipe *ctx,
struct dpu_hw_cdp_cfg *cfg,
enum dpu_sspp_multirect_index index);
void (*setup_cdp)(struct dpu_sw_pipe *pipe,
struct dpu_hw_cdp_cfg *cfg);
};
/**
* struct dpu_hw_pipe - pipe description
* struct dpu_hw_sspp - pipe description
* @base: hardware block base structure
* @hw: block hardware details
* @catalog: back pointer to catalog
......@@ -356,7 +347,7 @@ struct dpu_hw_sspp_ops {
* @cap: pointer to layer_cfg
* @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_reg_map hw;
const struct dpu_mdss_cfg *catalog;
......@@ -378,7 +369,7 @@ struct dpu_kms;
* @addr: Mapped register io address of MDP
* @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);
/**
......@@ -386,10 +377,10 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
* should be called during Hw pipe cleanup.
* @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_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry);
int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
struct dentry *entry);
#endif /*_DPU_HW_SSPP_H */
......@@ -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);
}
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)
{
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
......@@ -411,26 +429,6 @@ static void dpu_kms_disable_commit(struct msm_kms *kms)
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)
{
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
......@@ -939,7 +937,6 @@ static const struct msm_kms_funcs kms_funcs = {
.irq = dpu_core_irq,
.enable_commit = dpu_kms_enable_commit,
.disable_commit = dpu_kms_disable_commit,
.prepare_commit = dpu_kms_prepare_commit,
.flush_commit = dpu_kms_flush_commit,
.wait_flush = dpu_kms_wait_flush,
.complete_commit = dpu_kms_complete_commit,
......
This diff is collapsed.
......@@ -18,6 +18,10 @@
* struct dpu_plane_state: Define dpu extension of drm plane state object
* @base: base drm plane state object
* @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
* @needs_qos_remap: qos remap settings need to be updated
* @multirect_index: index of the rectangle of SSPP
......@@ -31,10 +35,12 @@
struct dpu_plane_state {
struct drm_plane_state base;
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;
bool needs_qos_remap;
uint32_t multirect_index;
uint32_t multirect_mode;
bool pending;
u64 plane_fetch_bw;
......@@ -44,26 +50,9 @@ struct dpu_plane_state {
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) \
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
* @plane: Pointer to drm plane structure
......@@ -88,19 +77,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
uint32_t pipe, enum drm_plane_type type,
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
* @plane: Pointer to DRM plane object
......
......@@ -8,6 +8,7 @@
#include "dpu_hw_lm.h"
#include "dpu_hw_ctl.h"
#include "dpu_hw_pingpong.h"
#include "dpu_hw_sspp.h"
#include "dpu_hw_intf.h"
#include "dpu_hw_wb.h"
#include "dpu_hw_dspp.h"
......@@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
for (i = 0; i < ARRAY_SIZE(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;
}
......@@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm,
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;
fail:
......
......@@ -21,6 +21,7 @@ struct dpu_global_state;
* @hw_intf: array of intf hardware resources
* @hw_wb: array of wb hardware resources
* @dspp_blks: array of dspp hardware resources
* @hw_sspp: array of sspp hardware resources
*/
struct dpu_rm {
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
......@@ -31,6 +32,7 @@ struct dpu_rm {
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 *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_
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__ */
......@@ -633,9 +633,9 @@ TRACE_EVENT(dpu_enc_phys_vid_irq_ctrl,
TRACE_EVENT(dpu_crtc_setup_mixer,
TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
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),
TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx, sspp,
TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
pixel_format, modifier),
TP_STRUCT__entry(
__field( uint32_t, crtc_id )
......@@ -659,9 +659,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
__entry->dst_rect = drm_plane_state_dest(state);
__entry->stage_idx = stage_idx;
__entry->stage = pstate->stage;
__entry->sspp = sspp;
__entry->multirect_idx = pstate->multirect_index;
__entry->multirect_mode = pstate->multirect_mode;
__entry->sspp = pstate->pipe.sspp->idx;
__entry->multirect_idx = pstate->pipe.multirect_index;
__entry->multirect_mode = pstate->pipe.multirect_mode;
__entry->pixel_format = pixel_format;
__entry->modifier = modifier;
),
......@@ -762,18 +762,17 @@ TRACE_EVENT(dpu_crtc_disable_frame_pending,
);
TRACE_EVENT(dpu_plane_set_scanout,
TP_PROTO(enum dpu_sspp index, struct dpu_hw_fmt_layout *layout,
enum dpu_sspp_multirect_index multirect_index),
TP_ARGS(index, layout, multirect_index),
TP_PROTO(struct dpu_sw_pipe *pipe, struct dpu_hw_fmt_layout *layout),
TP_ARGS(pipe, layout),
TP_STRUCT__entry(
__field( enum dpu_sspp, index )
__field_struct( struct dpu_hw_fmt_layout, layout )
__field( enum dpu_sspp_multirect_index, multirect_index)
),
TP_fast_assign(
__entry->index = index;
__entry->index = pipe->sspp->idx;
__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]} "
"multirect_index:%d", __entry->index, __entry->layout.width,
......
......@@ -179,6 +179,24 @@ static unsigned get_crtc_mask(struct drm_atomic_state *state)
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)
{
struct drm_device *dev = state->dev;
......
......@@ -58,7 +58,7 @@ static void msm_deinit_vram(struct drm_device *ddev);
static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = msm_framebuffer_create,
.atomic_check = drm_atomic_helper_check,
.atomic_check = msm_atomic_check,
.atomic_commit = drm_atomic_helper_commit,
};
......
......@@ -258,6 +258,7 @@ int msm_atomic_init_pending_timer(struct msm_pending_timer *timer,
struct msm_kms *kms, int crtc_idx);
void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer);
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);
void msm_atomic_state_clear(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