Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle
description: Reference to the AOSS side-channel message RAM.

qcom,broken-reset:
type: boolean
description:
Indicates that the remote processor reset line is not owned by the
operating system. When present, the PAS driver must not try to boot or
shut down the remote processor through SCM and may only attach to it if
it is already running.

smd-edge: false

firmware-name:
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/display/drm_hdmi_audio_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ EXPORT_SYMBOL(drm_connector_hdmi_audio_plugged_notify);

static const struct hdmi_codec_ops drm_connector_hdmi_audio_ops = {
.audio_startup = drm_connector_hdmi_audio_startup,
.hw_params = drm_connector_hdmi_audio_prepare,
.prepare = drm_connector_hdmi_audio_prepare,
.audio_shutdown = drm_connector_hdmi_audio_shutdown,
.mute_stream = drm_connector_hdmi_audio_mute_stream,
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

static const struct dpu_caps sc7280_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_dsc_encoder_width = DEFAULT_DSC_ENCODER_MAX_WIDTH,
.max_mixer_blendstages = 0x7,
.has_dim_layer = true,
.has_idle_pc = true,
Expand Down Expand Up @@ -122,24 +123,28 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = {
{
.name = "pingpong_0", .id = PINGPONG_0,
.base = 0x69000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = 0,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
}, {
.name = "pingpong_1", .id = PINGPONG_1,
.base = 0x6a000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = 0,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
}, {
.name = "pingpong_2", .id = PINGPONG_2,
.base = 0x6b000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_1,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
}, {
.name = "pingpong_3", .id = PINGPONG_3,
.base = 0x6c000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_1,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
Expand Down
7 changes: 7 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

static const struct dpu_caps sc8280xp_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_dsc_encoder_width = DEFAULT_DSC_ENCODER_MAX_WIDTH,
.max_mixer_blendstages = 11,
.has_src_split = true,
.has_dim_layer = true,
Expand Down Expand Up @@ -204,36 +205,42 @@ static const struct dpu_pingpong_cfg sc8280xp_pp[] = {
{
.name = "pingpong_0", .id = PINGPONG_0,
.base = 0x69000, .len = 0,
.max_linewidth = DPU_8_x_MAX_PINGPONG_0_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_0,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
}, {
.name = "pingpong_1", .id = PINGPONG_1,
.base = 0x6a000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_0,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
}, {
.name = "pingpong_2", .id = PINGPONG_2,
.base = 0x6b000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_1,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
}, {
.name = "pingpong_3", .id = PINGPONG_3,
.base = 0x6c000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_1,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
}, {
.name = "pingpong_4", .id = PINGPONG_4,
.base = 0x6d000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_2,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
}, {
.name = "pingpong_5", .id = PINGPONG_5,
.base = 0x6e000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_2,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
Expand Down
9 changes: 9 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

static const struct dpu_caps x1e80100_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_dsc_encoder_width = DEFAULT_DSC_ENCODER_MAX_WIDTH,
.max_mixer_blendstages = 0xb,
.has_src_split = true,
.has_dim_layer = true,
Expand Down Expand Up @@ -201,47 +202,55 @@ static const struct dpu_pingpong_cfg x1e80100_pp[] = {
{
.name = "pingpong_0", .id = PINGPONG_0,
.base = 0x69000, .len = 0,
.max_linewidth = DPU_8_x_MAX_PINGPONG_0_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_0,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
}, {
.name = "pingpong_1", .id = PINGPONG_1,
.base = 0x6a000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_0,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
}, {
.name = "pingpong_2", .id = PINGPONG_2,
.base = 0x6b000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_1,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
}, {
.name = "pingpong_3", .id = PINGPONG_3,
.base = 0x6c000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_1,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
}, {
.name = "pingpong_4", .id = PINGPONG_4,
.base = 0x6d000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_2,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
}, {
.name = "pingpong_5", .id = PINGPONG_5,
.base = 0x6e000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_2,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
}, {
.name = "pingpong_cwb_0", .id = PINGPONG_CWB_0,
.base = 0x66000, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
}, {
.name = "pingpong_cwb_1", .id = PINGPONG_CWB_1,
.base = 0x66400, .len = 0,
.max_linewidth = DPU_6_x_MAX_PINGPONG_WIDTH,
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
},
Expand Down
46 changes: 39 additions & 7 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,20 +762,46 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc)
_dpu_crtc_complete_flip(crtc);
}

static int msm_display_get_max_pingpong_width(struct dpu_kms *dpu_kms)
{
const struct dpu_pingpong_cfg *pingpong;
u32 max_pingpong_width = dpu_kms->catalog->pingpong[0].max_linewidth;

/*
* Find the smallest overall PINGPONG max_linewidth in the catalog since
* max_linewidth can differ between PINGPONGs even within the same
* chipset.
*
* Note: While, for DPU 8.x+, PINGPONG_0 can technically support up to
* 8k resolutions, this requires reworking the RM to try to reserve
* PINGPONG_0 for modes greater than 5k.
*
* Once this additional logic is implemented, we can drop this helper
* and use the reserved PINGPONG's max_linewidth
*/
for (int i = 1; i < dpu_kms->catalog->pingpong_count; i++) {
pingpong = &dpu_kms->catalog->pingpong[i];
max_pingpong_width = min(max_pingpong_width, pingpong->max_linewidth);
}

return max_pingpong_width;
}

static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
struct drm_display_mode *adj_mode = &state->adjusted_mode;
u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers;
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
int max_pingpong_width = msm_display_get_max_pingpong_width(dpu_kms);
int i;

/* if we cannot merge 2 LMs (no 3d mux) better to fail earlier
* before even checking the width after the split
*/
if (!dpu_kms->catalog->caps->has_3d_merge &&
adj_mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width)
adj_mode->hdisplay > max_pingpong_width)
return -E2BIG;

for (i = 0; i < cstate->num_mixers; i++) {
Expand All @@ -787,7 +813,7 @@ static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc,

trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r);

if (drm_rect_width(r) > dpu_kms->catalog->caps->max_mixer_width)
if (drm_rect_width(r) > max_pingpong_width)
return -E2BIG;
}

Expand Down Expand Up @@ -1367,7 +1393,6 @@ static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc_state
}

#define MAX_CHANNELS_PER_CRTC PIPES_PER_PLANE
#define MAX_HDISPLAY_SPLIT 1080

static struct msm_display_topology dpu_crtc_get_topology(
struct drm_crtc *crtc,
Expand All @@ -1377,12 +1402,18 @@ static struct msm_display_topology dpu_crtc_get_topology(
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
struct msm_display_topology topology = {0};
struct drm_encoder *drm_enc;
const struct dpu_caps *caps = dpu_kms->catalog->caps;
u32 max_hdisplay_split;

drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask)
dpu_encoder_update_topology(drm_enc, &topology, crtc_state->state,
&crtc_state->adjusted_mode);

topology.cwb_enabled = drm_crtc_in_clone_mode(crtc_state);
max_hdisplay_split = msm_display_get_max_pingpong_width(dpu_kms);

if (topology.num_dsc > 0 && caps->max_dsc_encoder_width > 0)
max_hdisplay_split = min(max_hdisplay_split, caps->max_dsc_encoder_width);

/*
* Datapath topology selection
Expand All @@ -1403,15 +1434,15 @@ static struct msm_display_topology dpu_crtc_get_topology(
* count both the WB and real-time phys encoders.
*
* For non-DSC CWB usecases, have the num_lm be decided by the
* (mode->hdisplay > MAX_HDISPLAY_SPLIT) check.
* (mode->hdisplay > max_hdisplay_split) check.
*/

if (topology.num_intf == 2 && !topology.cwb_enabled)
topology.num_lm = 2;
else if (topology.num_dsc == 2)
topology.num_lm = 2;
else if (dpu_kms->catalog->caps->has_3d_merge)
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
topology.num_lm = (mode->hdisplay > max_hdisplay_split) ? 2 : 1;
else
topology.num_lm = 1;

Expand Down Expand Up @@ -1591,12 +1622,13 @@ static enum drm_mode_status dpu_crtc_mode_valid(struct drm_crtc *crtc,
{
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
u64 adjusted_mode_clk;
int max_pingpong_width = msm_display_get_max_pingpong_width(dpu_kms);

/* if there is no 3d_mux block we cannot merge LMs so we cannot
* split the large layer into 2 LMs, filter out such modes
*/
if (!dpu_kms->catalog->caps->has_3d_merge &&
mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width)
mode->hdisplay > max_pingpong_width)
return MODE_BAD_HVALUE;

adjusted_mode_clk = dpu_core_perf_adjusted_mode_clk(mode->clock,
Expand All @@ -1616,7 +1648,7 @@ static enum drm_mode_status dpu_crtc_mode_valid(struct drm_crtc *crtc,
* max crtc width is equal to the max mixer width * 2 and max height is 4K
*/
return drm_mode_validate_size(mode,
2 * dpu_kms->catalog->caps->max_mixer_width,
2 * max_pingpong_width,
4096);
}

Expand Down
10 changes: 10 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
#define DPU_MAX_IMG_WIDTH 0x3fff
#define DPU_MAX_IMG_HEIGHT 0x3fff

#define DPU_1_x_MAX_PINGPONG_WIDTH 4096
#define DPU_6_x_MAX_PINGPONG_WIDTH 5120
#define DPU_8_x_MAX_PINGPONG_0_WIDTH 8960

#define DEFAULT_DSC_ENCODER_MAX_WIDTH 2560

#define CRTC_DUAL_MIXERS 2

#define MAX_XIN_COUNT 16
Expand Down Expand Up @@ -267,6 +273,7 @@ struct dpu_rotation_cfg {
/**
* struct dpu_caps - define DPU capabilities
* @max_mixer_width max layer mixer line width support.
* @max_dsc_encoder_width max dsc encoder line width support
* @max_mixer_blendstages max layer mixer blend stages or
* supported z order
* @has_src_split source split feature status
Expand All @@ -280,6 +287,7 @@ struct dpu_rotation_cfg {
*/
struct dpu_caps {
u32 max_mixer_width;
u32 max_dsc_encoder_width;
u32 max_mixer_blendstages;
bool has_src_split;
bool has_dim_layer;
Expand Down Expand Up @@ -463,13 +471,15 @@ struct dpu_dspp_cfg {
* struct dpu_pingpong_cfg - information of PING-PONG blocks
* @id enum identifying this block
* @base register offset of this block
* @max_linewidth max linewidth for PINGPONG
* @intr_done: index for PINGPONG done interrupt
* @intr_rdptr: index for PINGPONG readpointer done interrupt
* @sblk sub-blocks information
*/
struct dpu_pingpong_cfg {
DPU_HW_BLK_INFO;
u32 merge_3d;
u32 max_linewidth;
unsigned int intr_done;
unsigned int intr_rdptr;
const struct dpu_pingpong_sub_blks *sblk;
Expand Down
9 changes: 1 addition & 8 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,7 @@ static int dpu_wb_conn_get_modes(struct drm_connector *connector)
struct msm_drm_private *priv = dev->dev_private;
struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);

/*
* We should ideally be limiting the modes only to the maxlinewidth but
* on some chipsets this will allow even 4k modes to be added which will
* fail the per SSPP bandwidth checks. So, till we have dual-SSPP support
* and source split support added lets limit the modes based on max_mixer_width
* as 4K modes can then be supported.
*/
return drm_add_modes_noedid(connector, dpu_kms->catalog->caps->max_mixer_width,
return drm_add_modes_noedid(connector, dpu_kms->catalog->wb->maxlinewidth,
dev->mode_config.max_height);
}

Expand Down
Loading