diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2017-06-15 16:27:42 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 18:06:51 -0400 |
commit | ff5ef99248662ef98a64c11c5370ecd9fbbf57a6 (patch) | |
tree | 1bf411efad623fd346b6fa482c1ae7c26bf5ebad | |
parent | 1909bed5b4ff407130fb9d896565661add3bcdee (diff) | |
download | linux-ff5ef99248662ef98a64c11c5370ecd9fbbf57a6.tar.gz linux-ff5ef99248662ef98a64c11c5370ecd9fbbf57a6.tar.bz2 linux-ff5ef99248662ef98a64c11c5370ecd9fbbf57a6.zip |
drm/amdgpu/display: Enable DCN in DC
Enable DCN in DC.
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
39 files changed, 1250 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig index 47c8e2940a91..5c3bb3581842 100644 --- a/drivers/gpu/drm/amd/display/Kconfig +++ b/drivers/gpu/drm/amd/display/Kconfig @@ -17,6 +17,13 @@ config DRM_AMD_DC_PRE_VEGA by default. This includes Polaris, Carrizo, Tonga, Bonaire, and Hawaii. +config DRM_AMD_DC_DCN1_0 + bool "DCN 1.0 Raven family" + depends on DRM_AMD_DC + help + Choose this option if you want to have + RV family for display engine + config DEBUG_KERNEL_DC bool "Enable kgdb break in DC" depends on DRM_AMD_DC diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 74e32246ff30..4ec86ed5622f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -49,6 +49,16 @@ #include "modules/inc/mod_freesync.h" +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include "ivsrcid/irqsrcs_dcn_1_0.h" + +#include "raven1/DCN/dcn_1_0_offset.h" +#include "raven1/DCN/dcn_1_0_sh_mask.h" +#include "vega10/soc15ip.h" + +#include "soc15_common.h" +#endif + static enum drm_plane_type dm_surfaces_type_default[AMDGPU_MAX_PLANES] = { DRM_PLANE_TYPE_PRIMARY, DRM_PLANE_TYPE_PRIMARY, @@ -930,7 +940,8 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) int i; unsigned client_id = AMDGPU_IH_CLIENTID_LEGACY; - if (adev->asic_type == CHIP_VEGA10) + if (adev->asic_type == CHIP_VEGA10 || + adev->asic_type == CHIP_RAVEN) client_id = AMDGPU_IH_CLIENTID_DCE; int_params.requested_polarity = INTERRUPT_POLARITY_DEFAULT; @@ -1003,6 +1014,92 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) return 0; } +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +/* Register IRQ sources and initialize IRQ callbacks */ +static int dcn10_register_irq_handlers(struct amdgpu_device *adev) +{ + struct dc *dc = adev->dm.dc; + struct common_irq_params *c_irq_params; + struct dc_interrupt_params int_params = {0}; + int r; + int i; + + int_params.requested_polarity = INTERRUPT_POLARITY_DEFAULT; + int_params.current_polarity = INTERRUPT_POLARITY_DEFAULT; + + /* Actions of amdgpu_irq_add_id(): + * 1. Register a set() function with base driver. + * Base driver will call set() function to enable/disable an + * interrupt in DC hardware. + * 2. Register amdgpu_dm_irq_handler(). + * Base driver will call amdgpu_dm_irq_handler() for ALL interrupts + * coming from DC hardware. + * amdgpu_dm_irq_handler() will re-direct the interrupt to DC + * for acknowledging and handling. + * */ + + /* Use VSTARTUP interrupt */ + for (i = DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP; + i <= DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP + adev->mode_info.num_crtc - 1; + i++) { + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_DCE, i, &adev->crtc_irq); + + if (r) { + DRM_ERROR("Failed to add crtc irq id!\n"); + return r; + } + + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; + int_params.irq_source = + dc_interrupt_to_irq_source(dc, i, 0); + + c_irq_params = &adev->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1]; + + c_irq_params->adev = adev; + c_irq_params->irq_src = int_params.irq_source; + + amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_crtc_high_irq, c_irq_params); + } + + /* Use GRPH_PFLIP interrupt */ + for (i = DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT; + i <= DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT + adev->mode_info.num_crtc - 1; + i++) { + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_DCE, i, &adev->pageflip_irq); + if (r) { + DRM_ERROR("Failed to add page flip irq id!\n"); + return r; + } + + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; + int_params.irq_source = + dc_interrupt_to_irq_source(dc, i, 0); + + c_irq_params = &adev->dm.pflip_params[int_params.irq_source - DC_IRQ_SOURCE_PFLIP_FIRST]; + + c_irq_params->adev = adev; + c_irq_params->irq_src = int_params.irq_source; + + amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_pflip_high_irq, c_irq_params); + + } + + /* HPD */ + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_DCE, DCN_1_0__SRCID__DC_HPD1_INT, + &adev->hpd_irq); + if (r) { + DRM_ERROR("Failed to add hpd irq id!\n"); + return r; + } + + register_hpd_handlers(adev); + + return 0; +} +#endif + static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) { int r; @@ -1172,6 +1269,14 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) goto fail_free_encoder; } break; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case CHIP_RAVEN: + if (dcn10_register_irq_handlers(dm->adev)) { + DRM_ERROR("DM: Failed to initialize IRQ\n"); + goto fail_free_encoder; + } + break; +#endif default: DRM_ERROR("Usupported ASIC type: 0x%X\n", adev->asic_type); goto fail_free_encoder; @@ -1447,6 +1552,14 @@ static int dm_early_init(void *handle) adev->mode_info.num_dig = 6; adev->mode_info.plane_type = dm_surfaces_type_default; break; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case CHIP_RAVEN: + adev->mode_info.num_crtc = 4; + adev->mode_info.num_hpd = 4; + adev->mode_info.num_dig = 4; + adev->mode_info.plane_type = dm_surfaces_type_default; + break; +#endif default: DRM_ERROR("Usupported ASIC type: 0x%X\n", adev->asic_type); return -EINVAL; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c index 0f09e8b903d3..bca6769e7481 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c @@ -562,7 +562,8 @@ static void fill_plane_attributes_from_fb( surface->tiling_info.gfx8.pipe_config = AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); - if (adev->asic_type == CHIP_VEGA10) { + if (adev->asic_type == CHIP_VEGA10 || + adev->asic_type == CHIP_RAVEN) { /* Fill GFX9 params */ surface->tiling_info.gfx9.num_pipes = adev->gfx.config.gb_addr_config_fields.num_pipes; diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index 1a79762425ea..4f83e3011743 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -4,7 +4,12 @@ DC_LIBS = basics bios calcs dce gpio i2caux irq virtual +ifdef CONFIG_DRM_AMD_DC_DCN1_0 +DC_LIBS += dcn10 dml +endif + DC_LIBS += dce120 + DC_LIBS += dce112 DC_LIBS += dce110 DC_LIBS += dce100 diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c index 1cc3df1d5698..84b1f515aa47 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c @@ -53,6 +53,11 @@ bool dal_bios_parser_init_cmd_tbl_helper2( case DCE_VERSION_11_2: *h = dal_cmd_tbl_helper_dce112_get_table2(); return true; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case DCN_VERSION_1_0: + *h = dal_cmd_tbl_helper_dce112_get_table2(); + return true; +#endif case DCE_VERSION_12_0: *h = dal_cmd_tbl_helper_dce112_get_table2(); return true; diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile index 63a0edbc32e7..a095472bf4b5 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile +++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -3,8 +3,16 @@ # It calculates Bandwidth and Watermarks values for HW programming # +CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4 +CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4 +CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 + BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o +ifdef CONFIG_DRM_AMD_DC_DCN1_0 +BW_CALCS += dcn_calcs.o dcn_calc_math.o dcn_calc_auto.o +endif + AMD_DAL_BW_CALCS = $(addprefix $(AMDDALPATH)/dc/calcs/,$(BW_CALCS)) AMD_DISPLAY_FILES += $(AMD_DAL_BW_CALCS) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 2de86f8364a3..ae8b221c85aa 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -39,6 +39,9 @@ #include "dce100/dce100_resource.h" #include "dce110/dce110_resource.h" #include "dce112/dce112_resource.h" +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include "dcn10/dcn10_resource.h" +#endif #include "dce120/dce120_resource.h" enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) @@ -69,6 +72,11 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) case FAMILY_AI: dc_version = DCE_VERSION_12_0; break; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case FAMILY_RV: + dc_version = DCN_VERSION_1_0; + break; +#endif default: dc_version = DCE_VERSION_UNKNOWN; break; @@ -105,6 +113,13 @@ struct resource_pool *dc_create_resource_pool( res_pool = dce120_create_resource_pool( num_virtual_links, dc); break; + +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case DCN_VERSION_1_0: + res_pool = dcn10_create_resource_pool( + num_virtual_links, dc); + break; +#endif default: break; } @@ -1188,6 +1203,10 @@ static int acquire_first_free_pipe( pipe_ctx->dis_clk = pool->display_clock; pipe_ctx->pipe_idx = i; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + pipe_ctx->mpc_idx = -1; +#endif + pipe_ctx->stream = stream; return i; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 87675f032949..d74bbdce1090 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -94,7 +94,13 @@ struct dc_surface; struct validate_context; struct dc_cap_funcs { +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + bool (*get_dcc_compression_cap)(const struct dc *dc, + const struct dc_dcc_surface_param *input, + struct dc_surface_dcc_cap *output); +#else int i; +#endif }; struct dc_stream_funcs { @@ -164,6 +170,18 @@ struct dc_debug { bool disable_stutter; bool disable_dcc; bool disable_dfs_bypass; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + bool disable_dpp_power_gate; + bool disable_hubp_power_gate; + bool disable_pplib_wm_range; + bool use_dml_wm; + bool use_max_voltage; + int sr_exit_time_ns; + int sr_enter_plus_exit_time_ns; + int urgent_latency_ns; + int percent_of_ideal_drambw; + int dram_clock_change_latency_ns; +#endif bool disable_pplib_clock_request; bool disable_clock_gate; bool disable_dmcu; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h index 56087b36bdeb..e0abd2d49370 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h @@ -54,6 +54,22 @@ SR(DC_ABM1_HGLS_REG_READ_PROGRESS), \ SR(BIOS_SCRATCH_2) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + #define ABM_DCN10_REG_LIST(id)\ + ABM_COMMON_REG_LIST_DCE_BASE(), \ + SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ + SRI(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \ + SRI(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \ + SRI(DC_ABM1_HG_MISC_CTRL, ABM, id), \ + SRI(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \ + SRI(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \ + SRI(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \ + SRI(BL1_PWM_USER_LEVEL, ABM, id), \ + SRI(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \ + SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \ + NBIO_SR(BIOS_SCRATCH_2) +#endif + #define ABM_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -105,6 +121,39 @@ ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, mask_sh) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + #define ABM_MASK_SH_LIST_DCN10(mask_sh) \ + ABM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \ + ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \ + ABM1_HG_NUM_OF_BINS_SEL, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \ + ABM1_HG_VMAX_SEL, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \ + ABM1_HG_BIN_BITWIDTH_SIZE_SEL, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \ + ABM1_IPCSC_COEFF_SEL_R, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \ + ABM1_IPCSC_COEFF_SEL_G, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \ + ABM1_IPCSC_COEFF_SEL_B, mask_sh), \ + ABM_SF(ABM0_BL1_PWM_CURRENT_ABM_LEVEL, \ + BL1_PWM_CURRENT_ABM_LEVEL, mask_sh), \ + ABM_SF(ABM0_BL1_PWM_TARGET_ABM_LEVEL, \ + BL1_PWM_TARGET_ABM_LEVEL, mask_sh), \ + ABM_SF(ABM0_BL1_PWM_USER_LEVEL, \ + BL1_PWM_USER_LEVEL, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \ + ABM1_LS_MIN_PIXEL_VALUE_THRES, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \ + ABM1_LS_MAX_PIXEL_VALUE_THRES, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \ + ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \ + ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \ + ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \ + ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, mask_sh) +#endif + #define ABM_REG_FIELD_LIST(type) \ type ABM1_HG_NUM_OF_BINS_SEL; \ type ABM1_HG_VMAX_SEL; \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index bd4524ef3a37..142b3a01c204 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -586,6 +586,9 @@ static uint32_t dce110_get_pix_clk_dividers( break; case DCE_VERSION_11_2: case DCE_VERSION_12_0: +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case DCN_VERSION_1_0: +#endif dce112_get_pix_clk_dividers_helper(clk_src, pll_settings, pix_clk_params); break; @@ -815,6 +818,31 @@ static bool dce110_program_pix_clk( struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); struct bp_pixel_clock_parameters bp_pc_params = {0}; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) { + unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; + unsigned dp_dto_ref_kHz = 600000; + /* DPREF clock from FPGA TODO: Does FPGA have this value? */ + unsigned clock_kHz = pll_settings->actual_pix_clk; + + /* For faster simulation, if mode pixe clock less than 290MHz, + * pixel clock can be hard coded to 290Mhz. For 4K mode, pixel clock + * is greater than 500Mhz, need real pixel clock + * clock_kHz = 290000; + */ + /* TODO: un-hardcode when we can set display clock properly*/ + /*clock_kHz = pix_clk_params->requested_pix_clk;*/ + clock_kHz = 290000; + + /* Set DTO values: phase = target clock, modulo = reference clock */ + REG_WRITE(PHASE[inst], clock_kHz); + REG_WRITE(MODULO[inst], dp_dto_ref_kHz); + + /* Enable DTO */ + REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); + return true; + } +#endif /* First disable SS * ATOMBIOS will enable by default SS on PLL for DP, * do not disable it here @@ -870,6 +898,9 @@ static bool dce110_program_pix_clk( break; case DCE_VERSION_11_2: case DCE_VERSION_12_0: +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case DCN_VERSION_1_0: +#endif if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) { bp_pc_params.flags.SET_GENLOCK_REF_DIV_SRC = pll_settings->use_external_clk; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h index 28984c79fc46..e8bc98b3b622 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h @@ -55,6 +55,27 @@ CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\ CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, mask_sh) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#define CS_COMMON_REG_LIST_DCN1_0(index, pllid) \ + SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ + SRII(PHASE, DP_DTO, 0),\ + SRII(PHASE, DP_DTO, 1),\ + SRII(PHASE, DP_DTO, 2),\ + SRII(PHASE, DP_DTO, 3),\ + SRII(MODULO, DP_DTO, 0),\ + SRII(MODULO, DP_DTO, 1),\ + SRII(MODULO, DP_DTO, 2),\ + SRII(MODULO, DP_DTO, 3),\ + SRII(PIXEL_RATE_CNTL, OTG, 0), \ + SRII(PIXEL_RATE_CNTL, OTG, 1), \ + SRII(PIXEL_RATE_CNTL, OTG, 2), \ + SRII(PIXEL_RATE_CNTL, OTG, 3) + +#define CS_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ + CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\ + CS_SF(OTG0_PIXEL_RATE_CNTL, DP_DTO0_ENABLE, mask_sh) +#endif + #define CS_REG_FIELD_LIST(type) \ type PLL_REF_DIV_SRC; \ type DCCG_DEEP_COLOR_CNTL1; \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 81cb138cdc38..6e56d8308d66 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -29,6 +29,10 @@ #include "fixed32_32.h" #include "bios_parser_interface.h" #include "dc.h" +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include "dcn_calcs.h" +#include "core_dc.h" +#endif #define TO_DCE_CLOCKS(clocks)\ container_of(clocks, struct dce_disp_clk, base) @@ -400,6 +404,10 @@ static void dce112_set_clock( bp->funcs->set_dce_clock(bp, &dce_clk_params); +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + dce_psr_wait_loop(clk_dce, requested_clk_khz); +#endif + } static void dce_clock_read_integrated_info(struct dce_disp_clk *clk_dce) @@ -596,6 +604,13 @@ static bool dce_apply_clock_voltage_request( } } if (send_request) { +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + struct core_dc *core_dc = DC_TO_CORE(clk->ctx->dc); + /*use dcfclk request voltage*/ + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; + clock_voltage_req.clocks_in_khz = + dcn_find_dcfclk_suits_all(core_dc, &clk->cur_clocks_value); +#endif dm_pp_apply_clock_for_voltage_request( clk->ctx, &clock_voltage_req); } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index 29ff470086e5..103e905291a3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -45,6 +45,15 @@ CLK_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, mask_sh), \ CLK_SF(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, mask_sh) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#define CLK_DCN10_REG_LIST()\ + SR(DPREFCLK_CNTL), \ + SR(DENTIST_DISPCLK_CNTL), \ + SR(MASTER_COMM_DATA_REG1), \ + SR(MASTER_COMM_CMD_REG), \ + SR(MASTER_COMM_CNTL_REG) +#endif + #define CLK_COMMON_MASK_SH_LIST_SOC_BASE(mask_sh) \ CLK_SF(DCCG_DFS_DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \ CLK_SF(DCCG_DFS_DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh), \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index da7f86b61de4..c58328cd787b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -252,12 +252,234 @@ static void dce_dmcu_setup_psr(struct dmcu *dmcu, REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); } +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +bool dcn10_dmcu_load_iram(struct dmcu *dmcu, + unsigned int start_offset, + const char *src, + unsigned int bytes) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + unsigned int count = 0; + + REG_UPDATE(DMCU_CTRL, DMCU_ENABLE, 1); + + /* Enable write access to IRAM */ + REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL, + IRAM_HOST_ACCESS_EN, 1, + IRAM_WR_ADDR_AUTO_INC, 1); + + REG_WAIT(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10); + + REG_WRITE(DMCU_IRAM_WR_CTRL, start_offset); + + for (count = 0; count < bytes; count++) + REG_WRITE(DMCU_IRAM_WR_DATA, src[count]); + + /* Disable write access to IRAM to allow dynamic sleep state */ + REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL, + IRAM_HOST_ACCESS_EN, 0, + IRAM_WR_ADDR_AUTO_INC, 0); + + return true; +} + +static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + + uint32_t psrStateOffset = 0xf0; + + /* Enable write access to IRAM */ + REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 1); + + REG_WAIT(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10); + + /* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */ + REG_WRITE(DMCU_IRAM_RD_CTRL, psrStateOffset); + + /* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/ + *psr_state = REG_READ(DMCU_IRAM_RD_DATA); + + /* Disable write access to IRAM after finished using IRAM + * in order to allow dynamic sleep state + */ + REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 0); +} + +static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + unsigned int dmcu_max_retry_on_wait_reg_ready = 801; + unsigned int dmcu_wait_reg_ready_interval = 100; + + unsigned int retryCount; + uint32_t psr_state = 0; + + /* waitDMCUReadyForCmd */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, + dmcu_wait_reg_ready_interval, + dmcu_max_retry_on_wait_reg_ready); + + /* setDMCUParam_Cmd */ + if (enable) + REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, + PSR_ENABLE); + else + REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, + PSR_EXIT); + + /* notifyDMCUMsg */ + REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); + + /* Below loops 1000 x 500us = 500 ms. + * Exit PSR may need to wait 1-2 frames to power up. Timeout after at + * least a few frames. Should never hit the max retry assert below. + */ + for (retryCount = 0; retryCount <= 1000; retryCount++) { + dcn10_get_dmcu_psr_state(dmcu, &psr_state); + if (enable) { + if (psr_state != 0) + break; + } else { + if (psr_state == 0) + break; + } + dm_delay_in_microseconds(dmcu->ctx, 500); + } + + /* assert if max retry hit */ + ASSERT(retryCount <= 1000); +} + +static void dcn10_dmcu_setup_psr(struct dmcu *dmcu, + struct core_link *link, + struct psr_context *psr_context) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + + unsigned int dmcu_max_retry_on_wait_reg_ready = 801; + unsigned int dmcu_wait_reg_ready_interval = 100; + + union dce_dmcu_psr_config_data_reg1 masterCmdData1; + union dce_dmcu_psr_config_data_reg2 masterCmdData2; + union dce_dmcu_psr_config_data_reg3 masterCmdData3; + + link->link_enc->funcs->psr_program_dp_dphy_fast_training(link->link_enc, + psr_context->psrExitLinkTrainingRequired); + + /* Enable static screen interrupts for PSR supported display */ + /* Disable the interrupt coming from other displays. */ + REG_UPDATE_4(DMCU_INTERRUPT_TO_UC_EN_MASK, + STATIC_SCREEN1_INT_TO_UC_EN, 0, + STATIC_SCREEN2_INT_TO_UC_EN, 0, + STATIC_SCREEN3_INT_TO_UC_EN, 0, + STATIC_SCREEN4_INT_TO_UC_EN, 0); + + switch (psr_context->controllerId) { + /* Driver uses case 1 for unconfigured */ + case 1: + REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK, + STATIC_SCREEN1_INT_TO_UC_EN, 1); + break; + case 2: + REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK, + STATIC_SCREEN2_INT_TO_UC_EN, 1); + break; + case 3: + REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK, + STATIC_SCREEN3_INT_TO_UC_EN, 1); + break; + case 4: + REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK, + STATIC_SCREEN4_INT_TO_UC_EN, 1); + break; + case 5: + /* CZ/NL only has 4 CRTC!! + * really valid. + * There is no interrupt enable mask for these instances. + */ + break; + case 6: + /* CZ/NL only has 4 CRTC!! + * These are here because they are defined in HW regspec, + * but not really valid. There is no interrupt enable mask + * for these instances. + */ + break; + default: + REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK, + STATIC_SCREEN1_INT_TO_UC_EN, 1); + break; + } + + link->link_enc->funcs->psr_program_secondary_packet(link->link_enc, + psr_context->sdpTransmitLineNumDeadline); + + if (psr_context->psr_level.bits.SKIP_SMU_NOTIFICATION) + REG_UPDATE(SMU_INTERRUPT_CONTROL, DC_SMU_INT_ENABLE, 1); + + /* waitDMCUReadyForCmd */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, + dmcu_wait_reg_ready_interval, + dmcu_max_retry_on_wait_reg_ready); + + /* setDMCUParam_PSRHostConfigData */ + masterCmdData1.u32All = 0; + masterCmdData1.bits.timehyst_frames = psr_context->timehyst_frames; + masterCmdData1.bits.hyst_lines = psr_context->hyst_lines; + masterCmdData1.bits.rfb_update_auto_en = + psr_context->rfb_update_auto_en; + masterCmdData1.bits.dp_port_num = psr_context->transmitterId; + masterCmdData1.bits.dcp_sel = psr_context->controllerId; + masterCmdData1.bits.phy_type = psr_context->phyType; + masterCmdData1.bits.frame_cap_ind = + psr_context->psrFrameCaptureIndicationReq; + masterCmdData1.bits.aux_chan = psr_context->channel; + masterCmdData1.bits.aux_repeat = psr_context->aux_repeats; + dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), + masterCmdData1.u32All); + + masterCmdData2.u32All = 0; + masterCmdData2.bits.dig_fe = psr_context->engineId; + masterCmdData2.bits.dig_be = psr_context->transmitterId; + masterCmdData2.bits.skip_wait_for_pll_lock = + psr_context->skipPsrWaitForPllLock; + masterCmdData2.bits.frame_delay = psr_context->frame_delay; + masterCmdData2.bits.smu_phy_id = psr_context->smuPhyId; + masterCmdData2.bits.num_of_controllers = + psr_context->numberOfControllers; + dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG2), + masterCmdData2.u32All); + + masterCmdData3.u32All = 0; + masterCmdData3.bits.psr_level = psr_context->psr_level.u32all; + dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG3), + masterCmdData3.u32All); + + /* setDMCUParam_Cmd */ + REG_UPDATE(MASTER_COMM_CMD_REG, + MASTER_COMM_CMD_REG_BYTE0, PSR_SET); + + /* notifyDMCUMsg */ + REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); +} + +#endif + static const struct dmcu_funcs dce_funcs = { .load_iram = dce_dmcu_load_iram, .set_psr_enable = dce_dmcu_set_psr_enable, .setup_psr = dce_dmcu_setup_psr, }; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +static const struct dmcu_funcs dcn10_funcs = { + .load_iram = dcn10_dmcu_load_iram, + .set_psr_enable = dcn10_dmcu_set_psr_enable, + .setup_psr = dcn10_dmcu_setup_psr, +}; +#endif + static void dce_dmcu_construct( struct dce_dmcu *dmcu_dce, struct dc_context *ctx, @@ -296,6 +518,29 @@ struct dmcu *dce_dmcu_create( return &dmcu_dce->base; } +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +struct dmcu *dcn10_dmcu_create( + struct dc_context *ctx, + const struct dce_dmcu_registers *regs, + const struct dce_dmcu_shift *dmcu_shift, + const struct dce_dmcu_mask *dmcu_mask) +{ + struct dce_dmcu *dmcu_dce = dm_alloc(sizeof(*dmcu_dce)); + + if (dmcu_dce == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } + + dce_dmcu_construct( + dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask); + + dmcu_dce->base.funcs = &dcn10_funcs; + + return &dmcu_dce->base; +} +#endif + void dce_dmcu_destroy(struct dmcu **dmcu) { struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(*dmcu); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h index 7dc25386c2bf..584682ba1f77 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h @@ -48,6 +48,12 @@ DMCU_COMMON_REG_LIST_DCE_BASE(), \ SR(DCI_MEM_PWR_STATUS) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + #define DMCU_DCN10_REG_LIST()\ + DMCU_COMMON_REG_LIST_DCE_BASE(), \ + SR(DMU_MEM_PWR_CNTL) +#endif + #define DMCU_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -76,6 +82,13 @@ DMCU_SF(DCI_MEM_PWR_STATUS, \ DMCU_IRAM_MEM_PWR_STATE, mask_sh) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + #define DMCU_MASK_SH_LIST_DCN10(mask_sh) \ + DMCU_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \ + DMCU_SF(DMU_MEM_PWR_CNTL, \ + DMCU_IRAM_MEM_PWR_STATE, mask_sh) +#endif + #define DMCU_REG_FIELD_LIST(type) \ type DMCU_IRAM_MEM_PWR_STATE; \ type IRAM_HOST_ACCESS_EN; \ @@ -190,6 +203,14 @@ struct dmcu *dce_dmcu_create( const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask); +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +struct dmcu *dcn10_dmcu_create( + struct dc_context *ctx, + const struct dce_dmcu_registers *regs, + const struct dce_dmcu_shift *dmcu_shift, + const struct dce_dmcu_mask *dmcu_mask); +#endif + void dce_dmcu_destroy(struct dmcu **dmcu); #endif /* _DCE_ABM_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index c66585188ecd..dd13f47b6446 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -121,6 +121,12 @@ HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \ HWSEQ_PHYPLL_REG_LIST(CRTC) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#define HWSEQ_DCN1_REG_LIST()\ + HWSEQ_PIXEL_RATE_REG_LIST(OTG), \ + HWSEQ_PHYPLL_REG_LIST(OTG) +#endif + struct dce_hwseq_registers { uint32_t DCFE_CLOCK_CONTROL[6]; uint32_t DCFEV_CLOCK_CONTROL; @@ -129,6 +135,9 @@ struct dce_hwseq_registers { uint32_t BLND_CONTROL[6]; uint32_t BLNDV_CONTROL; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + /* DCE + DCN */ +#endif uint32_t CRTC_H_BLANK_START_END[6]; uint32_t PIXEL_RATE_CNTL[6]; uint32_t PHYPLL_PIXEL_RATE_CNTL[6]; @@ -192,6 +201,12 @@ struct dce_hwseq_registers { HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\ HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#define HWSEQ_DCN1_MASK_SH_LIST(mask_sh)\ + HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\ + HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, OTG0_) +#endif + #define HWSEQ_REG_FIED_LIST(type) \ type DCFE_CLOCK_ENABLE; \ type DCFEV_CLOCK_ENABLE; \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index 4e0b5d965355..8b04996d5b89 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -78,6 +78,10 @@ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ SR(DCI_MEM_PWR_STATUS) +#define LE_DCE80_REG_LIST(id)\ + SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ + LE_COMMON_REG_LIST_BASE(id) + #define LE_DCE100_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ @@ -97,9 +101,15 @@ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ SR(DCI_MEM_PWR_STATUS) -#define LE_DCE80_REG_LIST(id)\ - SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ - LE_COMMON_REG_LIST_BASE(id) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + #define LE_DCN10_REG_LIST(id)\ + LE_COMMON_REG_LIST_BASE(id), \ + SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ + SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ + SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ + SR(DMU_MEM_PWR_CNTL) +#endif + struct dce110_link_enc_aux_registers { uint32_t AUX_CONTROL; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 9713def6e481..a065e4ae6cba 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -147,6 +147,46 @@ static void dce110_update_generic_info_packet( AFMT_GENERIC0_UPDATE, (packet_index == 0), AFMT_GENERIC2_UPDATE, (packet_index == 2)); } +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (REG(AFMT_VBI_PACKET_CONTROL1)) { + switch (packet_index) { + case 0: + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, + AFMT_GENERIC0_FRAME_UPDATE, 1); + break; + case 1: + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, + AFMT_GENERIC1_FRAME_UPDATE, 1); + break; + case 2: + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, + AFMT_GENERIC2_FRAME_UPDATE, 1); + break; + case 3: + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, + AFMT_GENERIC3_FRAME_UPDATE, 1); + break; + case 4: + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, + AFMT_GENERIC4_FRAME_UPDATE, 1); + break; + case 5: + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, + AFMT_GENERIC5_FRAME_UPDATE, 1); + break; + case 6: + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, + AFMT_GENERIC6_FRAME_UPDATE, 1); + break; + case 7: + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, + AFMT_GENERIC7_FRAME_UPDATE, 1); + break; + default: + break; + } + } +#endif } static void dce110_update_hdmi_info_packet( @@ -202,6 +242,36 @@ static void dce110_update_hdmi_info_packet( HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case 4: + if (REG(HDMI_GENERIC_PACKET_CONTROL2)) + REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, + HDMI_GENERIC0_CONT, cont, + HDMI_GENERIC0_SEND, send, + HDMI_GENERIC0_LINE, line); + break; + case 5: + if (REG(HDMI_GENERIC_PACKET_CONTROL2)) + REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, + HDMI_GENERIC1_CONT, cont, + HDMI_GENERIC1_SEND, send, + HDMI_GENERIC1_LINE, line); + break; + case 6: + if (REG(HDMI_GENERIC_PACKET_CONTROL3)) + REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3, + HDMI_GENERIC0_CONT, cont, + HDMI_GENERIC0_SEND, send, + HDMI_GENERIC0_LINE, line); + break; + case 7: + if (REG(HDMI_GENERIC_PACKET_CONTROL3)) + REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3, + HDMI_GENERIC1_CONT, cont, + HDMI_GENERIC1_SEND, send, + HDMI_GENERIC1_LINE, line); + break; +#endif default: /* invalid HW packet index */ dm_logger_write( @@ -218,9 +288,24 @@ static void dce110_stream_encoder_dp_set_stream_attribute( struct dc_crtc_timing *crtc_timing, enum dc_color_space output_color_space) { +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + uint32_t h_active_start; + uint32_t v_active_start; + uint32_t misc0 = 0; + uint32_t misc1 = 0; + uint32_t h_blank; + uint32_t h_back_porch; + uint8_t synchronous_clock = 0; /* asynchronous mode */ + uint8_t colorimetry_bpc; +#endif struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (REG(DP_DB_CNTL)) + REG_UPDATE(DP_DB_CNTL, DP_DB_DISABLE, 1); +#endif + /* set pixel encoding */ switch (crtc_timing->pixel_encoding) { case PIXEL_ENCODING_YCBCR422: @@ -249,6 +334,10 @@ static void dce110_stream_encoder_dp_set_stream_attribute( if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN) REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1); +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (enc110->se_mask->DP_VID_N_MUL) + REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1); +#endif break; default: REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, @@ -256,6 +345,11 @@ static void dce110_stream_encoder_dp_set_stream_attribute( break; } +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (REG(DP_MSA_MISC)) + misc1 = REG_READ(DP_MSA_MISC); +#endif + /* set color depth */ switch (crtc_timing->display_color_depth) { @@ -289,6 +383,128 @@ static void dce110_stream_encoder_dp_set_stream_attribute( DP_DYN_RANGE, 0, DP_YCBCR_RANGE, 0); +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + switch (crtc_timing->display_color_depth) { + case COLOR_DEPTH_666: + colorimetry_bpc = 0; + break; + case COLOR_DEPTH_888: + colorimetry_bpc = 1; + break; + case COLOR_DEPTH_101010: + colorimetry_bpc = 2; + break; + case COLOR_DEPTH_121212: + colorimetry_bpc = 3; + break; + default: + colorimetry_bpc = 0; + break; + } + + misc0 = misc0 | synchronous_clock; + misc0 = colorimetry_bpc << 5; + + if (REG(DP_MSA_TIMING_PARAM1)) { + switch (output_color_space) { + case COLOR_SPACE_SRGB: + misc0 = misc0 | 0x0;; + misc1 = misc1 & ~0x80; /* bit7 = 0*/ + break; + case COLOR_SPACE_SRGB_LIMITED: + misc0 = misc0 | 0x8; /* bit3=1 */ + misc1 = misc1 & ~0x80; /* bit7 = 0*/ + break; + case COLOR_SPACE_YCBCR601: + misc0 = misc0 | 0x8; /* bit3=1, bit4=0 */ + misc1 = misc1 & ~0x80; /* bit7 = 0*/; + if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) + misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */ + else if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) + misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */ + break; + case COLOR_SPACE_YCBCR709: + misc0 = misc0 | 0x18; /* bit3=1, bit4=1 */ + misc1 = misc1 & ~0x80; /* bit7 = 0*/ + if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) + misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */ + else if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) + misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */ + break; + case COLOR_SPACE_2020_RGB_FULLRANGE: + case COLOR_SPACE_2020_RGB_LIMITEDRANGE: + case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_ADOBERGB: + case COLOR_SPACE_UNKNOWN: + case COLOR_SPACE_YCBCR601_LIMITED: + case COLOR_SPACE_YCBCR709_LIMITED: + /* do nothing */ + break; + } + +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (REG(DP_MSA_COLORIMETRY)) + REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0); + + if (REG(DP_MSA_MISC)) + REG_WRITE(DP_MSA_MISC, misc1); /* MSA_MISC1 */ + + /* dcn new register + * dc_crtc_timing is vesa dmt struct. data from edid + */ + if (REG(DP_MSA_TIMING_PARAM1)) + REG_SET_2(DP_MSA_TIMING_PARAM1, 0, + DP_MSA_HTOTAL, crtc_timing->h_total, + DP_MSA_VTOTAL, crtc_timing->v_total); +#endif + + /* calcuate from vesa timing parameters + * h_active_start related to leading edge of sync + */ + + h_blank = crtc_timing->h_total - crtc_timing->h_border_left - + crtc_timing->h_addressable - crtc_timing->h_border_right; + + h_back_porch = h_blank - crtc_timing->h_front_porch - + crtc_timing->h_sync_width; + + /* start at begining of left border */ + h_active_start = crtc_timing->h_sync_width + h_back_porch; + + + v_active_start = crtc_timing->v_total - crtc_timing->v_border_top - + crtc_timing->v_addressable - crtc_timing->v_border_bottom - + crtc_timing->v_front_porch; + + +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + /* start at begining of left border */ + if (REG(DP_MSA_TIMING_PARAM2)) + REG_SET_2(DP_MSA_TIMING_PARAM2, 0, + DP_MSA_HSTART, h_active_start, + DP_MSA_VSTART, v_active_start); + + if (REG(DP_MSA_TIMING_PARAM3)) + REG_SET_4(DP_MSA_TIMING_PARAM3, 0, + DP_MSA_HSYNCWIDTH, + crtc_timing->h_sync_width, + DP_MSA_HSYNCPOLARITY, + !crtc_timing->flags.HSYNC_POSITIVE_POLARITY, + DP_MSA_VSYNCWIDTH, + crtc_timing->v_sync_width, + DP_MSA_VSYNCPOLARITY, + !crtc_timing->flags.VSYNC_POSITIVE_POLARITY); + + /* HWDITH include border or overscan */ + if (REG(DP_MSA_TIMING_PARAM4)) + REG_SET_2(DP_MSA_TIMING_PARAM4, 0, + DP_MSA_HWIDTH, crtc_timing->h_border_left + + crtc_timing->h_addressable + crtc_timing->h_border_right, + DP_MSA_VHEIGHT, crtc_timing->v_border_top + + crtc_timing->v_addressable + crtc_timing->v_border_bottom); +#endif + } +#endif } static void dce110_stream_encoder_set_stream_attribute_helper( @@ -533,6 +749,19 @@ static void dce110_stream_encoder_update_hdmi_info_packets( dce110_update_hdmi_info_packet(enc110, 3, &info_frame->hdrsmd); } +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (enc110->se_mask->HDMI_DB_DISABLE) { + /* for bring up, disable dp double TODO */ + if (REG(HDMI_DB_CONTROL)) + REG_UPDATE(HDMI_DB_CONTROL, HDMI_DB_DISABLE, 1); + + dce110_update_hdmi_info_packet(enc110, 0, &info_frame->avi); + dce110_update_hdmi_info_packet(enc110, 1, &info_frame->vendor); + dce110_update_hdmi_info_packet(enc110, 2, &info_frame->gamut); + dce110_update_hdmi_info_packet(enc110, 3, &info_frame->spd); + dce110_update_hdmi_info_packet(enc110, 4, &info_frame->hdrsmd); + } +#endif } static void dce110_stream_encoder_stop_hdmi_info_packets( @@ -558,6 +787,26 @@ static void dce110_stream_encoder_stop_hdmi_info_packets( HDMI_GENERIC1_LINE, 0, HDMI_GENERIC1_SEND, 0); +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + /* stop generic packets 2 & 3 on HDMI */ + if (REG(HDMI_GENERIC_PACKET_CONTROL2)) + REG_SET_6(HDMI_GENERIC_PACKET_CONTROL2, 0, + HDMI_GENERIC0_CONT, 0, + HDMI_GENERIC0_LINE, 0, + HDMI_GENERIC0_SEND, 0, + HDMI_GENERIC1_CONT, 0, + HDMI_GENERIC1_LINE, 0, + HDMI_GENERIC1_SEND, 0); + + if (REG(HDMI_GENERIC_PACKET_CONTROL3)) + REG_SET_6(HDMI_GENERIC_PACKET_CONTROL3, 0, + HDMI_GENERIC0_CONT, 0, + HDMI_GENERIC0_LINE, 0, + HDMI_GENERIC0_SEND, 0, + HDMI_GENERIC1_CONT, 0, + HDMI_GENERIC1_LINE, 0, + HDMI_GENERIC1_SEND, 0); +#endif } static void dce110_stream_encoder_update_dp_info_packets( @@ -621,6 +870,21 @@ static void dce110_stream_encoder_stop_dp_info_packets( DP_SEC_STREAM_ENABLE, 0); } +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (enc110->se_mask->DP_SEC_GSP7_ENABLE) { + REG_SET_10(DP_SEC_CNTL, 0, + DP_SEC_GSP0_ENABLE, 0, + DP_SEC_GSP1_ENABLE, 0, + DP_SEC_GSP2_ENABLE, 0, + DP_SEC_GSP3_ENABLE, 0, + DP_SEC_GSP4_ENABLE, 0, + DP_SEC_GSP5_ENABLE, 0, + DP_SEC_GSP6_ENABLE, 0, + DP_SEC_GSP7_ENABLE, 0, + DP_SEC_MPG_ENABLE, 0, + DP_SEC_STREAM_ENABLE, 0); + } +#endif /* this register shared with audio info frame. * therefore we need to keep master enabled * if at least one of the fields is not 0 */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h index 850e12a8db61..0b548cb3af14 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h @@ -97,6 +97,23 @@ SE_COMMON_REG_LIST_DCE_BASE(id), \ SRI(AFMT_CNTL, DIG, id) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#define SE_DCN_REG_LIST(id)\ + SE_COMMON_REG_LIST_BASE(id),\ + SRI(AFMT_CNTL, DIG, id),\ + SRI(AFMT_VBI_PACKET_CONTROL1, DIG, id),\ + SRI(HDMI_GENERIC_PACKET_CONTROL2, DIG, id), \ + SRI(HDMI_GENERIC_PACKET_CONTROL3, DIG, id), \ + SRI(DP_DB_CNTL, DP, id), \ + SRI(DP_MSA_MISC, DP, id), \ + SRI(DP_MSA_COLORIMETRY, DP, id), \ + SRI(DP_MSA_TIMING_PARAM1, DP, id), \ + SRI(DP_MSA_TIMING_PARAM2, DP, id), \ + SRI(DP_MSA_TIMING_PARAM3, DP, id), \ + SRI(DP_MSA_TIMING_PARAM4, DP, id), \ + SRI(HDMI_DB_CONTROL, DIG, id) +#endif + #define SE_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -311,6 +328,48 @@ SE_SF(DIG0_AFMT_AVI_INFO3, AFMT_AVI_INFO_VERSION, mask_sh),\ SE_SF(DP0_DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, mask_sh) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#define SE_COMMON_MASK_SH_LIST_DCN10(mask_sh)\ + SE_COMMON_MASK_SH_LIST_SOC(mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC0_FRAME_UPDATE_PENDING, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC1_FRAME_UPDATE_PENDING, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_FRAME_UPDATE_PENDING, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_FRAME_UPDATE_PENDING, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_FRAME_UPDATE_PENDING, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_FRAME_UPDATE_PENDING, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_FRAME_UPDATE_PENDING, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE_PENDING, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC0_FRAME_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC1_FRAME_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_FRAME_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_FRAME_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_FRAME_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_FRAME_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_FRAME_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE, mask_sh),\ + SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP4_ENABLE, mask_sh),\ + SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP5_ENABLE, mask_sh),\ + SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP6_ENABLE, mask_sh),\ + SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, mask_sh),\ + SE_SF(DP0_DP_DB_CNTL, DP_DB_DISABLE, mask_sh),\ + SE_SF(DP0_DP_MSA_COLORIMETRY, DP_MSA_MISC0, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM1, DP_MSA_HTOTAL, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM1, DP_MSA_VTOTAL, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM2, DP_MSA_HSTART, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM2, DP_MSA_VSTART, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_HSYNCWIDTH, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_HSYNCPOLARITY, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_VSYNCWIDTH, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM3, DP_MSA_VSYNCPOLARITY, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_HWIDTH, mask_sh),\ + SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_VHEIGHT, mask_sh),\ + SE_SF(DIG0_HDMI_DB_CONTROL, HDMI_DB_DISABLE, mask_sh),\ + SE_SF(DP0_DP_VID_TIMING, DP_VID_N_MUL, mask_sh) +#endif + struct dce_stream_encoder_shift { uint8_t AFMT_GENERIC_INDEX; uint8_t AFMT_GENERIC0_UPDATE; @@ -625,6 +684,16 @@ struct dce110_stream_enc_registers { uint32_t HDMI_ACR_48_0; uint32_t HDMI_ACR_48_1; uint32_t TMDS_CNTL; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + uint32_t DP_DB_CNTL; + uint32_t DP_MSA_MISC; + uint32_t DP_MSA_COLORIMETRY; + uint32_t DP_MSA_TIMING_PARAM1; + uint32_t DP_MSA_TIMING_PARAM2; + uint32_t DP_MSA_TIMING_PARAM3; + uint32_t DP_MSA_TIMING_PARAM4; + uint32_t HDMI_DB_CONTROL; +#endif }; struct dce110_stream_encoder { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index dc4c16416370..c89df8acb458 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -947,6 +947,12 @@ static void program_scaler(const struct core_dc *dc, { struct tg_color color = {0}; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + /* TOFPGA */ + if (pipe_ctx->xfm->funcs->transform_set_pixel_storage_depth == NULL) + return; +#endif + if (dc->public.debug.surface_visual_confirm) get_surface_visual_confirm_color(pipe_ctx, &color); else @@ -1113,6 +1119,9 @@ static enum dc_status apply_single_controller_ctx_to_hw( program_scaler(dc, pipe_ctx); /* mst support - use total stream count */ +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (pipe_ctx->mi->funcs->allocate_mem_input != NULL) +#endif pipe_ctx->mi->funcs->allocate_mem_input( pipe_ctx->mi, stream->public.timing.h_total, @@ -1637,6 +1646,26 @@ enum dc_status dce110_apply_ctx_to_hw( /*TODO: when pplib works*/ apply_min_clocks(dc, context, &clocks_state, true); +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + if (context->fclk_khz + > dc->current_context->fclk_khz) { + struct dm_pp_clock_for_voltage_req clock; + + clock.clk_type = DM_PP_CLOCK_TYPE_FCLK; + clock.clocks_in_khz = context->fclk_khz; + dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); + dc->current_context->fclk_khz = clock.clocks_in_khz; + } + if (context->dcfclk_khz + > dc->current_context->dcfclk_khz) { + struct dm_pp_clock_for_voltage_req clock; + + clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; + clock.clocks_in_khz = context->dcfclk_khz; + dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); + dc->current_context->dcfclk_khz = clock.clocks_in_khz; + } +#endif if (context->dispclk_khz > dc->current_context->dispclk_khz) { dc->res_pool->display_clock->funcs->set_clock( diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h index cf6ecfcadd5e..fb61e333aefd 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services.h @@ -75,6 +75,10 @@ BREAK_TO_DEBUGGER(); \ } while (0) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include <asm/fpu/api.h> +#endif + #define dm_alloc(size) kzalloc(size, GFP_KERNEL) #define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL) #define dm_free(ptr) kfree(ptr) diff --git a/drivers/gpu/drm/amd/display/dc/dm_services_types.h b/drivers/gpu/drm/amd/display/dc/dm_services_types.h index 408141c6776e..b28304531d8a 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services_types.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services_types.h @@ -69,6 +69,7 @@ enum dm_pp_clock_type { DM_PP_CLOCK_TYPE_ENGINE_CLK, /* System clock */ DM_PP_CLOCK_TYPE_MEMORY_CLK, DM_PP_CLOCK_TYPE_DCFCLK, + DM_PP_CLOCK_TYPE_DCEFCLK, DM_PP_CLOCK_TYPE_SOCCLK, DM_PP_CLOCK_TYPE_PIXELCLK, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, diff --git a/drivers/gpu/drm/amd/display/dc/gpio/Makefile b/drivers/gpu/drm/amd/display/dc/gpio/Makefile index 5e831aff4830..70d01a9e9676 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/Makefile +++ b/drivers/gpu/drm/amd/display/dc/gpio/Makefile @@ -38,6 +38,17 @@ AMD_DAL_GPIO_DCE120 = $(addprefix $(AMDDALPATH)/dc/gpio/dce120/,$(GPIO_DCE120)) AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCE120) ############################################################################### +# DCN 1x +############################################################################### +ifdef CONFIG_DRM_AMD_DC_DCN1_0 +GPIO_DCN10 = hw_translate_dcn10.o hw_factory_dcn10.o + +AMD_DAL_GPIO_DCN10 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn10/,$(GPIO_DCN10)) + +AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN10) +endif + +############################################################################### # Diagnostics on FPGA ############################################################################### GPIO_DIAG_FPGA = hw_translate_diag.o hw_factory_diag.o diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c index 29ba83d2c211..8a8b619a60a8 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c @@ -43,8 +43,10 @@ #include "dce80/hw_factory_dce80.h" #include "dce110/hw_factory_dce110.h" - #include "dce120/hw_factory_dce120.h" +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include "dcn10/hw_factory_dcn10.h" +#endif #include "diagnostics/hw_factory_diag.h" @@ -77,6 +79,11 @@ bool dal_hw_factory_init( case DCE_VERSION_12_0: dal_hw_factory_dce120_init(factory); return true; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case DCN_VERSION_1_0: + dal_hw_factory_dcn10_init(factory); + return true; +#endif default: ASSERT_CRITICAL(false); return false; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c index 872edda54536..36c082bda4ae 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c @@ -43,6 +43,10 @@ #include "dce80/hw_translate_dce80.h" #include "dce110/hw_translate_dce110.h" #include "dce120/hw_translate_dce120.h" +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include "dcn10/hw_translate_dcn10.h" +#endif + #include "diagnostics/hw_translate_diag.h" /* @@ -71,6 +75,11 @@ bool dal_hw_translate_init( case DCE_VERSION_12_0: dal_hw_translate_dce120_init(translate); return true; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case DCN_VERSION_1_0: + dal_hw_translate_dcn10_init(translate); + return true; +#endif default: BREAK_TO_DEBUGGER(); return false; diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/Makefile b/drivers/gpu/drm/amd/display/dc/i2caux/Makefile index a636768d06d5..55603400acd9 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/Makefile +++ b/drivers/gpu/drm/amd/display/dc/i2caux/Makefile @@ -48,6 +48,17 @@ AMD_DAL_I2CAUX_DCE112 = $(addprefix $(AMDDALPATH)/dc/i2caux/dce112/,$(I2CAUX_DCE AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCE112) ############################################################################### +# DCN 1.0 family +############################################################################### +ifdef CONFIG_DRM_AMD_DC_DCN1_0 +I2CAUX_DCN1 = i2caux_dcn10.o + +AMD_DAL_I2CAUX_DCN1 = $(addprefix $(AMDDALPATH)/dc/i2caux/dcn10/,$(I2CAUX_DCN1)) + +AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCN1) +endif + +############################################################################### # DCE 120 family ############################################################################### I2CAUX_DCE120 = i2caux_dce120.o diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c index 0743265e933c..983645b1be78 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c @@ -59,6 +59,10 @@ #include "dce120/i2caux_dce120.h" +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include "dcn10/i2caux_dcn10.h" +#endif + #include "diagnostics/i2caux_diag.h" /* @@ -84,6 +88,10 @@ struct i2caux *dal_i2caux_create( return dal_i2caux_dce100_create(ctx); case DCE_VERSION_12_0: return dal_i2caux_dce120_create(ctx); + #if defined(CONFIG_DRM_AMD_DC_DCN1_0) + case DCN_VERSION_1_0: + return dal_i2caux_dcn10_create(ctx); + #endif default: BREAK_TO_DEBUGGER(); return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_dc.h b/drivers/gpu/drm/amd/display/dc/inc/core_dc.h index f9363f642f92..392cff2cd558 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_dc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_dc.h @@ -30,6 +30,11 @@ struct core_dc { /* Inputs into BW and WM calculations. */ struct bw_calcs_dceip bw_dceip; struct bw_calcs_vbios bw_vbios; +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 + struct dcn_soc_bounding_box dcn_soc; + struct dcn_ip_params dcn_ip; + struct display_mode_lib dml; +#endif /* HW functions */ struct hw_sequencer_funcs hwss; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 9e5e0ba5b10b..c1273d6142c4 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -28,8 +28,11 @@ #include "dc.h" #include "dce_calcs.h" +#include "dcn_calcs.h" #include "ddc_service_types.h" #include "dc_bios_types.h" +#include "mem_input.h" +#include "mpc.h" struct core_stream; @@ -254,6 +257,7 @@ struct resource_pool { struct abm *abm; struct dmcu *dmcu; + struct mpc *mpc; const struct resource_funcs *funcs; const struct resource_caps *res_cap; @@ -287,10 +291,20 @@ struct pipe_ctx { struct pipe_ctx *top_pipe; struct pipe_ctx *bottom_pipe; +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 + uint8_t mpc_idx; + struct _vcs_dpi_display_dlg_regs_st dlg_regs; + struct _vcs_dpi_display_ttu_regs_st ttu_regs; + struct _vcs_dpi_display_rq_regs_st rq_regs; + struct _vcs_dpi_display_pipe_dest_params_st pipe_dlg_param; +#endif }; struct resource_context { struct pipe_ctx pipe_ctx[MAX_PIPES]; +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 + struct mpc_tree_cfg mpc_tree[MAX_PIPES]; +#endif bool is_stream_enc_acquired[MAX_PIPES * 2]; bool is_audio_acquired[MAX_PIPES]; uint8_t clock_source_ref_count[MAX_CLOCK_SOURCES]; @@ -309,6 +323,18 @@ struct validate_context { /* Note: these are big structures, do *not* put on stack! */ struct dm_pp_display_configuration pp_display_cfg; int dispclk_khz; +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 + int dppclk_khz; + bool dppclk_div; + int dcfclk_khz; + int dcfclk_deep_sleep_khz; + int socclk_khz; + int fclk_khz; + int dram_ccm_us; + int min_active_dram_ccm_us; + struct dcn_watermark_set watermarks; + struct dcn_bw_internal_vars dcn_bw_vars; +#endif }; #endif /* _CORE_TYPES_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h index 97f26b55535f..240ab11d1d30 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h @@ -37,6 +37,13 @@ struct clocks_value { bool dispclk_notify_pplib_done; bool pixelclk_notify_pplib_done; bool phyclk_notigy_pplib_done; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + int dcfclock_in_khz; + int dppclk_in_khz; + int mclk_in_khz; + int phyclk_in_khz; + int common_vdd_level; +#endif }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h index 2d472d8ef555..0f952e5b3ae8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h @@ -122,6 +122,7 @@ struct ipp_funcs { struct input_pixel_processor *ipp, const struct pwl_params *params); + void (*ipp_destroy)(struct input_pixel_processor **ipp); }; #endif /* __DAL_IPP_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h index 179f5ad70f48..0880ce98c90c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h @@ -31,6 +31,30 @@ #include "dce/dce_mem_input.h" /* temporary */ +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include "dml/display_mode_structs.h" + +struct cstate_pstate_watermarks_st { + uint32_t cstate_exit_ns; + uint32_t cstate_enter_plus_exit_ns; + uint32_t pstate_change_ns; +}; + +struct dcn_watermarks { + uint32_t pte_meta_urgent_ns; + uint32_t urgent_ns; + struct cstate_pstate_watermarks_st cstate_pstate; +}; + +struct dcn_watermark_set { + struct dcn_watermarks a; + struct dcn_watermarks b; + struct dcn_watermarks c; + struct dcn_watermarks d; +}; + +#endif + struct stutter_modes { bool enhanced; bool quad_dmif_buffer; @@ -52,6 +76,23 @@ struct mem_input { }; struct mem_input_funcs { +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + void (*program_watermarks)( + struct mem_input *mem_input, + struct dcn_watermark_set *watermarks, + unsigned int refclk_period_ns); + + void (*mem_input_setup)( + struct mem_input *mem_input, + struct _vcs_dpi_display_dlg_regs_st *dlg_regs, + struct _vcs_dpi_display_ttu_regs_st *ttu_regs, + struct _vcs_dpi_display_rq_regs_st *rq_regs, + struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest); + + void (*disable_request)(struct mem_input *mem_input); + +#endif + void (*mem_input_program_display_marks)( struct mem_input *mem_input, struct bw_watermarks nbp, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h new file mode 100644 index 000000000000..2e86ebe5eeda --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -0,0 +1,110 @@ +/* Copyright 2012-15 Advanced Micro Devices, Inc. + * + * 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_MPC_H__ +#define __DC_MPC_H__ + +/* define the maximum number of pipes + * MAX_NUM_PIPPES = MAX_PIPES defined in core_type.h + */ +enum { + MAX_NUM_PIPPES = 6 +}; + +enum blend_mode { + DIGI_BYPASS = 0, /* digital bypass */ + TOP_PASSTHRU, /* top layer pass through */ + TOP_BLND /* top layer blend */ +}; + +/* This structure define the mpc tree configuration + * num_pipes - number of pipes of the tree + * opp_id - instance id of OPP to drive MPC + * dpp- array of DPP index + * mpcc - array of MPCC index + * mode - the most bottom layer MPCC mode control. + * All other layers need to be program to 3 + * + * The connection will be: + * mpcc[num_pipes-1]->mpcc[num_pipes-2]->...->mpcc[1]->mpcc[0]->OPP[opp_id] + * dpp[0]->mpcc[0] + * dpp[1]->mpcc[1] + * ... + * dpp[num_pipes-1]->mpcc[num_pipes-1] + * mpcc[0] is the most top layer of MPC tree, + * mpcc[num_pipes-1] is the most bottom layer. + */ + +struct mpc_tree_cfg { + uint8_t num_pipes; + uint8_t opp_id; + /* dpp pipes for blend */ + uint8_t dpp[MAX_NUM_PIPPES]; + /* mpcc insatnces for blend */ + uint8_t mpcc[MAX_NUM_PIPPES]; + enum blend_mode mode; +}; + +struct mpcc_blnd_cfg { + /* 0- perpixel alpha, 1- perpixel alpha combined with global gain, + * 2- global alpha + */ + uint8_t alpha_mode; + uint8_t global_gain; + uint8_t global_alpha; + bool overlap_only; + bool pre_multiplied_alpha; +}; + +struct mpcc_sm_cfg { + bool enable; + /* 0-single plane, 2-row subsampling, 4-column subsampling, + * 6-checkboard subsampling + */ + uint8_t sm_mode; + bool frame_alt; /* 0- disable, 1- enable */ + bool field_alt; /* 0- disable, 1- enable */ + /* 0-no force, 2-force frame polarity from top, + * 3-force frame polarity from bottom + */ + uint8_t force_next_frame_porlarity; + /* 0-no force, 2-force field polarity from top, + * 3-force field polarity from bottom + */ + uint8_t force_next_field_polarity; +}; + +struct mpcc_vupdate_lock_cfg { + bool cfg_lock; + bool adr_lock; + bool adr_cfg_lock; + bool cur0_lock; + bool cur1_lock; +}; + +struct mpc { + struct dc_context *ctx; +}; + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h index 92c99c3b9002..64d43257db96 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h @@ -27,6 +27,7 @@ #define __DAL_OPP_H__ #include "hw_shared.h" +#include "dc_hw_types.h" #include "transform.h" struct fixed31_32; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index 00cdaaae455c..9f130affb31c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -91,10 +91,22 @@ enum crtc_state { CRTC_STATE_VBLANK = 0, CRTC_STATE_VACTIVE }; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +struct _dlg_otg_param { + int vstartup_start; + int vupdate_offset; + int vupdate_width; + int vready_offset; + enum signal_type signal; +}; +#endif struct timing_generator { const struct timing_generator_funcs *funcs; struct dc_bios *bp; struct dc_context *ctx; +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + struct _dlg_otg_param dlg_otg_param; +#endif int inst; }; @@ -155,6 +167,10 @@ struct timing_generator_funcs { bool (*arm_vert_intr)(struct timing_generator *tg, uint8_t width); +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + void (*program_global_sync)(struct timing_generator *tg); + void (*enable_optc_clock)(struct timing_generator *tg, bool enable); +#endif }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/irq/Makefile b/drivers/gpu/drm/amd/display/dc/irq/Makefile index 222f36e3074f..c7e93f7223bd 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/Makefile +++ b/drivers/gpu/drm/amd/display/dc/irq/Makefile @@ -36,3 +36,13 @@ AMD_DAL_IRQ_DCE12 = $(addprefix $(AMDDALPATH)/dc/irq/dce120/,$(IRQ_DCE12)) AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCE12) +############################################################################### +# DCN 1x +############################################################################### +ifdef CONFIG_DRM_AMD_DC_DCN1_0 +IRQ_DCN1 = irq_service_dcn10.o + +AMD_DAL_IRQ_DCN1 = $(addprefix $(AMDDALPATH)/dc/irq/dcn10/,$(IRQ_DCN1)) + +AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN1) +endif diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c index 5255c14254df..0a1fae4ef83a 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c @@ -35,6 +35,11 @@ #include "dce120/irq_service_dce120.h" + +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include "dcn10/irq_service_dcn10.h" +#endif + #include "reg_helper.h" #include "irq_service.h" diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index 6dab058f8f3c..3d2ed5c83734 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h @@ -109,6 +109,19 @@ #define ASIC_REV_IS_STONEY(rev) \ ((rev >= STONEY_A0) && (rev < CZ_UNKNOWN)) +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +/* DCN1_0 */ +#define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */ +#define RAVEN_A0 0x01 +#define RAVEN_UNKNOWN 0xFF + +#define ASIC_REV_IS_RAVEN(eChipRev) ((eChipRev >= RAVEN_A0) && eChipRev < RAVEN_UNKNOWN) +#endif + +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#define FAMILY_RV 142 /* DCN 1*/ +#endif + /* * ASIC chip ID */ diff --git a/drivers/gpu/drm/amd/display/include/dal_types.h b/drivers/gpu/drm/amd/display/include/dal_types.h index 0cefde14aa02..50a2a3ebf36d 100644 --- a/drivers/gpu/drm/amd/display/include/dal_types.h +++ b/drivers/gpu/drm/amd/display/include/dal_types.h @@ -39,7 +39,10 @@ enum dce_version { DCE_VERSION_11_0, DCE_VERSION_11_2, DCE_VERSION_12_0, - DCE_VERSION_MAX, +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) + DCN_VERSION_1_0, +#endif + DCN_VERSION_MAX }; #endif /* __DAL_TYPES_H__ */ |