Merge branch 'drm-next-4.17' of git://people.freedesktop.org/~agd5f/linux into drm...
authorDave Airlie <airlied@redhat.com>
Thu, 12 Apr 2018 23:25:21 +0000 (09:25 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 12 Apr 2018 23:25:21 +0000 (09:25 +1000)
- Add a PX quirk for radeon
- Fix flickering and stability issues with DC on some platforms
- Fix HDMI audio regression
- Few other misc DC and base driver fixes

* 'drm-next-4.17' of git://people.freedesktop.org/~agd5f/linux:
  Revert "drm/amd/display: disable CRTCs with NULL FB on their primary plane (V2)"
  Revert "drm/amd/display: fix dereferencing possible ERR_PTR()"
  drm/amd/display: Fix regamma not affecting full-intensity color values
  drm/amd/display: Fix FBC text console corruption
  drm/amd/display: Only register backlight device if embedded panel connected
  drm/amd/display: fix brightness level after resume from suspend
  drm/amd/display: HDMI has no sound after Panel power off/on
  drm/amdgpu: add MP1 and THM hw ip base reg offset
  drm/amdgpu: fix null pointer panic with direct fw loading on gpu reset
  drm/radeon: add PX quirk for Asus K73TK

drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/radeon/radeon_device.c

index 0193f6ced00be025372e5a5e27c9b8ec1425b42f..c8b605f3dc05d58c2bbc88cf98f772e5418ce7f6 100644 (file)
@@ -1379,6 +1379,7 @@ enum amd_hw_ip_block_type {
        ATHUB_HWIP,
        NBIO_HWIP,
        MP0_HWIP,
+       MP1_HWIP,
        UVD_HWIP,
        VCN_HWIP = UVD_HWIP,
        VCE_HWIP,
@@ -1388,6 +1389,7 @@ enum amd_hw_ip_block_type {
        SMUIO_HWIP,
        PWR_HWIP,
        NBIF_HWIP,
+       THM_HWIP,
        MAX_HWIP
 };
 
index 19e71f4a8ac2fa6bd579b835cd6cd2513ff0999e..c7d43e064fc76a010a04b5634713c51fd816c0ad 100644 (file)
@@ -505,6 +505,9 @@ failed:
 
 int psp_gpu_reset(struct amdgpu_device *adev)
 {
+       if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
+               return 0;
+
        return psp_mode1_reset(&adev->psp);
 }
 
index 4c45db7f115740d3b6e1e49cf4751812655913b8..45aafca7f31560fb4e0862c500046e61030cb336 100644 (file)
@@ -38,6 +38,7 @@ int vega10_reg_base_init(struct amdgpu_device *adev)
                adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
                adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
                adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
+               adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
                adev->reg_offset[UVD_HWIP][i] = (uint32_t *)(&(UVD_BASE.instance[i]));
                adev->reg_offset[VCE_HWIP][i] = (uint32_t *)(&(VCE_BASE.instance[i]));
                adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN_BASE.instance[i]));
@@ -49,7 +50,7 @@ int vega10_reg_base_init(struct amdgpu_device *adev)
                adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
                adev->reg_offset[PWR_HWIP][i] = (uint32_t *)(&(PWR_BASE.instance[i]));
                adev->reg_offset[NBIF_HWIP][i] = (uint32_t *)(&(NBIF_BASE.instance[i]));
-
+               adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
        }
        return 0;
 }
index e42a28e3adc5179ba26faf0c6583109221cdcb70..4e2f379ce2172c4a8b7925aec15873105f4b2c40 100644 (file)
@@ -1403,6 +1403,28 @@ static int initialize_plane(struct amdgpu_display_manager *dm,
        return ret;
 }
 
