diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce60')
6 files changed, 4 insertions, 2045 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce60/Makefile b/drivers/gpu/drm/amd/display/dc/dce60/Makefile index eede83ad91fa..824f73eb3326 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce60/Makefile @@ -25,8 +25,7 @@ CFLAGS_$(AMDDALPATH)/dc/dce60/dce60_resource.o = -Wno-override-init -DCE60 = dce60_timing_generator.o dce60_hw_sequencer.o \ - dce60_resource.o +DCE60 = dce60_timing_generator.o AMD_DAL_DCE60 = $(addprefix $(AMDDALPATH)/dc/dce60/,$(DCE60)) diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c deleted file mode 100644 index 1fdeef47e4dc..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#include "dm_services.h" -#include "dc.h" -#include "core_types.h" -#include "dce60_hw_sequencer.h" - -#include "dce/dce_hwseq.h" -#include "dce110/dce110_hwseq.h" -#include "dce100/dce100_hwseq.h" - -/* include DCE6 register header files */ -#include "dce/dce_6_0_d.h" -#include "dce/dce_6_0_sh_mask.h" - -#define DC_LOGGER_INIT() - -/******************************************************************************* - * Private definitions - ******************************************************************************/ - -/***************************PIPE_CONTROL***********************************/ - -/* - * Check if FBC can be enabled - */ -static bool dce60_should_enable_fbc(struct dc *dc, - struct dc_state *context, - uint32_t *pipe_idx) -{ - uint32_t i; - struct pipe_ctx *pipe_ctx = NULL; - struct resource_context *res_ctx = &context->res_ctx; - unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; - - - ASSERT(dc->fbc_compressor); - - /* FBC memory should be allocated */ - if (!dc->ctx->fbc_gpu_addr) - return false; - - /* Only supports single display */ - if (context->stream_count != 1) - return false; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - if (res_ctx->pipe_ctx[i].stream) { - - pipe_ctx = &res_ctx->pipe_ctx[i]; - - if (!pipe_ctx) - continue; - - /* fbc not applicable on underlay pipe */ - if (pipe_ctx->pipe_idx != underlay_idx) { - *pipe_idx = i; - break; - } - } - } - - if (i == dc->res_pool->pipe_count) - return false; - - if (!pipe_ctx->stream->link) - return false; - - /* Only supports eDP */ - if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP) - return false; - - /* PSR should not be enabled */ - if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled) - return false; - - /* Nothing to compress */ - if (!pipe_ctx->plane_state) - return false; - - /* Only for non-linear tiling */ - if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) - return false; - - return true; -} - -/* - * Enable FBC - */ -static void dce60_enable_fbc( - struct dc *dc, - struct dc_state *context) -{ - uint32_t pipe_idx = 0; - - if (dce60_should_enable_fbc(dc, context, &pipe_idx)) { - /* Program GRPH COMPRESSED ADDRESS and PITCH */ - struct compr_addr_and_pitch_params params = {0, 0, 0}; - struct compressor *compr = dc->fbc_compressor; - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; - - params.source_view_width = pipe_ctx->stream->timing.h_addressable; - params.source_view_height = pipe_ctx->stream->timing.v_addressable; - params.inst = pipe_ctx->stream_res.tg->inst; - compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; - - compr->funcs->surface_address_and_pitch(compr, ¶ms); - compr->funcs->set_fbc_invalidation_triggers(compr, 1); - - compr->funcs->enable_fbc(compr, ¶ms); - } -} - - -/******************************************************************************* - * Front End programming - ******************************************************************************/ - -static void dce60_set_default_colors(struct pipe_ctx *pipe_ctx) -{ - struct default_adjustment default_adjust = { 0 }; - - default_adjust.force_hw_default = false; - default_adjust.in_color_space = pipe_ctx->plane_state->color_space; - default_adjust.out_color_space = pipe_ctx->stream->output_color_space; - default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; - default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; - - /* display color depth */ - default_adjust.color_depth = - pipe_ctx->stream->timing.display_color_depth; - - /* Lb color depth */ - default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; - - pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( - pipe_ctx->plane_res.xfm, &default_adjust); -} - -/******************************************************************************* - * In order to turn on surface we will program - * CRTC - * - * DCE6 has no bottom_pipe and no Blender HW - * We need to set 'blank_target' to false in order to turn on the display - * - * |-----------|------------|---------| - * |curr pipe | set_blank | | - * |Surface |blank_target| CRCT | - * |visibility | argument | | - * |-----------|------------|---------| - * | off | true | blank | - * | on | false | unblank | - * |-----------|------------|---------| - * - ******************************************************************************/ -static void dce60_program_surface_visibility(const struct dc *dc, - struct pipe_ctx *pipe_ctx) -{ - bool blank_target = false; - - /* DCE6 has no bottom_pipe and no Blender HW */ - - if (!pipe_ctx->plane_state->visible) - blank_target = true; - - /* DCE6 skip dce_set_blender_mode() but then proceed to 'unblank' CRTC */ - pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); - -} - - -static void dce60_get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, - struct tg_color *color) -{ - uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4; - - switch (pipe_ctx->plane_res.scl_data.format) { - case PIXEL_FORMAT_ARGB8888: - /* set boarder color to red */ - color->color_r_cr = color_value; - break; - - case PIXEL_FORMAT_ARGB2101010: - /* set boarder color to blue */ - color->color_b_cb = color_value; - break; - case PIXEL_FORMAT_420BPP8: - /* set boarder color to green */ - color->color_g_y = color_value; - break; - case PIXEL_FORMAT_420BPP10: - /* set boarder color to yellow */ - color->color_g_y = color_value; - color->color_r_cr = color_value; - break; - case PIXEL_FORMAT_FP16: - /* set boarder color to white */ - color->color_r_cr = color_value; - color->color_b_cb = color_value; - color->color_g_y = color_value; - break; - default: - break; - } -} - -static void dce60_program_scaler(const struct dc *dc, - const struct pipe_ctx *pipe_ctx) -{ - struct tg_color color = {0}; - - /* DCE6 skips DCN TOFPGA check for transform_set_pixel_storage_depth == NULL */ - - if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) - dce60_get_surface_visual_confirm_color(pipe_ctx, &color); - else - color_space_to_black_color(dc, - pipe_ctx->stream->output_color_space, - &color); - - pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( - pipe_ctx->plane_res.xfm, - pipe_ctx->plane_res.scl_data.lb_params.depth, - &pipe_ctx->stream->bit_depth_params); - - if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) { - /* - * The way 420 is packed, 2 channels carry Y component, 1 channel - * alternate between Cb and Cr, so both channels need the pixel - * value for Y - */ - if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) - color.color_r_cr = color.color_g_y; - - pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( - pipe_ctx->stream_res.tg, - &color); - } - - pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, - &pipe_ctx->plane_res.scl_data); -} - -static void -dce60_program_front_end_for_pipe( - struct dc *dc, struct pipe_ctx *pipe_ctx) -{ - struct mem_input *mi = pipe_ctx->plane_res.mi; - struct dc_plane_state *plane_state = pipe_ctx->plane_state; - struct xfm_grph_csc_adjustment adjust; - struct out_csc_color_matrix tbl_entry; - unsigned int i; - struct dce_hwseq *hws = dc->hwseq; - - DC_LOGGER_INIT(); - memset(&tbl_entry, 0, sizeof(tbl_entry)); - - memset(&adjust, 0, sizeof(adjust)); - adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; - - dce_enable_fe_clock(dc->hwseq, mi->inst, true); - - dce60_set_default_colors(pipe_ctx); - if (pipe_ctx->stream->csc_color_matrix.enable_adjustment - == true) { - tbl_entry.color_space = - pipe_ctx->stream->output_color_space; - - for (i = 0; i < 12; i++) - tbl_entry.regval[i] = - pipe_ctx->stream->csc_color_matrix.matrix[i]; - - pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment - (pipe_ctx->plane_res.xfm, &tbl_entry); - } - - if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { - adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; - - for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) - adjust.temperature_matrix[i] = - pipe_ctx->stream->gamut_remap_matrix.matrix[i]; - } - - pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); - - pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; - - dce60_program_scaler(dc, pipe_ctx); - - mi->funcs->mem_input_program_surface_config( - mi, - plane_state->format, - &plane_state->tiling_info, - &plane_state->plane_size, - plane_state->rotation, - NULL, - false); - if (mi->funcs->set_blank) - mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); - - if (dc->config.gpu_vm_support) - mi->funcs->mem_input_program_pte_vm( - pipe_ctx->plane_res.mi, - plane_state->format, - &plane_state->tiling_info, - plane_state->rotation); - - /* Moved programming gamma from dc to hwss */ - if (pipe_ctx->plane_state->update_flags.bits.full_update || - pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || - pipe_ctx->plane_state->update_flags.bits.gamma_change) - hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); - - if (pipe_ctx->plane_state->update_flags.bits.full_update) - hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream); - - DC_LOG_SURFACE( - "Pipe:%d %p: addr hi:0x%x, " - "addr low:0x%x, " - "src: %d, %d, %d," - " %d; dst: %d, %d, %d, %d;" - "clip: %d, %d, %d, %d\n", - pipe_ctx->pipe_idx, - (void *) pipe_ctx->plane_state, - pipe_ctx->plane_state->address.grph.addr.high_part, - pipe_ctx->plane_state->address.grph.addr.low_part, - pipe_ctx->plane_state->src_rect.x, - pipe_ctx->plane_state->src_rect.y, - pipe_ctx->plane_state->src_rect.width, - pipe_ctx->plane_state->src_rect.height, - pipe_ctx->plane_state->dst_rect.x, - pipe_ctx->plane_state->dst_rect.y, - pipe_ctx->plane_state->dst_rect.width, - pipe_ctx->plane_state->dst_rect.height, - pipe_ctx->plane_state->clip_rect.x, - pipe_ctx->plane_state->clip_rect.y, - pipe_ctx->plane_state->clip_rect.width, - pipe_ctx->plane_state->clip_rect.height); - - DC_LOG_SURFACE( - "Pipe %d: width, height, x, y\n" - "viewport:%d, %d, %d, %d\n" - "recout: %d, %d, %d, %d\n", - pipe_ctx->pipe_idx, - pipe_ctx->plane_res.scl_data.viewport.width, - pipe_ctx->plane_res.scl_data.viewport.height, - pipe_ctx->plane_res.scl_data.viewport.x, - pipe_ctx->plane_res.scl_data.viewport.y, - pipe_ctx->plane_res.scl_data.recout.width, - pipe_ctx->plane_res.scl_data.recout.height, - pipe_ctx->plane_res.scl_data.recout.x, - pipe_ctx->plane_res.scl_data.recout.y); -} - -static void dce60_apply_ctx_for_surface( - struct dc *dc, - const struct dc_stream_state *stream, - int num_planes, - struct dc_state *context) -{ - int i; - - if (num_planes == 0) - return; - - if (dc->fbc_compressor) - dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - - if (pipe_ctx->stream != stream) - continue; - - /* Need to allocate mem before program front end for Fiji */ - pipe_ctx->plane_res.mi->funcs->allocate_mem_input( - pipe_ctx->plane_res.mi, - pipe_ctx->stream->timing.h_total, - pipe_ctx->stream->timing.v_total, - pipe_ctx->stream->timing.pix_clk_100hz / 10, - context->stream_count); - - dce60_program_front_end_for_pipe(dc, pipe_ctx); - - dc->hwss.update_plane_addr(dc, pipe_ctx); - - dce60_program_surface_visibility(dc, pipe_ctx); - - } - - if (dc->fbc_compressor) - dce60_enable_fbc(dc, context); -} - -void dce60_hw_sequencer_construct(struct dc *dc) -{ - dce110_hw_sequencer_construct(dc); - - dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating; - dc->hwss.apply_ctx_for_surface = dce60_apply_ctx_for_surface; - dc->hwss.cursor_lock = dce60_pipe_control_lock; - dc->hwss.pipe_control_lock = dce60_pipe_control_lock; - dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth; - dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth; -} - diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.h deleted file mode 100644 index f3b2d8b60d5b..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#ifndef __DC_HWSS_DCE60_H__ -#define __DC_HWSS_DCE60_H__ - -#include "core_types.h" -#include "hw_sequencer_private.h" - -struct dc; - -void dce60_hw_sequencer_construct(struct dc *dc); - -#endif /* __DC_HWSS_DCE60_H__ */ - diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c deleted file mode 100644 index 8db9f7514466..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c +++ /dev/null @@ -1,1526 +0,0 @@ -/* - * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#include <linux/slab.h> - -#include "dce/dce_6_0_d.h" -#include "dce/dce_6_0_sh_mask.h" - -#include "dm_services.h" - -#include "link_encoder.h" -#include "stream_encoder.h" - -#include "resource.h" -#include "include/irq_service_interface.h" -#include "irq/dce60/irq_service_dce60.h" -#include "dce110/dce110_timing_generator.h" -#include "dce110/dce110_resource.h" -#include "dce60/dce60_timing_generator.h" -#include "dce/dce_mem_input.h" -#include "dce/dce_link_encoder.h" -#include "dce/dce_stream_encoder.h" -#include "dce/dce_ipp.h" -#include "dce/dce_transform.h" -#include "dce/dce_opp.h" -#include "dce/dce_clock_source.h" -#include "dce/dce_audio.h" -#include "dce/dce_hwseq.h" -#include "dce60/dce60_hw_sequencer.h" -#include "dce100/dce100_resource.h" -#include "dce/dce_panel_cntl.h" - -#include "reg_helper.h" - -#include "dce/dce_dmcu.h" -#include "dce/dce_aux.h" -#include "dce/dce_abm.h" -#include "dce/dce_i2c.h" -/* TODO remove this include */ - -#include "dce60_resource.h" - -#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT -#include "gmc/gmc_6_0_d.h" -#include "gmc/gmc_6_0_sh_mask.h" -#endif - -#ifndef mmDP_DPHY_INTERNAL_CTRL -#define mmDP_DPHY_INTERNAL_CTRL 0x1CDE -#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x1CDE -#define mmDP1_DP_DPHY_INTERNAL_CTRL 0x1FDE -#define mmDP2_DP_DPHY_INTERNAL_CTRL 0x42DE -#define mmDP3_DP_DPHY_INTERNAL_CTRL 0x45DE -#define mmDP4_DP_DPHY_INTERNAL_CTRL 0x48DE -#define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4BDE -#endif - - -#ifndef mmBIOS_SCRATCH_2 - #define mmBIOS_SCRATCH_2 0x05CB - #define mmBIOS_SCRATCH_3 0x05CC - #define mmBIOS_SCRATCH_6 0x05CF -#endif - -#ifndef mmDP_DPHY_FAST_TRAINING - #define mmDP_DPHY_FAST_TRAINING 0x1CCE - #define mmDP0_DP_DPHY_FAST_TRAINING 0x1CCE - #define mmDP1_DP_DPHY_FAST_TRAINING 0x1FCE - #define mmDP2_DP_DPHY_FAST_TRAINING 0x42CE - #define mmDP3_DP_DPHY_FAST_TRAINING 0x45CE - #define mmDP4_DP_DPHY_FAST_TRAINING 0x48CE - #define mmDP5_DP_DPHY_FAST_TRAINING 0x4BCE -#endif - - -#ifndef mmHPD_DC_HPD_CONTROL - #define mmHPD_DC_HPD_CONTROL 0x189A - #define mmHPD0_DC_HPD_CONTROL 0x189A - #define mmHPD1_DC_HPD_CONTROL 0x18A2 - #define mmHPD2_DC_HPD_CONTROL 0x18AA - #define mmHPD3_DC_HPD_CONTROL 0x18B2 - #define mmHPD4_DC_HPD_CONTROL 0x18BA - #define mmHPD5_DC_HPD_CONTROL 0x18C2 -#endif - -#define DCE11_DIG_FE_CNTL 0x4a00 -#define DCE11_DIG_BE_CNTL 0x4a47 -#define DCE11_DP_SEC 0x4ac3 - -static const struct dce110_timing_generator_offsets dce60_tg_offsets[] = { - { - .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL), - .dcp = (mmGRPH_CONTROL - mmGRPH_CONTROL), - .dmif = (mmDMIF_PG0_DPG_PIPE_ARBITRATION_CONTROL3 - - mmDPG_PIPE_ARBITRATION_CONTROL3), - }, - { - .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL), - .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL), - .dmif = (mmDMIF_PG1_DPG_PIPE_ARBITRATION_CONTROL3 - - mmDPG_PIPE_ARBITRATION_CONTROL3), - }, - { - .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL), - .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL), - .dmif = (mmDMIF_PG2_DPG_PIPE_ARBITRATION_CONTROL3 - - mmDPG_PIPE_ARBITRATION_CONTROL3), - }, - { - .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL), - .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL), - .dmif = (mmDMIF_PG3_DPG_PIPE_ARBITRATION_CONTROL3 - - mmDPG_PIPE_ARBITRATION_CONTROL3), - }, - { - .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL), - .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL), - .dmif = (mmDMIF_PG4_DPG_PIPE_ARBITRATION_CONTROL3 - - mmDPG_PIPE_ARBITRATION_CONTROL3), - }, - { - .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL), - .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL), - .dmif = (mmDMIF_PG5_DPG_PIPE_ARBITRATION_CONTROL3 - - mmDPG_PIPE_ARBITRATION_CONTROL3), - } -}; - -/* set register offset */ -#define SR(reg_name)\ - .reg_name = mm ## reg_name - -/* set register offset with instance */ -#define SRI(reg_name, block, id)\ - .reg_name = mm ## block ## id ## _ ## reg_name - -#define ipp_regs(id)\ -[id] = {\ - IPP_COMMON_REG_LIST_DCE_BASE(id)\ -} - -static const struct dce_ipp_registers ipp_regs[] = { - ipp_regs(0), - ipp_regs(1), - ipp_regs(2), - ipp_regs(3), - ipp_regs(4), - ipp_regs(5) -}; - -static const struct dce_ipp_shift ipp_shift = { - IPP_DCE60_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) -}; - -static const struct dce_ipp_mask ipp_mask = { - IPP_DCE60_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) -}; - -#define transform_regs(id)\ -[id] = {\ - XFM_COMMON_REG_LIST_DCE60(id)\ -} - -static const struct dce_transform_registers xfm_regs[] = { - transform_regs(0), - transform_regs(1), - transform_regs(2), - transform_regs(3), - transform_regs(4), - transform_regs(5) -}; - -static const struct dce_transform_shift xfm_shift = { - XFM_COMMON_MASK_SH_LIST_DCE60(__SHIFT) -}; - -static const struct dce_transform_mask xfm_mask = { - XFM_COMMON_MASK_SH_LIST_DCE60(_MASK) -}; - -#define aux_regs(id)\ -[id] = {\ - AUX_REG_LIST(id)\ -} - -static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = { - aux_regs(0), - aux_regs(1), - aux_regs(2), - aux_regs(3), - aux_regs(4), - aux_regs(5) -}; - -#define hpd_regs(id)\ -[id] = {\ - HPD_REG_LIST(id)\ -} - -static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = { - hpd_regs(0), - hpd_regs(1), - hpd_regs(2), - hpd_regs(3), - hpd_regs(4), - hpd_regs(5) -}; - -#define link_regs(id)\ -[id] = {\ - LE_DCE60_REG_LIST(id)\ -} - -static const struct dce110_link_enc_registers link_enc_regs[] = { - link_regs(0), - link_regs(1), - link_regs(2), - link_regs(3), - link_regs(4), - link_regs(5) -}; - -#define stream_enc_regs(id)\ -[id] = {\ - SE_COMMON_REG_LIST_DCE_BASE(id),\ - .AFMT_CNTL = 0,\ -} - -static const struct dce110_stream_enc_registers stream_enc_regs[] = { - stream_enc_regs(0), - stream_enc_regs(1), - stream_enc_regs(2), - stream_enc_regs(3), - stream_enc_regs(4), - stream_enc_regs(5) -}; - -static const struct dce_stream_encoder_shift se_shift = { - SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT) -}; - -static const struct dce_stream_encoder_mask se_mask = { - SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK) -}; - -static const struct dce_panel_cntl_registers panel_cntl_regs[] = { - { DCE_PANEL_CNTL_REG_LIST() } -}; - -static const struct dce_panel_cntl_shift panel_cntl_shift = { - DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT) -}; - -static const struct dce_panel_cntl_mask panel_cntl_mask = { - DCE_PANEL_CNTL_MASK_SH_LIST(_MASK) -}; - -#define opp_regs(id)\ -[id] = {\ - OPP_DCE_60_REG_LIST(id),\ -} - -static const struct dce_opp_registers opp_regs[] = { - opp_regs(0), - opp_regs(1), - opp_regs(2), - opp_regs(3), - opp_regs(4), - opp_regs(5) -}; - -static const struct dce_opp_shift opp_shift = { - OPP_COMMON_MASK_SH_LIST_DCE_60(__SHIFT) -}; - -static const struct dce_opp_mask opp_mask = { - OPP_COMMON_MASK_SH_LIST_DCE_60(_MASK) -}; - -static const struct dce110_aux_registers_shift aux_shift = { - DCE10_AUX_MASK_SH_LIST(__SHIFT) -}; - -static const struct dce110_aux_registers_mask aux_mask = { - DCE10_AUX_MASK_SH_LIST(_MASK) -}; - -#define aux_engine_regs(id)\ -[id] = {\ - AUX_COMMON_REG_LIST(id), \ - .AUX_RESET_MASK = 0 \ -} - -static const struct dce110_aux_registers aux_engine_regs[] = { - aux_engine_regs(0), - aux_engine_regs(1), - aux_engine_regs(2), - aux_engine_regs(3), - aux_engine_regs(4), - aux_engine_regs(5) -}; - -#define audio_regs(id)\ -[id] = {\ - AUD_COMMON_REG_LIST(id)\ -} - -static const struct dce_audio_registers audio_regs[] = { - audio_regs(0), - audio_regs(1), - audio_regs(2), - audio_regs(3), - audio_regs(4), - audio_regs(5), -}; - -static const struct dce_audio_shift audio_shift = { - AUD_DCE60_MASK_SH_LIST(__SHIFT) -}; - -static const struct dce_audio_mask audio_mask = { - AUD_DCE60_MASK_SH_LIST(_MASK) -}; - -#define clk_src_regs(id)\ -[id] = {\ - CS_COMMON_REG_LIST_DCE_80(id),\ -} - - -static const struct dce110_clk_src_regs clk_src_regs[] = { - clk_src_regs(0), - clk_src_regs(1), - clk_src_regs(2) -}; - -static const struct dce110_clk_src_shift cs_shift = { - CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) -}; - -static const struct dce110_clk_src_mask cs_mask = { - CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) -}; - -static const struct bios_registers bios_regs = { - .BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3, - .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 -}; - -static const struct resource_caps res_cap = { - .num_timing_generator = 6, - .num_audio = 6, - .num_stream_encoder = 6, - .num_pll = 2, - .num_ddc = 6, -}; - -static const struct resource_caps res_cap_61 = { - .num_timing_generator = 4, - .num_audio = 6, - .num_stream_encoder = 6, - .num_pll = 3, - .num_ddc = 6, -}; - -static const struct resource_caps res_cap_64 = { - .num_timing_generator = 2, - .num_audio = 2, - .num_stream_encoder = 2, - .num_pll = 2, - .num_ddc = 2, -}; - -static const struct dc_plane_cap plane_cap = { - .type = DC_PLANE_TYPE_DCE_RGB, - - .pixel_format_support = { - .argb8888 = true, - .nv12 = false, - .fp16 = false - }, - - .max_upscale_factor = { - .argb8888 = 16000, - .nv12 = 1, - .fp16 = 1 - }, - - .max_downscale_factor = { - .argb8888 = 250, - .nv12 = 1, - .fp16 = 1 - } -}; - -static const struct dce_dmcu_registers dmcu_regs = { - DMCU_DCE60_REG_LIST() -}; - -static const struct dce_dmcu_shift dmcu_shift = { - DMCU_MASK_SH_LIST_DCE60(__SHIFT) -}; - -static const struct dce_dmcu_mask dmcu_mask = { - DMCU_MASK_SH_LIST_DCE60(_MASK) -}; -static const struct dce_abm_registers abm_regs = { - ABM_DCE110_COMMON_REG_LIST() -}; - -static const struct dce_abm_shift abm_shift = { - ABM_MASK_SH_LIST_DCE110(__SHIFT) -}; - -static const struct dce_abm_mask abm_mask = { - ABM_MASK_SH_LIST_DCE110(_MASK) -}; - -#define CTX ctx -#define REG(reg) mm ## reg - -#ifndef mmCC_DC_HDMI_STRAPS -#define mmCC_DC_HDMI_STRAPS 0x1918 -#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40 -#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6 -#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700 -#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8 -#endif - -static int map_transmitter_id_to_phy_instance( - enum transmitter transmitter) -{ - switch (transmitter) { - case TRANSMITTER_UNIPHY_A: - return 0; - case TRANSMITTER_UNIPHY_B: - return 1; - case TRANSMITTER_UNIPHY_C: - return 2; - case TRANSMITTER_UNIPHY_D: - return 3; - case TRANSMITTER_UNIPHY_E: - return 4; - case TRANSMITTER_UNIPHY_F: - return 5; - case TRANSMITTER_UNIPHY_G: - return 6; - default: - ASSERT(0); - return 0; - } -} - -static void read_dce_straps( - struct dc_context *ctx, - struct resource_straps *straps) -{ - REG_GET_2(CC_DC_HDMI_STRAPS, - HDMI_DISABLE, &straps->hdmi_disable, - AUDIO_STREAM_NUMBER, &straps->audio_stream_number); - - REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio); -} - -static struct audio *create_audio( - struct dc_context *ctx, unsigned int inst) -{ - return dce60_audio_create(ctx, inst, - &audio_regs[inst], &audio_shift, &audio_mask); -} - -static struct timing_generator *dce60_timing_generator_create( - struct dc_context *ctx, - uint32_t instance, - const struct dce110_timing_generator_offsets *offsets) -{ - struct dce110_timing_generator *tg110 = - kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); - - if (!tg110) - return NULL; - - dce60_timing_generator_construct(tg110, ctx, instance, offsets); - return &tg110->base; -} - -static struct output_pixel_processor *dce60_opp_create( - struct dc_context *ctx, - uint32_t inst) -{ - struct dce110_opp *opp = - kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); - - if (!opp) - return NULL; - - dce60_opp_construct(opp, - ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask); - return &opp->base; -} - -static struct dce_aux *dce60_aux_engine_create( - struct dc_context *ctx, - uint32_t inst) -{ - struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); - - if (!aux_engine) - return NULL; - - dce110_aux_engine_construct(aux_engine, ctx, inst, - SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, - &aux_engine_regs[inst], - &aux_mask, - &aux_shift, - ctx->dc->caps.extended_aux_timeout_support); - - return &aux_engine->base; -} -#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) } - -static const struct dce_i2c_registers i2c_hw_regs[] = { - i2c_inst_regs(1), - i2c_inst_regs(2), - i2c_inst_regs(3), - i2c_inst_regs(4), - i2c_inst_regs(5), - i2c_inst_regs(6), -}; - -static const struct dce_i2c_shift i2c_shifts = { - I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) -}; - -static const struct dce_i2c_mask i2c_masks = { - I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) -}; - -static struct dce_i2c_hw *dce60_i2c_hw_create( - struct dc_context *ctx, - uint32_t inst) -{ - struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); - - if (!dce_i2c_hw) - return NULL; - - dce_i2c_hw_construct(dce_i2c_hw, ctx, inst, - &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); - - return dce_i2c_hw; -} - -static struct dce_i2c_sw *dce60_i2c_sw_create( - struct dc_context *ctx) -{ - struct dce_i2c_sw *dce_i2c_sw = - kzalloc(sizeof(struct dce_i2c_sw), GFP_KERNEL); - - if (!dce_i2c_sw) - return NULL; - - dce_i2c_sw_construct(dce_i2c_sw, ctx); - - return dce_i2c_sw; -} -static struct stream_encoder *dce60_stream_encoder_create( - enum engine_id eng_id, - struct dc_context *ctx) -{ - struct dce110_stream_encoder *enc110 = - kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); - - if (!enc110) - return NULL; - - dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, - &stream_enc_regs[eng_id], - &se_shift, &se_mask); - return &enc110->base; -} - -#define SRII(reg_name, block, id)\ - .reg_name[id] = mm ## block ## id ## _ ## reg_name - -static const struct dce_hwseq_registers hwseq_reg = { - HWSEQ_DCE6_REG_LIST() -}; - -static const struct dce_hwseq_shift hwseq_shift = { - HWSEQ_DCE6_MASK_SH_LIST(__SHIFT) -}; - -static const struct dce_hwseq_mask hwseq_mask = { - HWSEQ_DCE6_MASK_SH_LIST(_MASK) -}; - -static struct dce_hwseq *dce60_hwseq_create( - struct dc_context *ctx) -{ - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); - - if (hws) { - hws->ctx = ctx; - hws->regs = &hwseq_reg; - hws->shifts = &hwseq_shift; - hws->masks = &hwseq_mask; - } - return hws; -} - -static const struct resource_create_funcs res_create_funcs = { - .read_dce_straps = read_dce_straps, - .create_audio = create_audio, - .create_stream_encoder = dce60_stream_encoder_create, - .create_hwseq = dce60_hwseq_create, -}; - -#define mi_inst_regs(id) { \ - MI_DCE6_REG_LIST(id), \ - .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \ -} -static const struct dce_mem_input_registers mi_regs[] = { - mi_inst_regs(0), - mi_inst_regs(1), - mi_inst_regs(2), - mi_inst_regs(3), - mi_inst_regs(4), - mi_inst_regs(5), -}; - -static const struct dce_mem_input_shift mi_shifts = { - MI_DCE6_MASK_SH_LIST(__SHIFT), - .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT -}; - -static const struct dce_mem_input_mask mi_masks = { - MI_DCE6_MASK_SH_LIST(_MASK), - .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK -}; - -static struct mem_input *dce60_mem_input_create( - struct dc_context *ctx, - uint32_t inst) -{ - struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), - GFP_KERNEL); - - if (!dce_mi) { - BREAK_TO_DEBUGGER(); - return NULL; - } - - dce60_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks); - dce_mi->wa.single_head_rdreq_dmif_limit = 2; - return &dce_mi->base; -} - -static void dce60_transform_destroy(struct transform **xfm) -{ - kfree(TO_DCE_TRANSFORM(*xfm)); - *xfm = NULL; -} - -static struct transform *dce60_transform_create( - struct dc_context *ctx, - uint32_t inst) -{ - struct dce_transform *transform = - kzalloc(sizeof(struct dce_transform), GFP_KERNEL); - - if (!transform) - return NULL; - - dce60_transform_construct(transform, ctx, inst, - &xfm_regs[inst], &xfm_shift, &xfm_mask); - transform->prescaler_on = false; - return &transform->base; -} - -static const struct encoder_feature_support link_enc_feature = { - .max_hdmi_deep_color = COLOR_DEPTH_121212, - .max_hdmi_pixel_clock = 297000, - .flags.bits.IS_HBR2_CAPABLE = true, - .flags.bits.IS_TPS3_CAPABLE = true -}; - -static struct link_encoder *dce60_link_encoder_create( - struct dc_context *ctx, - const struct encoder_init_data *enc_init_data) -{ - struct dce110_link_encoder *enc110 = - kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); - int link_regs_id; - - if (!enc110) - return NULL; - - link_regs_id = - map_transmitter_id_to_phy_instance(enc_init_data->transmitter); - - dce60_link_encoder_construct(enc110, - enc_init_data, - &link_enc_feature, - &link_enc_regs[link_regs_id], - &link_enc_aux_regs[enc_init_data->channel - 1], - &link_enc_hpd_regs[enc_init_data->hpd_source]); - return &enc110->base; -} - -static struct panel_cntl *dce60_panel_cntl_create(const struct panel_cntl_init_data *init_data) -{ - struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); - - if (!panel_cntl) - return NULL; - - dce_panel_cntl_construct(panel_cntl, - init_data, - &panel_cntl_regs[init_data->inst], - &panel_cntl_shift, - &panel_cntl_mask); - - return &panel_cntl->base; -} - -static struct clock_source *dce60_clock_source_create( - struct dc_context *ctx, - struct dc_bios *bios, - enum clock_source_id id, - const struct dce110_clk_src_regs *regs, - bool dp_clk_src) -{ - struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); - - if (!clk_src) - return NULL; - - if (dce110_clk_src_construct(clk_src, ctx, bios, id, - regs, &cs_shift, &cs_mask)) { - clk_src->base.dp_clk_src = dp_clk_src; - return &clk_src->base; - } - - kfree(clk_src); - BREAK_TO_DEBUGGER(); - return NULL; -} - -static void dce60_clock_source_destroy(struct clock_source **clk_src) -{ - kfree(TO_DCE110_CLK_SRC(*clk_src)); - *clk_src = NULL; -} - -static struct input_pixel_processor *dce60_ipp_create( - struct dc_context *ctx, uint32_t inst) -{ - struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); - - if (!ipp) { - BREAK_TO_DEBUGGER(); - return NULL; - } - - dce60_ipp_construct(ipp, ctx, inst, - &ipp_regs[inst], &ipp_shift, &ipp_mask); - return &ipp->base; -} - -static void dce60_resource_destruct(struct dce110_resource_pool *pool) -{ - unsigned int i; - - for (i = 0; i < pool->base.pipe_count; i++) { - if (pool->base.opps[i] != NULL) - dce110_opp_destroy(&pool->base.opps[i]); - - if (pool->base.transforms[i] != NULL) - dce60_transform_destroy(&pool->base.transforms[i]); - - if (pool->base.ipps[i] != NULL) - dce_ipp_destroy(&pool->base.ipps[i]); - - if (pool->base.mis[i] != NULL) { - kfree(TO_DCE_MEM_INPUT(pool->base.mis[i])); - pool->base.mis[i] = NULL; - } - - if (pool->base.timing_generators[i] != NULL) { - kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); - pool->base.timing_generators[i] = NULL; - } - } - - for (i = 0; i < pool->base.res_cap->num_ddc; i++) { - if (pool->base.engines[i] != NULL) - dce110_engine_destroy(&pool->base.engines[i]); - if (pool->base.hw_i2cs[i] != NULL) { - kfree(pool->base.hw_i2cs[i]); - pool->base.hw_i2cs[i] = NULL; - } - if (pool->base.sw_i2cs[i] != NULL) { - kfree(pool->base.sw_i2cs[i]); - pool->base.sw_i2cs[i] = NULL; - } - } - - for (i = 0; i < pool->base.stream_enc_count; i++) { - if (pool->base.stream_enc[i] != NULL) - kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i])); - } - - for (i = 0; i < pool->base.clk_src_count; i++) { - if (pool->base.clock_sources[i] != NULL) { - dce60_clock_source_destroy(&pool->base.clock_sources[i]); - } - } - - if (pool->base.abm != NULL) - dce_abm_destroy(&pool->base.abm); - - if (pool->base.dmcu != NULL) - dce_dmcu_destroy(&pool->base.dmcu); - - if (pool->base.dp_clock_source != NULL) - dce60_clock_source_destroy(&pool->base.dp_clock_source); - - for (i = 0; i < pool->base.audio_count; i++) { - if (pool->base.audios[i] != NULL) { - dce_aud_destroy(&pool->base.audios[i]); - } - } - - if (pool->base.irqs != NULL) { - dal_irq_service_destroy(&pool->base.irqs); - } -} - -static bool dce60_validate_bandwidth( - struct dc *dc, - struct dc_state *context, - bool fast_validate) -{ - int i; - bool at_least_one_pipe = false; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - if (context->res_ctx.pipe_ctx[i].stream) - at_least_one_pipe = true; - } - - if (at_least_one_pipe) { - /* TODO implement when needed but for now hardcode max value*/ - context->bw_ctx.bw.dce.dispclk_khz = 681000; - context->bw_ctx.bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; - } else { - context->bw_ctx.bw.dce.dispclk_khz = 0; - context->bw_ctx.bw.dce.yclk_khz = 0; - } - - return true; -} - -static bool dce60_validate_surface_sets( - struct dc_state *context) -{ - int i; - - for (i = 0; i < context->stream_count; i++) { - if (context->stream_status[i].plane_count == 0) - continue; - - if (context->stream_status[i].plane_count > 1) - return false; - - if (context->stream_status[i].plane_states[0]->format - >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) - return false; - } - - return true; -} - -static enum dc_status dce60_validate_global( - struct dc *dc, - struct dc_state *context) -{ - if (!dce60_validate_surface_sets(context)) - return DC_FAIL_SURFACE_VALIDATE; - - return DC_OK; -} - -static void dce60_destroy_resource_pool(struct resource_pool **pool) -{ - struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool); - - dce60_resource_destruct(dce110_pool); - kfree(dce110_pool); - *pool = NULL; -} - -static const struct resource_funcs dce60_res_pool_funcs = { - .destroy = dce60_destroy_resource_pool, - .link_enc_create = dce60_link_encoder_create, - .panel_cntl_create = dce60_panel_cntl_create, - .validate_bandwidth = dce60_validate_bandwidth, - .validate_plane = dce100_validate_plane, - .add_stream_to_ctx = dce100_add_stream_to_ctx, - .validate_global = dce60_validate_global, - .find_first_free_match_stream_enc_for_link = dce100_find_first_free_match_stream_enc_for_link -}; - -static bool dce60_construct( - uint8_t num_virtual_links, - struct dc *dc, - struct dce110_resource_pool *pool) -{ - unsigned int i; - struct dc_context *ctx = dc->ctx; - struct dc_bios *bp; - - ctx->dc_bios->regs = &bios_regs; - - pool->base.res_cap = &res_cap; - pool->base.funcs = &dce60_res_pool_funcs; - - - /************************************************* - * Resource + asic cap harcoding * - *************************************************/ - pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; - pool->base.pipe_count = res_cap.num_timing_generator; - pool->base.timing_generator_count = res_cap.num_timing_generator; - dc->caps.max_downscale_ratio = 200; - dc->caps.i2c_speed_in_khz = 40; - dc->caps.max_cursor_size = 64; - dc->caps.dual_link_dvi = true; - dc->caps.extended_aux_timeout_support = false; - - /************************************************* - * Create resources * - *************************************************/ - - bp = ctx->dc_bios; - - if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) { - pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); - - pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); - pool->base.clock_sources[1] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); - pool->base.clk_src_count = 2; - - } else { - pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); - - pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); - pool->base.clk_src_count = 1; - } - - if (pool->base.dp_clock_source == NULL) { - dm_error("DC: failed to create dp clock source!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - for (i = 0; i < pool->base.clk_src_count; i++) { - if (pool->base.clock_sources[i] == NULL) { - dm_error("DC: failed to create clock sources!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - } - - pool->base.dmcu = dce_dmcu_create(ctx, - &dmcu_regs, - &dmcu_shift, - &dmcu_mask); - if (pool->base.dmcu == NULL) { - dm_error("DC: failed to create dmcu!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - pool->base.abm = dce_abm_create(ctx, - &abm_regs, - &abm_shift, - &abm_mask); - if (pool->base.abm == NULL) { - dm_error("DC: failed to create abm!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - { - struct irq_service_init_data init_data; - init_data.ctx = dc->ctx; - pool->base.irqs = dal_irq_service_dce60_create(&init_data); - if (!pool->base.irqs) - goto res_create_fail; - } - - for (i = 0; i < pool->base.pipe_count; i++) { - pool->base.timing_generators[i] = dce60_timing_generator_create( - ctx, i, &dce60_tg_offsets[i]); - if (pool->base.timing_generators[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create tg!\n"); - goto res_create_fail; - } - - pool->base.mis[i] = dce60_mem_input_create(ctx, i); - if (pool->base.mis[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create memory input!\n"); - goto res_create_fail; - } - - pool->base.ipps[i] = dce60_ipp_create(ctx, i); - if (pool->base.ipps[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create input pixel processor!\n"); - goto res_create_fail; - } - - pool->base.transforms[i] = dce60_transform_create(ctx, i); - if (pool->base.transforms[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create transform!\n"); - goto res_create_fail; - } - - pool->base.opps[i] = dce60_opp_create(ctx, i); - if (pool->base.opps[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create output pixel processor!\n"); - goto res_create_fail; - } - } - - for (i = 0; i < pool->base.res_cap->num_ddc; i++) { - pool->base.engines[i] = dce60_aux_engine_create(ctx, i); - if (pool->base.engines[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create aux engine!!\n"); - goto res_create_fail; - } - pool->base.hw_i2cs[i] = dce60_i2c_hw_create(ctx, i); - if (pool->base.hw_i2cs[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create i2c engine!!\n"); - goto res_create_fail; - } - pool->base.sw_i2cs[i] = dce60_i2c_sw_create(ctx); - if (pool->base.sw_i2cs[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create sw i2c!!\n"); - goto res_create_fail; - } - } - - dc->caps.max_planes = pool->base.pipe_count; - - for (i = 0; i < dc->caps.max_planes; ++i) - dc->caps.planes[i] = plane_cap; - - dc->caps.disable_dp_clk_share = true; - - if (!resource_construct(num_virtual_links, dc, &pool->base, - &res_create_funcs)) - goto res_create_fail; - - /* Create hardware sequencer */ - dce60_hw_sequencer_construct(dc); - - return true; - -res_create_fail: - dce60_resource_destruct(pool); - return false; -} - -struct resource_pool *dce60_create_resource_pool( - uint8_t num_virtual_links, - struct dc *dc) -{ - struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); - - if (!pool) - return NULL; - - if (dce60_construct(num_virtual_links, dc, pool)) - return &pool->base; - - kfree(pool); - BREAK_TO_DEBUGGER(); - return NULL; -} - -static bool dce61_construct( - uint8_t num_virtual_links, - struct dc *dc, - struct dce110_resource_pool *pool) -{ - unsigned int i; - struct dc_context *ctx = dc->ctx; - struct dc_bios *bp; - - ctx->dc_bios->regs = &bios_regs; - - pool->base.res_cap = &res_cap_61; - pool->base.funcs = &dce60_res_pool_funcs; - - - /************************************************* - * Resource + asic cap harcoding * - *************************************************/ - pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; - pool->base.pipe_count = res_cap_61.num_timing_generator; - pool->base.timing_generator_count = res_cap_61.num_timing_generator; - dc->caps.max_downscale_ratio = 200; - dc->caps.i2c_speed_in_khz = 40; - dc->caps.max_cursor_size = 64; - dc->caps.is_apu = true; - - /************************************************* - * Create resources * - *************************************************/ - - bp = ctx->dc_bios; - - if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) { - pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); - - pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); - pool->base.clock_sources[1] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); - pool->base.clock_sources[2] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); - pool->base.clk_src_count = 3; - - } else { - pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); - - pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); - pool->base.clock_sources[1] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); - pool->base.clk_src_count = 2; - } - - if (pool->base.dp_clock_source == NULL) { - dm_error("DC: failed to create dp clock source!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - for (i = 0; i < pool->base.clk_src_count; i++) { - if (pool->base.clock_sources[i] == NULL) { - dm_error("DC: failed to create clock sources!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - } - - pool->base.dmcu = dce_dmcu_create(ctx, - &dmcu_regs, - &dmcu_shift, - &dmcu_mask); - if (pool->base.dmcu == NULL) { - dm_error("DC: failed to create dmcu!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - pool->base.abm = dce_abm_create(ctx, - &abm_regs, - &abm_shift, - &abm_mask); - if (pool->base.abm == NULL) { - dm_error("DC: failed to create abm!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - { - struct irq_service_init_data init_data; - init_data.ctx = dc->ctx; - pool->base.irqs = dal_irq_service_dce60_create(&init_data); - if (!pool->base.irqs) - goto res_create_fail; - } - - for (i = 0; i < pool->base.pipe_count; i++) { - pool->base.timing_generators[i] = dce60_timing_generator_create( - ctx, i, &dce60_tg_offsets[i]); - if (pool->base.timing_generators[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create tg!\n"); - goto res_create_fail; - } - - pool->base.mis[i] = dce60_mem_input_create(ctx, i); - if (pool->base.mis[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create memory input!\n"); - goto res_create_fail; - } - - pool->base.ipps[i] = dce60_ipp_create(ctx, i); - if (pool->base.ipps[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create input pixel processor!\n"); - goto res_create_fail; - } - - pool->base.transforms[i] = dce60_transform_create(ctx, i); - if (pool->base.transforms[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create transform!\n"); - goto res_create_fail; - } - - pool->base.opps[i] = dce60_opp_create(ctx, i); - if (pool->base.opps[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create output pixel processor!\n"); - goto res_create_fail; - } - } - - for (i = 0; i < pool->base.res_cap->num_ddc; i++) { - pool->base.engines[i] = dce60_aux_engine_create(ctx, i); - if (pool->base.engines[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create aux engine!!\n"); - goto res_create_fail; - } - pool->base.hw_i2cs[i] = dce60_i2c_hw_create(ctx, i); - if (pool->base.hw_i2cs[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create i2c engine!!\n"); - goto res_create_fail; - } - pool->base.sw_i2cs[i] = dce60_i2c_sw_create(ctx); - if (pool->base.sw_i2cs[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create sw i2c!!\n"); - goto res_create_fail; - } - } - - dc->caps.max_planes = pool->base.pipe_count; - - for (i = 0; i < dc->caps.max_planes; ++i) - dc->caps.planes[i] = plane_cap; - - dc->caps.disable_dp_clk_share = true; - - if (!resource_construct(num_virtual_links, dc, &pool->base, - &res_create_funcs)) - goto res_create_fail; - - /* Create hardware sequencer */ - dce60_hw_sequencer_construct(dc); - - return true; - -res_create_fail: - dce60_resource_destruct(pool); - return false; -} - -struct resource_pool *dce61_create_resource_pool( - uint8_t num_virtual_links, - struct dc *dc) -{ - struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); - - if (!pool) - return NULL; - - if (dce61_construct(num_virtual_links, dc, pool)) - return &pool->base; - - kfree(pool); - BREAK_TO_DEBUGGER(); - return NULL; -} - -static bool dce64_construct( - uint8_t num_virtual_links, - struct dc *dc, - struct dce110_resource_pool *pool) -{ - unsigned int i; - struct dc_context *ctx = dc->ctx; - struct dc_bios *bp; - - ctx->dc_bios->regs = &bios_regs; - - pool->base.res_cap = &res_cap_64; - pool->base.funcs = &dce60_res_pool_funcs; - - - /************************************************* - * Resource + asic cap harcoding * - *************************************************/ - pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; - pool->base.pipe_count = res_cap_64.num_timing_generator; - pool->base.timing_generator_count = res_cap_64.num_timing_generator; - dc->caps.max_downscale_ratio = 200; - dc->caps.i2c_speed_in_khz = 40; - dc->caps.max_cursor_size = 64; - dc->caps.is_apu = true; - - /************************************************* - * Create resources * - *************************************************/ - - bp = ctx->dc_bios; - - if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) { - pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); - - pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], false); - pool->base.clock_sources[1] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false); - pool->base.clk_src_count = 2; - - } else { - pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], true); - - pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false); - pool->base.clk_src_count = 1; - } - - if (pool->base.dp_clock_source == NULL) { - dm_error("DC: failed to create dp clock source!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - for (i = 0; i < pool->base.clk_src_count; i++) { - if (pool->base.clock_sources[i] == NULL) { - dm_error("DC: failed to create clock sources!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - } - - pool->base.dmcu = dce_dmcu_create(ctx, - &dmcu_regs, - &dmcu_shift, - &dmcu_mask); - if (pool->base.dmcu == NULL) { - dm_error("DC: failed to create dmcu!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - pool->base.abm = dce_abm_create(ctx, - &abm_regs, - &abm_shift, - &abm_mask); - if (pool->base.abm == NULL) { - dm_error("DC: failed to create abm!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - - { - struct irq_service_init_data init_data; - init_data.ctx = dc->ctx; - pool->base.irqs = dal_irq_service_dce60_create(&init_data); - if (!pool->base.irqs) - goto res_create_fail; - } - - for (i = 0; i < pool->base.pipe_count; i++) { - pool->base.timing_generators[i] = dce60_timing_generator_create( - ctx, i, &dce60_tg_offsets[i]); - if (pool->base.timing_generators[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create tg!\n"); - goto res_create_fail; - } - - pool->base.mis[i] = dce60_mem_input_create(ctx, i); - if (pool->base.mis[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create memory input!\n"); - goto res_create_fail; - } - - pool->base.ipps[i] = dce60_ipp_create(ctx, i); - if (pool->base.ipps[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create input pixel processor!\n"); - goto res_create_fail; - } - - pool->base.transforms[i] = dce60_transform_create(ctx, i); - if (pool->base.transforms[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create transform!\n"); - goto res_create_fail; - } - - pool->base.opps[i] = dce60_opp_create(ctx, i); - if (pool->base.opps[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error("DC: failed to create output pixel processor!\n"); - goto res_create_fail; - } - } - - for (i = 0; i < pool->base.res_cap->num_ddc; i++) { - pool->base.engines[i] = dce60_aux_engine_create(ctx, i); - if (pool->base.engines[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create aux engine!!\n"); - goto res_create_fail; - } - pool->base.hw_i2cs[i] = dce60_i2c_hw_create(ctx, i); - if (pool->base.hw_i2cs[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create i2c engine!!\n"); - goto res_create_fail; - } - pool->base.sw_i2cs[i] = dce60_i2c_sw_create(ctx); - if (pool->base.sw_i2cs[i] == NULL) { - BREAK_TO_DEBUGGER(); - dm_error( - "DC:failed to create sw i2c!!\n"); - goto res_create_fail; - } - } - - dc->caps.max_planes = pool->base.pipe_count; - - for (i = 0; i < dc->caps.max_planes; ++i) - dc->caps.planes[i] = plane_cap; - - dc->caps.disable_dp_clk_share = true; - - if (!resource_construct(num_virtual_links, dc, &pool->base, - &res_create_funcs)) - goto res_create_fail; - - /* Create hardware sequencer */ - dce60_hw_sequencer_construct(dc); - - return true; - -res_create_fail: - dce60_resource_destruct(pool); - return false; -} - -struct resource_pool *dce64_create_resource_pool( - uint8_t num_virtual_links, - struct dc *dc) -{ - struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); - - if (!pool) - return NULL; - - if (dce64_construct(num_virtual_links, dc, pool)) - return &pool->base; - - kfree(pool); - BREAK_TO_DEBUGGER(); - return NULL; -} diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.h b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.h deleted file mode 100644 index 5d653a76b0b0..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#ifndef __DC_RESOURCE_DCE60_H__ -#define __DC_RESOURCE_DCE60_H__ - -#include "core_types.h" - -struct dc; -struct resource_pool; - -struct resource_pool *dce60_create_resource_pool( - uint8_t num_virtual_links, - struct dc *dc); - -struct resource_pool *dce61_create_resource_pool( - uint8_t num_virtual_links, - struct dc *dc); - -struct resource_pool *dce64_create_resource_pool( - uint8_t num_virtual_links, - struct dc *dc); - -#endif /* __DC_RESOURCE_DCE60_H__ */ - diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c index c1a85ee374d9..e691a1cf3356 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c @@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg, int vstartup_start, int vupdate_offset, int vupdate_width, + int pstate_keepout, const enum signal_type signal, bool use_vbios) { if (!use_vbios) program_pix_dur(tg, timing->pix_clk_100hz); - dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios); + dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, 0, use_vbios); } static void dce60_timing_generator_enable_advanced_request( @@ -238,6 +239,7 @@ static const struct timing_generator_funcs dce60_tg_funcs = { dce60_timing_generator_enable_advanced_request, .configure_crc = dce60_configure_crc, .get_crc = dce110_get_crc, + .is_two_pixels_per_container = dce110_is_two_pixels_per_container, }; void dce60_timing_generator_construct( |