diff options
Diffstat (limited to 'drivers/gpu/drm/display')
| -rw-r--r-- | drivers/gpu/drm/display/drm_bridge_connector.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/display/drm_dp_helper.c | 96 | ||||
| -rw-r--r-- | drivers/gpu/drm/display/drm_dp_tunnel.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/display/drm_hdmi_cec_helper.c | 2 |
5 files changed, 87 insertions, 42 deletions
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 6cdb432dbc30..5eb7e9bfe361 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -210,7 +210,7 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force) enum drm_connector_status status; if (detect) { - status = detect->funcs->detect(detect); + status = detect->funcs->detect(detect, connector); if (hdmi) drm_atomic_helper_connector_hdmi_hotplug(connector, status); @@ -463,7 +463,7 @@ static int drm_bridge_connector_audio_startup(struct drm_connector *connector) if (!bridge->funcs->hdmi_audio_startup) return 0; - return bridge->funcs->hdmi_audio_startup(connector, bridge); + return bridge->funcs->hdmi_audio_startup(bridge, connector); } if (bridge_connector->bridge_dp_audio) { @@ -472,7 +472,7 @@ static int drm_bridge_connector_audio_startup(struct drm_connector *connector) if (!bridge->funcs->dp_audio_startup) return 0; - return bridge->funcs->dp_audio_startup(connector, bridge); + return bridge->funcs->dp_audio_startup(bridge, connector); } return -EINVAL; @@ -489,13 +489,13 @@ static int drm_bridge_connector_audio_prepare(struct drm_connector *connector, if (bridge_connector->bridge_hdmi_audio) { bridge = bridge_connector->bridge_hdmi_audio; - return bridge->funcs->hdmi_audio_prepare(connector, bridge, fmt, hparms); + return bridge->funcs->hdmi_audio_prepare(bridge, connector, fmt, hparms); } if (bridge_connector->bridge_dp_audio) { bridge = bridge_connector->bridge_dp_audio; - return bridge->funcs->dp_audio_prepare(connector, bridge, fmt, hparms); + return bridge->funcs->dp_audio_prepare(bridge, connector, fmt, hparms); } return -EINVAL; @@ -509,12 +509,12 @@ static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector) if (bridge_connector->bridge_hdmi_audio) { bridge = bridge_connector->bridge_hdmi_audio; - bridge->funcs->hdmi_audio_shutdown(connector, bridge); + bridge->funcs->hdmi_audio_shutdown(bridge, connector); } if (bridge_connector->bridge_dp_audio) { bridge = bridge_connector->bridge_dp_audio; - bridge->funcs->dp_audio_shutdown(connector, bridge); + bridge->funcs->dp_audio_shutdown(bridge, connector); } } @@ -531,7 +531,7 @@ static int drm_bridge_connector_audio_mute_stream(struct drm_connector *connecto if (!bridge->funcs->hdmi_audio_mute_stream) return -ENOTSUPP; - return bridge->funcs->hdmi_audio_mute_stream(connector, bridge, + return bridge->funcs->hdmi_audio_mute_stream(bridge, connector, enable, direction); } @@ -541,7 +541,7 @@ static int drm_bridge_connector_audio_mute_stream(struct drm_connector *connecto if (!bridge->funcs->dp_audio_mute_stream) return -ENOTSUPP; - return bridge->funcs->dp_audio_mute_stream(connector, bridge, + return bridge->funcs->dp_audio_mute_stream(bridge, connector, enable, direction); } @@ -604,7 +604,7 @@ static int drm_bridge_connector_hdmi_cec_init(struct drm_connector *connector) if (!bridge->funcs->hdmi_cec_init) return 0; - return bridge->funcs->hdmi_cec_init(connector, bridge); + return bridge->funcs->hdmi_cec_init(bridge, connector); } static const struct drm_connector_hdmi_cec_funcs drm_bridge_connector_hdmi_cec_funcs = { @@ -795,11 +795,14 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, if (bridge_connector->bridge_hdmi_audio || bridge_connector->bridge_dp_audio) { struct device *dev; + struct drm_bridge *bridge; if (bridge_connector->bridge_hdmi_audio) - dev = bridge_connector->bridge_hdmi_audio->hdmi_audio_dev; + bridge = bridge_connector->bridge_hdmi_audio; else - dev = bridge_connector->bridge_dp_audio->hdmi_audio_dev; + bridge = bridge_connector->bridge_dp_audio; + + dev = bridge->hdmi_audio_dev; ret = drm_connector_hdmi_audio_init(connector, dev, &drm_bridge_connector_hdmi_audio_funcs, diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c index 7b9afcf48836..2d279e82922f 100644 --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c @@ -58,7 +58,7 @@ static int dp_aux_ep_probe(struct device *dev) container_of(aux_ep, struct dp_aux_ep_device_with_data, aux_ep); int ret; - ret = dev_pm_domain_attach(dev, true); + ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON); if (ret) return dev_err_probe(dev, ret, "Failed to attach to PM Domain\n"); diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 385a1bfdb272..1ecc3df7e316 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -742,7 +742,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, int ret; if (dpcd_access_needs_probe(aux)) { - ret = drm_dp_dpcd_probe(aux, DP_LANE0_1_STATUS); + ret = drm_dp_dpcd_probe(aux, DP_TRAINING_PATTERN_SET); if (ret < 0) return ret; } @@ -3957,23 +3957,31 @@ EXPORT_SYMBOL(drm_dp_pcon_convert_rgb_to_ycbcr); * Returns: %0 on success, negative error code on failure */ int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, - u16 level) + u32 level) { int ret; - u8 buf[2] = { 0 }; + unsigned int offset = DP_EDP_BACKLIGHT_BRIGHTNESS_MSB; + u8 buf[3] = { 0 }; /* The panel uses the PWM for controlling brightness levels */ - if (!bl->aux_set) + if (!(bl->aux_set || bl->luminance_set)) return 0; - if (bl->lsb_reg_used) { + if (bl->luminance_set) { + level = level * 1000; + level &= 0xffffff; + buf[0] = (level & 0x0000ff); + buf[1] = (level & 0x00ff00) >> 8; + buf[2] = (level & 0xff0000) >> 16; + offset = DP_EDP_PANEL_TARGET_LUMINANCE_VALUE; + } else if (bl->lsb_reg_used) { buf[0] = (level & 0xff00) >> 8; buf[1] = (level & 0x00ff); } else { buf[0] = level; } - ret = drm_dp_dpcd_write_data(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, buf, sizeof(buf)); + ret = drm_dp_dpcd_write_data(aux, offset, buf, sizeof(buf)); if (ret < 0) { drm_err(aux->drm_dev, "%s: Failed to write aux backlight level: %d\n", @@ -4036,7 +4044,7 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli * Returns: %0 on success, negative error code on failure. */ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, - const u16 level) + const u32 level) { int ret; u8 dpcd_buf; @@ -4046,6 +4054,9 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli else dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_PWM; + if (bl->luminance_set) + dpcd_buf |= DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE; + if (bl->pwmgen_bit_count) { ret = drm_dp_dpcd_write_byte(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); if (ret < 0) @@ -4209,7 +4220,7 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i u8 *current_mode) { int ret; - u8 buf[2]; + u8 buf[3]; u8 mode_reg; ret = drm_dp_dpcd_read_byte(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &mode_reg); @@ -4226,17 +4237,37 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i if (*current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { int size = 1 + bl->lsb_reg_used; - ret = drm_dp_dpcd_read_data(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, buf, size); - if (ret < 0) { - drm_dbg_kms(aux->drm_dev, "%s: Failed to read backlight level: %d\n", - aux->name, ret); - return ret; - } + if (bl->luminance_set) { + ret = drm_dp_dpcd_read_data(aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, + buf, sizeof(buf)); + if (ret < 0) { + drm_dbg_kms(aux->drm_dev, + "%s: Failed to read backlight level: %d\n", + aux->name, ret); + return ret; + } - if (bl->lsb_reg_used) - return (buf[0] << 8) | buf[1]; - else - return buf[0]; + /* + * Incase luminance is set we want to send the value back in nits but + * since DP_EDP_PANEL_TARGET_LUMINANCE stores values in millinits we + * need to divide by 1000. + */ + return (buf[0] | buf[1] << 8 | buf[2] << 16) / 1000; + } else { + ret = drm_dp_dpcd_read_data(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, + buf, size); + if (ret < 0) { + drm_dbg_kms(aux->drm_dev, + "%s: Failed to read backlight level: %d\n", + aux->name, ret); + return ret; + } + + if (bl->lsb_reg_used) + return (buf[0] << 8) | buf[1]; + else + return buf[0]; + } } /* @@ -4251,10 +4282,12 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i * interface. * @aux: The DP aux device to use for probing * @bl: The &drm_edp_backlight_info struct to fill out with information on the backlight + * @max_luminance: max luminance when need luminance is set as true * @driver_pwm_freq_hz: Optional PWM frequency from the driver in hz * @edp_dpcd: A cached copy of the eDP DPCD * @current_level: Where to store the probed brightness level, if any * @current_mode: Where to store the currently set backlight control mode + * @need_luminance: Tells us if a we want to manipulate backlight using luminance values * * Initializes a &drm_edp_backlight_info struct by probing @aux for it's backlight capabilities, * along with also probing the current and maximum supported brightness levels. @@ -4266,8 +4299,9 @@ drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_i */ int drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, + u32 max_luminance, u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], - u16 *current_level, u8 *current_mode) + u32 *current_level, u8 *current_mode, bool need_luminance) { int ret; @@ -4277,18 +4311,26 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl bl->aux_set = true; if (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) bl->lsb_reg_used = true; + if ((edp_dpcd[0] & DP_EDP_15) && edp_dpcd[3] & + (DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE) && need_luminance) + bl->luminance_set = true; /* Sanity check caps */ - if (!bl->aux_set && !(edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP)) { + if (!bl->aux_set && !(edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP) && + !bl->luminance_set) { drm_dbg_kms(aux->drm_dev, - "%s: Panel supports neither AUX or PWM brightness control? Aborting\n", + "%s: Panel does not support AUX, PWM or luminance-based brightness control. Aborting\n", aux->name); return -EINVAL; } - ret = drm_edp_backlight_probe_max(aux, bl, driver_pwm_freq_hz, edp_dpcd); - if (ret < 0) - return ret; + if (bl->luminance_set) { + bl->max = max_luminance; + } else { + ret = drm_edp_backlight_probe_max(aux, bl, driver_pwm_freq_hz, edp_dpcd); + if (ret < 0) + return ret; + } ret = drm_edp_backlight_probe_state(aux, bl, current_mode); if (ret < 0) @@ -4367,7 +4409,7 @@ int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) { struct dp_aux_backlight *bl; struct backlight_properties props = { 0 }; - u16 current_level; + u32 current_level; u8 current_mode; u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; int ret; @@ -4391,8 +4433,8 @@ int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) bl->aux = aux; - ret = drm_edp_backlight_init(aux, &bl->info, 0, edp_dpcd, - ¤t_level, ¤t_mode); + ret = drm_edp_backlight_init(aux, &bl->info, 0, 0, edp_dpcd, + ¤t_level, ¤t_mode, false); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/display/drm_dp_tunnel.c b/drivers/gpu/drm/display/drm_dp_tunnel.c index 8a4ef5438f35..43f13a7c79b9 100644 --- a/drivers/gpu/drm/display/drm_dp_tunnel.c +++ b/drivers/gpu/drm/display/drm_dp_tunnel.c @@ -1921,7 +1921,7 @@ drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count) } #ifdef CONFIG_DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG - ref_tracker_dir_init(&mgr->ref_tracker, 16, "dptun"); + ref_tracker_dir_init(&mgr->ref_tracker, 16, "drm_dptun"); #endif for (i = 0; i < max_group_count; i++) { diff --git a/drivers/gpu/drm/display/drm_hdmi_cec_helper.c b/drivers/gpu/drm/display/drm_hdmi_cec_helper.c index b4273c3522fa..3651ad0f76e0 100644 --- a/drivers/gpu/drm/display/drm_hdmi_cec_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_cec_helper.c @@ -69,7 +69,7 @@ static void drm_connector_hdmi_cec_adapter_unregister(struct drm_device *dev, vo struct drm_connector *connector = res; struct drm_connector_hdmi_cec_data *data = connector->cec.data; - cec_delete_adapter(data->adapter); + cec_unregister_adapter(data->adapter); if (data->funcs->uninit) data->funcs->uninit(connector); |