+
+static void register_backlight_device(struct amdgpu_display_manager *dm,
+                                     struct dc_link *link)
+{
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
+       defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
+
+       if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
+           link->type != dc_connection_none) {
+               /* Event if registration failed, we should continue with
+                * DM initialization because not having a backlight control
+                * is better then a black screen.
+                */
+               amdgpu_dm_register_backlight_device(dm);
+
+               if (dm->backlight_dev)
+                       dm->backlight_link = link;
+       }
+#endif
+}
+
+
 /* In this architecture, the association
  * connector -> encoder -> crtc
  * id not really requried. The crtc and connector will hold the
@@ -1456,6 +1478,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 
        /* loops over all connectors on the board */
        for (i = 0; i < link_cnt; i++) {
+               struct dc_link *link = NULL;
 
                if (i > AMDGPU_DM_MAX_DISPLAY_INDEX) {
                        DRM_ERROR(
@@ -1482,9 +1505,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
                        goto fail;
                }
 
-               if (dc_link_detect(dc_get_link_at_index(dm->dc, i),
-                               DETECT_REASON_BOOT))
+               link = dc_get_link_at_index(dm->dc, i);
+
+               if (dc_link_detect(link, DETECT_REASON_BOOT)) {
                        amdgpu_dm_update_connector_after_detect(aconnector);
+                       register_backlight_device(dm, link);
+               }
+
+
        }
 
        /* Software is initialized. Now we can register interrupt handlers. */
@@ -2685,7 +2713,8 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
        defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
 
-       if (link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) {
+       if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
+           link->type != dc_connection_none) {
                amdgpu_dm_register_backlight_device(dm);
 
                if (dm->backlight_dev) {
@@ -3561,6 +3590,7 @@ create_i2c(struct ddc_service *ddc_service,
        return i2c;
 }
 
+
 /* Note: this function assumes that dc_link_detect() was called for the
  * dc_link which will be represented by this aconnector.
  */
@@ -3630,28 +3660,6 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
                || connector_type == DRM_MODE_CONNECTOR_eDP)
                amdgpu_dm_initialize_dp_connector(dm, aconnector);
 
-#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
-       defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
-
-       /* NOTE: this currently will create backlight device even if a panel
-        * is not connected to the eDP/LVDS connector.
-        *
-        * This is less than ideal but we don't have sink information at this
-        * stage since detection happens after. We can't do detection earlier
-        * since MST detection needs connectors to be created first.
-        */
-       if (link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) {
-               /* Event if registration failed, we should continue with
-                * DM initialization because not having a backlight control
-                * is better then a black screen.
-                */
-               amdgpu_dm_register_backlight_device(dm);
-
-               if (dm->backlight_dev)
-                       dm->backlight_link = link;
-       }
-#endif
-
 out_free:
        if (res) {
                kfree(i2c);
@@ -4840,33 +4848,6 @@ static int dm_update_planes_state(struct dc *dc,
        return ret;
 }
 
-static int dm_atomic_check_plane_state_fb(struct drm_atomic_state *state,
-                                         struct drm_crtc *crtc)
-{
-       struct drm_plane *plane;
-       struct drm_crtc_state *crtc_state;
-
-       WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
-
-       drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
-               struct drm_plane_state *plane_state =
-                       drm_atomic_get_plane_state(state, plane);
-
-               if (IS_ERR(plane_state))
-                       return -EDEADLK;
-
-               crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc);
-               if (IS_ERR(crtc_state))
-                       return PTR_ERR(crtc_state);
-
-               if (crtc->primary == plane && crtc_state->active) {
-                       if (!plane_state->fb)
-                               return -EINVAL;
-               }
-       }
-       return 0;
-}
-
 static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                  struct drm_atomic_state *state)
 {
@@ -4890,10 +4871,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                goto fail;
 
        for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
-               ret = dm_atomic_check_plane_state_fb(state, crtc);
-               if (ret)
-                       goto fail;
-
                if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
                    !new_crtc_state->color_mgmt_changed)
                        continue;
index eeb04471b2f50699b033574f46dcfea042d00633..6d1c4981a1851fa23a6b42f7ba98f78ca55f686b 100644 (file)
@@ -1997,6 +1997,19 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
        return true;
 }
 
+bool dc_link_set_abm_disable(const struct dc_link *link)
+{
+       struct dc  *core_dc = link->ctx->dc;
+       struct abm *abm = core_dc->res_pool->abm;
+
+       if ((abm == NULL) || (abm->funcs->set_backlight_level == NULL))
+               return false;
+
+       abm->funcs->set_abm_immediate_disable(abm);
+
+       return true;
+}
+
 bool dc_link_set_psr_enable(const struct dc_link *link, bool enable, bool wait)
 {
        struct dc  *core_dc = link->ctx->dc;
index fb4d9eafdc6e20b96fe66c0bbde8624293b2cf12..dc34515ef01fd2f25be758c482b0cf8c853b8d7c 100644 (file)
@@ -132,6 +132,8 @@ static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_
 bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level,
                uint32_t frame_ramp, const struct dc_stream_state *stream);
 
+bool dc_link_set_abm_disable(const struct dc_link *dc_link);
+
 bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable, bool wait);
 
 bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
index 444558ca653393326539aec1ba3a5f2c0c0ab8d4..162f6a6c4208fc38850d074bb6c6c83f2f539890 100644 (file)
@@ -735,6 +735,8 @@ static void dce110_stream_encoder_update_hdmi_info_packets(
                if (info_frame->avi.valid) {
                        const uint32_t *content =
                                (const uint32_t *) &info_frame->avi.sb[0];
+                       /*we need turn on clock before programming AFMT block*/
+                       REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
 
                        REG_WRITE(AFMT_AVI_INFO0, content[0]);
 
index 775d3bf0bd3956dfeed77c7b6718ac4635bba093..9150d26944508e4a91ec5d16af7cb2d6fa3b589e 100644 (file)
@@ -102,6 +102,43 @@ static uint32_t align_to_chunks_number_per_line(uint32_t pixels)
        return 256 * ((pixels + 255) / 256);
 }
 
+static void reset_lb_on_vblank(struct dc_context *ctx)
+{
+       uint32_t value, frame_count;
+       uint32_t retry = 0;
+       uint32_t status_pos =
+                       dm_read_reg(ctx, mmCRTC_STATUS_POSITION);
+
+
+       /* Only if CRTC is enabled and counter is moving we wait for one frame. */
+       if (status_pos != dm_read_reg(ctx, mmCRTC_STATUS_POSITION)) {
+               /* Resetting LB on VBlank */
+               value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL);
+               set_reg_field_value(value, 3, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL);
+               set_reg_field_value(value, 1, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2);
+               dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value);
+
+               frame_count = dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT);
+
+
+               for (retry = 100; retry > 0; retry--) {
+                       if (frame_count != dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT))
+                               break;
+                       msleep(1);
+               }
+               if (!retry)
+                       dm_error("Frame count did not increase for 100ms.\n");
+
+               /* Resetting LB on VBlank */
+               value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL);
+               set_reg_field_value(value, 2, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL);
+               set_reg_field_value(value, 0, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2);
+               dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value);
+
+       }
+
+}
+
 static void wait_for_fbc_state_changed(
        struct dce110_compressor *cp110,
        bool enabled)
@@ -232,19 +269,23 @@ void dce110_compressor_disable_fbc(struct compressor *compressor)
 {
        struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor);
 
-       if (compressor->options.bits.FBC_SUPPORT &&
-               dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) {
-               uint32_t reg_data;
-               /* Turn off compression */
-               reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL);
-               set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
-               dm_write_reg(compressor->ctx, mmFBC_CNTL, reg_data);
-
-               /* Reset enum controller_id to undefined */
-               compressor->attached_inst = 0;
-               compressor->is_enabled = false;
-
-               wait_for_fbc_state_changed(cp110, false);
+       if (compressor->options.bits.FBC_SUPPORT) {
+               if (dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) {
+                       uint32_t reg_data;
+                       /* Turn off compression */
+                       reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL);
+                       set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
+                       dm_write_reg(compressor->ctx, mmFBC_CNTL, reg_data);
+
+                       /* Reset enum controller_id to undefined */
+                       compressor->attached_inst = 0;
+                       compressor->is_enabled = false;
+
+                       wait_for_fbc_state_changed(cp110, false);
+               }
+
+               /* Sync line buffer  - dce100/110 only*/
+               reset_lb_on_vblank(compressor->ctx);
        }
 }
 
index 30dd62f0f5fa413c7e1e8376a73c964ac504f4f5..d0575999f17282a97f1c1ecffc0fcae85c5f7e2a 100644 (file)
@@ -453,10 +453,13 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
 
        } else {
                /* 10 segments
-                * segment is from 2^-10 to 2^0
+                * segment is from 2^-10 to 2^1
+                * We include an extra segment for range [2^0, 2^1). This is to
+                * ensure that colors with normalized values of 1 don't miss the
+                * LUT.
                 */
                region_start = -10;
-               region_end = 0;
+               region_end = 1;
 
                seg_distr[0] = 4;
                seg_distr[1] = 4;
@@ -468,7 +471,7 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
                seg_distr[7] = 4;
                seg_distr[8] = 4;
                seg_distr[9] = 4;
-               seg_distr[10] = -1;
+               seg_distr[10] = 0;
                seg_distr[11] = -1;
                seg_distr[12] = -1;
                seg_distr[13] = -1;
@@ -1016,8 +1019,10 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
        struct dc_stream_state *stream = pipe_ctx->stream;
        struct dc_link *link = stream->sink->link;
 
-       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP)
+       if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
                link->dc->hwss.edp_backlight_control(link, false);
+               dc_link_set_abm_disable(link);
+       }
 
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
                pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
index e415d2c097a70244ea26bbee949014623f48e7fc..48d0e6bd05088c0726c2d78d61f72820ef3b830e 100644 (file)
@@ -140,6 +140,10 @@ static struct radeon_px_quirk radeon_px_quirk_list[] = {
         * https://bugs.freedesktop.org/show_bug.cgi?id=101491
         */
        { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX },
+       /* Asus K73TK laptop with AMD A6-3420M APU and Radeon 7670m GPU
+        * https://bugzilla.kernel.org/show_bug.cgi?id=51381#c52
+        */
+       { PCI_VENDOR_ID_ATI, 0x6840, 0x1043, 0x2123, RADEON_PX_QUIRK_DISABLE_PX },
        { 0, 0, 0, 0, 0 },
 };