drm/amd/display: move wm ranges reporting to end of init hw
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn10 / dcn10_hw_sequencer.c
index 2d50cfc..eb91432 100644 (file)
@@ -670,6 +670,10 @@ static void dcn10_bios_golden_init(struct dc *dc)
        int i;
        bool allow_self_fresh_force_enable = true;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
+       if (dc->hwss.s0i3_golden_init_wa && dc->hwss.s0i3_golden_init_wa(dc))
+               return;
+#endif
        if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled)
                allow_self_fresh_force_enable =
                                dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub);
@@ -828,11 +832,23 @@ static void dcn10_reset_back_end_for_pipe(
        if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
                /* DPMS may already disable */
                if (!pipe_ctx->stream->dpms_off)
-                       core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
-               else if (pipe_ctx->stream_res.audio) {
-                       dc->hwss.disable_audio_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
+                       core_link_disable_stream(pipe_ctx);
+               else if (pipe_ctx->stream_res.audio)
+                       dc->hwss.disable_audio_stream(pipe_ctx);
+
+               if (pipe_ctx->stream_res.audio) {
+                       /*disable az_endpoint*/
+                       pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+
+                       /*free audio*/
+                       if (dc->caps.dynamic_audio == true) {
+                               /*we have to dynamic arbitrate the audio endpoints*/
+                               /*we free the resource, need reset is_audio_acquired*/
+                               update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
+                                               pipe_ctx->stream_res.audio, false);
+                               pipe_ctx->stream_res.audio = NULL;
+                       }
                }
-
        }
 
        /* by upper caller loop, parent pipe: pipe0, will be reset last.
@@ -1197,34 +1213,34 @@ static void dcn10_init_hw(struct dc *dc)
                return;
        }
 
-       if (!dcb->funcs->is_accelerated_mode(dcb)) {
-               dc->hwss.bios_golden_init(dc);
-               if (dc->ctx->dc_bios->fw_info_valid) {
-                       res_pool->ref_clocks.xtalin_clock_inKhz =
-                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
-
-                       if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
-                               if (res_pool->dccg && res_pool->hubbub) {
-
-                                       (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-                                                       dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
-                                                       &res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-                                       (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-                                                       res_pool->ref_clocks.dccg_ref_clock_inKhz,
-                                                       &res_pool->ref_clocks.dchub_ref_clock_inKhz);
-                               } else {
-                                       // Not all ASICs have DCCG sw component
-                                       res_pool->ref_clocks.dccg_ref_clock_inKhz =
-                                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-                                       res_pool->ref_clocks.dchub_ref_clock_inKhz =
-                                                       res_pool->ref_clocks.xtalin_clock_inKhz;
-                               }
-                       }
-               } else
-                       ASSERT_CRITICAL(false);
+       if (!dcb->funcs->is_accelerated_mode(dcb))
                dc->hwss.disable_vga(dc->hwseq);
-       }
+
+       dc->hwss.bios_golden_init(dc);
+       if (dc->ctx->dc_bios->fw_info_valid) {
+               res_pool->ref_clocks.xtalin_clock_inKhz =
+                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
+
+               if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+                       if (res_pool->dccg && res_pool->hubbub) {
+
+                               (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+                                               dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
+                                               &res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+                               (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+                                               res_pool->ref_clocks.dccg_ref_clock_inKhz,
+                                               &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+                       } else {
+                               // Not all ASICs have DCCG sw component
+                               res_pool->ref_clocks.dccg_ref_clock_inKhz =
+                                               res_pool->ref_clocks.xtalin_clock_inKhz;
+                               res_pool->ref_clocks.dchub_ref_clock_inKhz =
+                                               res_pool->ref_clocks.xtalin_clock_inKhz;
+                       }
+               }
+       } else
+               ASSERT_CRITICAL(false);
 
        for (i = 0; i < dc->link_count; i++) {
                /* Power up AND update implementation according to the
@@ -1256,19 +1272,8 @@ static void dcn10_init_hw(struct dc *dc)
         */
        if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
                dc->hwss.init_pipes(dc, dc->current_state);
-               for (i = 0; i < res_pool->pipe_count; i++) {
-                       struct hubp *hubp = res_pool->hubps[i];
-                       struct dpp *dpp = res_pool->dpps[i];
-
-                       hubp->funcs->hubp_init(hubp);
-                       res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
-                       dc->hwss.plane_atomic_power_down(dc, dpp, hubp);
-               }
-
-               apply_DEGVIDCN10_253_wa(dc);
        }
 
-
        for (i = 0; i < res_pool->audio_count; i++) {
                struct audio *audio = res_pool->audios[i];
 
@@ -1299,6 +1304,10 @@ static void dcn10_init_hw(struct dc *dc)
        }
 
        dc->hwss.enable_power_gating_plane(dc->hwseq, true);
+
+       if (dc->clk_mgr->funcs->notify_wm_ranges)
+               dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
 }
 
 static void dcn10_reset_hw_ctx_wrap(
@@ -1451,15 +1460,15 @@ static void log_tf(struct dc_context *ctx,
        DC_LOG_ALL_TF_CHANNELS("Logging all channels...");
 
        for (i = 0; i < hw_points_num; i++) {
-               DC_LOG_GAMMA("R %d %llu\n", i, tf->tf_pts.red[i].value);
-               DC_LOG_ALL_TF_CHANNELS("G %d, %llu\n", i, tf->tf_pts.green[i].value);
-               DC_LOG_ALL_TF_CHANNELS("B %d, %llu\n", i, tf->tf_pts.blue[i].value);
+               DC_LOG_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value);
+               DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value);
+               DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value);
        }
 
        for (i = hw_points_num; i < MAX_NUM_HW_POINTS; i++) {
-               DC_LOG_ALL_GAMMA("R %d %llu\n", i, tf->tf_pts.red[i].value);
-               DC_LOG_ALL_TF_CHANNELS("G %d %llu\n", i, tf->tf_pts.green[i].value);
-               DC_LOG_ALL_TF_CHANNELS("B %d %llu\n", i, tf->tf_pts.blue[i].value);
+               DC_LOG_ALL_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value);
+               DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value);
+               DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value);
        }
 }
 
