Skip to content
This repository was archived by the owner on Apr 9, 2025. It is now read-only.
Open
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
2 changes: 2 additions & 0 deletions drivers/gpu/drm/drm_atomic_uapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
} else if (property == config->writeback_fb_id_property) {
struct drm_framebuffer *fb;
int ret;
drm_dbg_kms(dev, "writeback_fb_id_property, val %d\n", val);

fb = drm_framebuffer_lookup(dev, file_priv, val);
ret = drm_atomic_set_writeback_fb_for_connector(state, fb);
Expand All @@ -758,6 +759,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
return ret;
} else if (property == config->writeback_out_fence_ptr_property) {
s32 __user *fence_ptr = u64_to_user_ptr(val);
drm_dbg_kms(dev, "writeback_out_fence_ptr_property\n");

return set_out_fence_for_connector(state->state, connector,
fence_ptr);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ i915-y += \
display/intel_tv.o \
display/intel_vdsc.o \
display/intel_vrr.o \
display/intel_wb.o \
display/vlv_dsi.o \
display/vlv_dsi_pll.o

Expand Down
8 changes: 7 additions & 1 deletion drivers/gpu/drm/i915/display/intel_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ static u32 acpi_display_type(struct intel_connector *connector)
case DRM_MODE_CONNECTOR_LVDS:
case DRM_MODE_CONNECTOR_eDP:
case DRM_MODE_CONNECTOR_DSI:
case DRM_MODE_CONNECTOR_WRITEBACK:
display_type = ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL;
break;
case DRM_MODE_CONNECTOR_Unknown:
Expand Down Expand Up @@ -349,8 +350,13 @@ void intel_acpi_video_register(struct drm_i915_private *i915)
*/
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
struct intel_panel *panel = &to_intel_connector(connector)->panel;
struct intel_panel *panel;
struct intel_connector *intel_connector =
to_intel_connector(connector);

if (!intel_connector)
continue;
panel = &intel_connector->panel;
if (panel->backlight.funcs && !panel->backlight.device) {
acpi_video_register_backlight();
break;
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/i915/display/intel_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,9 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state)
if (new_crtc_state->do_async_flip)
return;

if (new_crtc_state->output_types & BIT(INTEL_OUTPUT_WB))
return;

if (intel_crtc_needs_vblank_work(new_crtc_state))
intel_crtc_vblank_work_init(new_crtc_state);

Expand Down Expand Up @@ -638,6 +641,9 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
if (new_crtc_state->do_async_flip)
return;

if (new_crtc_state->output_types & BIT(INTEL_OUTPUT_WB))
return;

trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end);

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static const char * const output_type_str[] = {
OUTPUT_TYPE(DSI),
OUTPUT_TYPE(DDI),
OUTPUT_TYPE(DP_MST),
OUTPUT_TYPE(WB),
};

#undef OUTPUT_TYPE
Expand Down
8 changes: 7 additions & 1 deletion drivers/gpu/drm/i915/display/intel_ddi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1953,6 +1953,12 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder)
*/
if (encoder->type == INTEL_OUTPUT_DP_MST)
return;
/*
* WD transcoder is a virtual encoder hence sanization
* is not required for it
*/
if (encoder->type == INTEL_OUTPUT_WB)
return;

if (!encoder->base.crtc && intel_encoder_is_dp(encoder)) {
u8 pipe_mask;
Expand Down Expand Up @@ -4358,7 +4364,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->type = INTEL_OUTPUT_DDI;
encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
encoder->port = port;
encoder->cloneable = 0;
encoder->cloneable = 1 << INTEL_OUTPUT_WB;
encoder->pipe_mask = ~0;

if (IS_DG2(dev_priv)) {
Expand Down
79 changes: 74 additions & 5 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
#include "intel_sprite.h"
#include "intel_tc.h"
#include "intel_vga.h"
#include "intel_wb.h"
#include "i9xx_plane.h"
#include "skl_scaler.h"
#include "skl_universal_plane.h"
Expand Down Expand Up @@ -1076,7 +1077,9 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
continue;

encoder = to_intel_encoder(connector_state->best_encoder);
num_encoders++;

if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
num_encoders++;
}

drm_WARN(encoder->base.dev, num_encoders != 1,
Expand Down Expand Up @@ -1338,7 +1341,8 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
if (hsw_ips_pre_update(state, crtc))
intel_crtc_wait_for_next_vblank(crtc);

if (intel_fbc_pre_update(state, crtc))
if (intel_fbc_pre_update(state, crtc) &&
!(new_crtc_state->output_types & BIT(INTEL_OUTPUT_WB)))
intel_crtc_wait_for_next_vblank(crtc);

if (!needs_async_flip_vtd_wa(old_crtc_state) &&
Expand Down Expand Up @@ -1514,6 +1518,10 @@ static void intel_encoders_update_prepare(struct intel_atomic_state *state)
continue;

intel_connector = to_intel_connector(connector);
/* intel_connector instance is not created for WD transcoder */
if (!intel_connector)
continue;

encoder = intel_connector_primary_encoder(intel_connector);
if (!encoder->update_prepare)
continue;
Expand Down Expand Up @@ -1543,6 +1551,10 @@ static void intel_encoders_update_complete(struct intel_atomic_state *state)
continue;

intel_connector = to_intel_connector(connector);
/* intel_connector instance is not created for WD transcoder */
if (!intel_connector)
continue;

encoder = intel_connector_primary_encoder(intel_connector);
if (!encoder->update_complete)
continue;
Expand All @@ -1553,6 +1565,38 @@ static void intel_encoders_update_complete(struct intel_atomic_state *state)
}
}

static void intel_queue_writeback_job(struct intel_atomic_state *state)
{
struct drm_connector_state *new_conn_state;
struct drm_connector *connector;
struct drm_writeback_connector *wb_conn;
int i;

for_each_new_connector_in_state(&state->base, connector, new_conn_state,
i) {
if (!new_conn_state->writeback_job)
continue;

wb_conn = drm_connector_to_writeback(connector);
drm_writeback_queue_job(wb_conn, new_conn_state);
}
}

static void intel_enable_writeback_capture(struct intel_atomic_state *state,
struct intel_crtc_state *crtc_state)
{
struct drm_connector_state *new_conn_state;
struct drm_connector *connector;
int i;

for_each_new_connector_in_state(&state->base, connector, new_conn_state,
i) {
if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
continue;
intel_wb_enable_capture(crtc_state, new_conn_state);
}
}

static void intel_encoders_pre_pll_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
Expand Down Expand Up @@ -1653,8 +1697,12 @@ static void intel_encoders_post_disable(struct intel_atomic_state *state,
int i;

for_each_old_connector_in_state(&state->base, conn, old_conn_state, i) {
struct intel_encoder *encoder =
to_intel_encoder(old_conn_state->best_encoder);
struct intel_encoder *encoder;

if (conn->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
continue;

encoder = to_intel_encoder(old_conn_state->best_encoder);

if (old_conn_state->crtc != &crtc->base)
continue;
Expand Down Expand Up @@ -1933,7 +1981,8 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
bdw_set_pipemisc(new_crtc_state);

if (!intel_crtc_is_bigjoiner_slave(new_crtc_state) &&
!transcoder_is_dsi(cpu_transcoder))
!transcoder_is_dsi(cpu_transcoder) &&
!transcoder_is_wd(cpu_transcoder))
hsw_configure_cpu_transcoder(new_crtc_state);

crtc->active = true;
Expand Down Expand Up @@ -7535,6 +7584,11 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
}
}

for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
if ((new_crtc_state->output_types & BIT(INTEL_OUTPUT_WB)))
intel_wb_set_vblank_event(state, crtc, new_crtc_state);
}

intel_encoders_update_prepare(state);

intel_dbuf_pre_plane_update(state);
Expand All @@ -7545,9 +7599,20 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_crtc_enable_flip_done(state, crtc);
}

for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
if ((new_crtc_state->output_types & BIT(INTEL_OUTPUT_WB))) {
intel_queue_writeback_job(state);
intel_enable_writeback_capture(state, new_crtc_state);
}
}

/* Now enable the clocks, plane, pipe, and connectors that we set up. */
dev_priv->display.funcs.display->commit_modeset_enables(state);

for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
if ((new_crtc_state->output_types & BIT(INTEL_OUTPUT_WB)))
intel_wb_set_vblank_event(state, crtc, new_crtc_state);
}
intel_encoders_update_complete(state);

if (state->modeset)
Expand Down Expand Up @@ -7899,6 +7964,10 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
if (!HAS_DISPLAY(dev_priv))
return;

/* Initializing WD transcoder */
if (DISPLAY_VER(dev_priv) >= 12)
intel_wb_init(dev_priv, TRANSCODER_WD_0);

if (IS_DG2(dev_priv)) {
intel_ddi_init(dev_priv, PORT_A);
intel_ddi_init(dev_priv, PORT_B);
Expand Down
14 changes: 13 additions & 1 deletion drivers/gpu/drm/i915/display/intel_display.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct intel_crtc_state;
struct intel_digital_port;
struct intel_dp;
struct intel_encoder;
struct intel_connector;
struct intel_initial_plane_config;
struct intel_load_detect_pipe;
struct intel_plane;
Expand Down Expand Up @@ -120,6 +121,8 @@ enum transcoder {
TRANSCODER_DSI_1,
TRANSCODER_DSI_A = TRANSCODER_DSI_0, /* legacy DSI */
TRANSCODER_DSI_C = TRANSCODER_DSI_1, /* legacy DSI */
TRANSCODER_WD_0,
TRANSCODER_WD_1,

I915_MAX_TRANSCODERS
};
Expand All @@ -141,6 +144,10 @@ static inline const char *transcoder_name(enum transcoder transcoder)
return "DSI A";
case TRANSCODER_DSI_C:
return "DSI C";
case TRANSCODER_WD_0:
return "WD 0";
case TRANSCODER_WD_1:
return "WD 1";
default:
return "<invalid>";
}
Expand All @@ -151,6 +158,11 @@ static inline bool transcoder_is_dsi(enum transcoder transcoder)
return transcoder == TRANSCODER_DSI_A || transcoder == TRANSCODER_DSI_C;
}

static inline bool transcoder_is_wd(enum transcoder transcoder)
{
return transcoder == TRANSCODER_WD_0 || transcoder == TRANSCODER_WD_1;
}

/*
* Global legacy plane identifier. Valid only for primary/sprite
* planes on pre-g4x, and only for primary planes on g4x-bdw.
Expand Down Expand Up @@ -463,7 +475,7 @@ enum hpd_pin {
for_each_if(intel_encoder_can_psr(intel_encoder))

#define for_each_intel_connector_iter(intel_connector, iter) \
while ((intel_connector = to_intel_connector(drm_connector_list_iter_next(iter))))
while ((intel_connector = intel_connector_list_iter_next(iter)))

#define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \
list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
Expand Down
13 changes: 9 additions & 4 deletions drivers/gpu/drm/i915/display/intel_display_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ static void intel_hdmi_info(struct seq_file *m,
static void intel_connector_info(struct seq_file *m,
struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_connector *intel_connector;
const struct drm_connector_state *conn_state = connector->state;
struct intel_encoder *encoder =
to_intel_encoder(conn_state->best_encoder);
Expand All @@ -573,6 +573,8 @@ static void intel_connector_info(struct seq_file *m,
if (!encoder)
return;

intel_connector = to_intel_connector(connector);

switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
Expand All @@ -590,12 +592,15 @@ static void intel_connector_info(struct seq_file *m,
break;
}

seq_puts(m, "\tHDCP version: ");
intel_hdcp_info(m, intel_connector);
if (intel_connector) {
seq_puts(m, "\tHDCP version: ");
intel_hdcp_info(m, intel_connector);
}

seq_printf(m, "\tmax bpc: %u\n", connector->display_info.bpc);

intel_panel_info(m, intel_connector);
if (intel_connector)
intel_panel_info(m, intel_connector);

seq_printf(m, "\tmodes:\n");
list_for_each_entry(mode, &connector->modes, head)
Expand Down
Loading