@@ -1491,9 +1500,12 @@ dcn10_set_output_transfer_func(struct pipe_ctx *pipe_ctx,
        } else
                dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS);
 
-       log_tf(stream->ctx,
-                       stream->out_transfer_func,
-                       dpp->regamma_params.hw_points_num);
+       if (stream != NULL && stream->ctx != NULL &&
+                       stream->out_transfer_func != NULL) {
+               log_tf(stream->ctx,
+                               stream->out_transfer_func,
+                               dpp->regamma_params.hw_points_num);
+       }
 
        return true;
 }
@@ -2300,8 +2312,7 @@ void update_dchubp_dpp(
                        dc->res_pool->dccg->funcs->update_dpp_dto(
                                        dc->res_pool->dccg,
                                        dpp->inst,
-                                       pipe_ctx->plane_res.bw.dppclk_khz,
-                                       false);
+                                       pipe_ctx->plane_res.bw.dppclk_khz);
                else
                        dc->clk_mgr->clks.dppclk_khz = should_divided_by_2 ?
                                                dc->clk_mgr->clks.dispclk_khz / 2 :
@@ -2508,8 +2519,10 @@ static void program_all_pipe_in_tree(
                pipe_ctx->stream_res.tg->funcs->set_vtg_params(
                                pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
 
-               dc->hwss.blank_pixel_data(dc, pipe_ctx, blank);
+               if (dc->hwss.setup_vupdate_interrupt)
+                       dc->hwss.setup_vupdate_interrupt(pipe_ctx);
 
+               dc->hwss.blank_pixel_data(dc, pipe_ctx, blank);
        }
 
        if (pipe_ctx->plane_state != NULL)
@@ -2537,7 +2550,7 @@ struct pipe_ctx *find_top_pipe_for_stream(
                if (pipe_ctx->stream != stream)
                        continue;
 
-               if (!pipe_ctx->top_pipe)
+               if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe)
                        return pipe_ctx;
        }
        return NULL;
@@ -2743,7 +2756,8 @@ static void dcn10_optimize_bandwidth(
 }
 
 static void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
-               int num_pipes, int vmin, int vmax)
+               int num_pipes, unsigned int vmin, unsigned int vmax,
+               unsigned int vmid, unsigned int vmid_frame_number)
 {
        int i = 0;
        struct drr_params params = {0};
@@ -2752,6 +2766,8 @@ static void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
 
        params.vertical_total_max = vmax;
        params.vertical_total_min = vmin;
+       params.vertical_total_mid = vmid;
+       params.vertical_total_mid_frame_num = vmid_frame_number;
 
        /* TODO: If multiple pipes are to be supported, you need
         * some GSL stuff. Static screen triggers may be programmed differently
@@ -2972,6 +2988,40 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
                        == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
                pos_cpy.enable = false;
 
+       // Swap axis and mirror horizontally
+       if (param.rotation == ROTATION_ANGLE_90) {
+               uint32_t temp_x = pos_cpy.x;
+               pos_cpy.x = pipe_ctx->plane_res.scl_data.viewport.width -
+                               (pos_cpy.y - pipe_ctx->plane_res.scl_data.viewport.x) + pipe_ctx->plane_res.scl_data.viewport.x;
+               pos_cpy.y = temp_x;
+       }
+       // Swap axis and mirror vertically
+       else if (param.rotation == ROTATION_ANGLE_270) {
+               uint32_t temp_y = pos_cpy.y;
+               if (pos_cpy.x >  pipe_ctx->plane_res.scl_data.viewport.height) {
+                       pos_cpy.x = pos_cpy.x - pipe_ctx->plane_res.scl_data.viewport.height;
+                       pos_cpy.y = pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.x;
+               } else {
+                       pos_cpy.y = 2 * pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.x;
+               }
+               pos_cpy.x = temp_y;
+       }
+       // Mirror horizontally and vertically
+       else if (param.rotation == ROTATION_ANGLE_180) {
+               if (pos_cpy.x >= pipe_ctx->plane_res.scl_data.viewport.width + pipe_ctx->plane_res.scl_data.viewport.x) {
+                       pos_cpy.x = 2 * pipe_ctx->plane_res.scl_data.viewport.width
+                                       - pos_cpy.x + 2 * pipe_ctx->plane_res.scl_data.viewport.x;
+               } else {
+                       uint32_t temp_x = pos_cpy.x;
+                       pos_cpy.x = 2 * pipe_ctx->plane_res.scl_data.viewport.x - pos_cpy.x;
+                       if (temp_x >= pipe_ctx->plane_res.scl_data.viewport.x + (int)hubp->curs_attr.width
+                                       || pos_cpy.x <= (int)hubp->curs_attr.width + pipe_ctx->plane_state->src_rect.x) {
+                               pos_cpy.x = temp_x + pipe_ctx->plane_res.scl_data.viewport.width;
+                       }
+               }
+               pos_cpy.y = pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.y;
+       }
+
        hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
        dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width, hubp->curs_attr.height);
 }
@@ -2983,7 +3033,7 @@ static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
        pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
                        pipe_ctx->plane_res.hubp, attributes);
        pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
-               pipe_ctx->plane_res.dpp, attributes->color_format);
+               pipe_ctx->plane_res.dpp, attributes);
 }
 
 static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx)