v5: testing WIP7 adding incrementally: @@ -619,7 +614,7 @@ static struct mem_input *dce60_mem_input_create( return NULL; } - dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks); + 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; } @@ -640,7 +635,7 @@ static struct transform *dce60_transform_create( if (!transform) return NULL; - dce_transform_construct(transform, ctx, inst, + dce60_transform_construct(transform, ctx, inst, &xfm_regs[inst], &xfm_shift, &xfm_mask); transform->prescaler_on = false; return &transform->base; 1) WIP7: same problem (screen not active) 2) SONY AZZURRA android_x86_64_no-dce_mem_input: "Screen is on but is black" 3) CRUZER android_x86_64_no-dce_transform: same problem (screen not active) 4) android_x86_64_no-dce_both 2) and 3): "Screen is on but is black" Extended tests: 7001-WIP7-ARBITRATION_CONTROL3.patch : Ok *7001-WIP7-ipp.patch : "Screen is on but is black" -> ipp *7001-WIP7-link_regs.patch : Ok *7001-WIP7-opp.patch : "Screen is on but is black" -> opp *7001-WIP7-stream_enc_regs.patch: Ok (only removed 7th instance) *7001-WIP7-audio_regs.patch : Ok *7001-WIP7-dmcu_regs.patch : Ok *7001-WIP7-hwseq_registers.patch : 7001-WIP7_no-dce_mem_input_and_no_ipp.patch: "Screen is on but is black" -> opp 7001-WIP7-no-dce_both_no_Xpp.patch: "Screen is on but is black" 7001-WIP7_no-dce_mem_input_and_no_Xpp.patch: CONCLUSION: This commit is the key to solve ipp, opp and hwseq issues "drm/amd/display: Don't attempt to program missing register fields on DCE8" https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/drivers/gpu/drm/amd/display/dc/dce?id=beed42b5bc68e9c37c4474393a2e3dbf6ed4c26b The missing registers in DCE6: ipp_{mask,shift} DEGAMMA_CONTROL__CURSOR2_DEGAMMA_MODE__{MASK,SHIFT} static void dce_ipp_set_degamma( struct input_pixel_processor *ipp, enum ipp_degamma_mode mode) { struct dce_ipp *ipp_dce = TO_DCE_IPP(ipp); uint32_t degamma_type = (mode == IPP_DEGAMMA_MODE_HW_sRGB) ? 1 : 0; ASSERT(mode == IPP_DEGAMMA_MODE_BYPASS || mode == IPP_DEGAMMA_MODE_HW_sRGB); - REG_SET_3(DEGAMMA_CONTROL, 0, - GRPH_DEGAMMA_MODE, degamma_type, - CURSOR_DEGAMMA_MODE, degamma_type, - CURSOR2_DEGAMMA_MODE, degamma_type); + REG_SET_2(DEGAMMA_CONTROL, 0, + GRPH_DEGAMMA_MODE, degamma_type, + CURSOR_DEGAMMA_MODE, degamma_type); + + if (ipp_dce->ipp_mask->CURSOR2_DEGAMMA_MODE != 0) + REG_SET(DEGAMMA_CONTROL, 0, + CURSOR2_DEGAMMA_MODE, degamma_type); } link_enc_hpd_regs[0].DC_HPD_CONTROL Ok link_enc_regs[0].DP_DPHY_SCRAM_CNTL Ok opp_regs[0].FMT_CLAMP_COMPONENT_R FMT_CLAMP_LOWER_R,FMT_CLAMP_UPPER_R opp_regs[0].FMT_CLAMP_COMPONENT_G FMT_CLAMP_LOWER_G,FMT_CLAMP_UPPER_G opp_regs[0].FMT_CLAMP_COMPONENT_B FMT_CLAMP_LOWER_B,FMT_CLAMP_UPPER_B diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c index 51081d9ae3fb..e0551655c4ad 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c @@ -350,23 +350,25 @@ void dce110_opp_set_clamping( FMT_CLAMP_COLOR_FORMAT, 3); break; case CLAMPING_LIMITED_RANGE_PROGRAMMABLE: - /*Set clamp control*/ - REG_SET_2(FMT_CLAMP_CNTL, 0, - FMT_CLAMP_DATA_EN, 1, - FMT_CLAMP_COLOR_FORMAT, 7); - - /*set the defaults*/ - REG_SET_2(FMT_CLAMP_COMPONENT_R, 0, - FMT_CLAMP_LOWER_R, 0x10, - FMT_CLAMP_UPPER_R, 0xFEF); - - REG_SET_2(FMT_CLAMP_COMPONENT_G, 0, - FMT_CLAMP_LOWER_G, 0x10, - FMT_CLAMP_UPPER_G, 0xFEF); - - REG_SET_2(FMT_CLAMP_COMPONENT_B, 0, - FMT_CLAMP_LOWER_B, 0x10, - FMT_CLAMP_UPPER_B, 0xFEF); + if (REG(FMT_CLAMP_COMPONENT_R)) { + /*Set clamp control*/ + REG_SET_2(FMT_CLAMP_CNTL, 0, + FMT_CLAMP_DATA_EN, 1, + FMT_CLAMP_COLOR_FORMAT, 7); + + /*set the defaults*/ + REG_SET_2(FMT_CLAMP_COMPONENT_R, 0, + FMT_CLAMP_LOWER_R, 0x10, + FMT_CLAMP_UPPER_R, 0xFEF); + + REG_SET_2(FMT_CLAMP_COMPONENT_G, 0, + FMT_CLAMP_LOWER_G, 0x10, + FMT_CLAMP_UPPER_G, 0xFEF); + + REG_SET_2(FMT_CLAMP_COMPONENT_B, 0, + FMT_CLAMP_LOWER_B, 0x10, + FMT_CLAMP_UPPER_B, 0xFEF); + } break; default: break; opp_{mask,shift}FMT_BIT_DEPTH_CONTROL__FMT_TRUNCATE_MODE__{MASK,SHIFT} diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c index 51081d9ae3fb..4f0aea44b6e4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c @@ -108,37 +108,39 @@ static void set_truncation( const struct bit_depth_reduction_params *params) { /*Disable truncation*/ - REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, + REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, 0, - FMT_TRUNCATE_DEPTH, 0, - FMT_TRUNCATE_MODE, 0); + FMT_TRUNCATE_DEPTH, 0); + if (opp110->opp_mask->FMT_TRUNCATE_MODE != 0) + REG_UPDATE(FMT_BIT_DEPTH_CONTROL, + FMT_TRUNCATE_MODE, 0); if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) { /* 8bpc trunc on YCbCr422*/ if (params->flags.TRUNCATE_DEPTH == 1) - REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, + REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, 1, - FMT_TRUNCATE_DEPTH, 1, - FMT_TRUNCATE_MODE, 0); + FMT_TRUNCATE_DEPTH, 1); else if (params->flags.TRUNCATE_DEPTH == 2) /* 10bpc trunc on YCbCr422*/ - REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, + REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, 1, - FMT_TRUNCATE_DEPTH, 2, - FMT_TRUNCATE_MODE, 0); + FMT_TRUNCATE_DEPTH, 2); return; } /* on other format-to do */ if (params->flags.TRUNCATE_ENABLED == 0) return; /*Set truncation depth and Enable truncation*/ - REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, + REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, 1, FMT_TRUNCATE_DEPTH, - params->flags.TRUNCATE_DEPTH, - FMT_TRUNCATE_MODE, - params->flags.TRUNCATE_MODE); + params->flags.TRUNCATE_DEPTH); + if (opp110->opp_mask->FMT_TRUNCATE_MODE != 0) + REG_UPDATE(FMT_BIT_DEPTH_CONTROL, + FMT_TRUNCATE_MODE, + params->flags.TRUNCATE_MODE); } FMT_CONTROL__FMT_SUBSAMPLING_MODE FMT_CONTROL__FMT_SUBSAMPLING_ORDER Ok opp_{mask,shift}FMT_CONTROL__FMT_SRC_SELECT__{MASK,SHIFT} Keep AS-IS because it was missing in DCE8 too audio_mask.DCCG_AUDIO_DTO2_USE_512FBR_DTO Ok dmcu_regs.SMU_INTERRUPT_CONTROL__DC_SMU_INT_ENABLE Ok hwseq_reg[0].BLND_CONTROL; hwseq_{mask,shift}.BLND_CONTROL_BLND_MODE hwseq_reg[0].BLND_V_UPDATE_LOCK; hwseq_{mask,shift}.{BLND_DCP_GRPH_V_UPDATE_LOCK,BLND_SCL_V_UPDATE_LOCK,BLND_DCP_GRPH_SURF_V_UPDATE_LOCK} dce_mem_input.c DPG_PIPE_ARBITRATION_CONTROL3__NB_PSTATE_CHANGE_WATERMARK_MASK_{MASK,SHIFT} DPG_PIPE_ARBITRATION_CONTROL3__STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK_{MASK,SHIFT} GRPH_CONTROL__GRPH_MICRO_TILE_MODE_MASK dce_transform.c xfm_regs OUT_CLAMP_CONTROL_R_CR OUT_CLAMP_CONTROL_R_CR__OUT_CLAMP_MIN_R_CR_MASK OUT_CLAMP_CONTROL_R_CR__OUT_CLAMP_MAX_R_CR_MASK OUT_CLAMP_CONTROL_G_Y OUT_CLAMP_CONTROL_G_Y__OUT_CLAMP_MIN_G_Y_MASK OUT_CLAMP_CONTROL_G_Y__OUT_CLAMP_MAX_G_Y_MASK OUT_CLAMP_CONTROL_B_CB OUT_CLAMP_CONTROL_B_CB__OUT_CLAMP_MIN_B_CB_MASK OUT_CLAMP_CONTROL_B_CB__OUT_CLAMP_MAX_B_CB_MASK SCL_MODE SCL_MODE__SCL_MODE_MASK SCL_HORZ_FILTER_INIT SCL_HORZ_FILTER_INIT__SCL_H_INIT_INT_MASK SCL_HORZ_FILTER_INIT__SCL_H_INIT_FRAC_MASK xfm_mask.DATA_FORMAT__ALPHA_EN xfm_mask.DATA_FORMAT__PIXEL_EXPAN_MODE xfm_mask.DATA_FORMAT__PIXEL_DEPTH__SHIFT SCL_CONTROL__SCL_BOUNDARY_MODE_{MASK,SHIFT} SCL_TAP_CONTROL__SCL_V_NUM_OF_TAPS_{MASK,SHIFT} SCL_TAP_CONTROL__SCL_H_NUM_OF_TAPS_{MASK,SHIFT} SCL_UPDATE__SCL_COEF_UPDATE_COMPLETE_{MASK,SHIFT} drivers/gpu/drm/amd/display/dc/dm_services.h:60 #define DM_CHECK_ADDR_0 drivers/gpu/drm/amd/display/dc/dm_services.h:82 printk(KERN_INFO "cgs_write_register(ctx->cgs_device, address=%x, value=%x\n", address, value) drivers/gpu/drm/amd/display/dc/dm_services.h:123 /* ASSERT(mask != 0); */ if (mask != 0) printk(KERN_INFO "Valid mask %x\n", mask); else printk(KERN_WARNING "Invalid mask %x\n", mask); v4: What to try now? The trace of amdgpu_dm:amdgpu_dc_wreg for the working dce8 header version suggests to check mmLB_DATA_FORMAT, mmLB_MEMORY_CTRL processing The register lists are flexible for each DCE asic type, so check the transforms O Rework MI_DMIF_PG_MASK_SH_DCE6(mask_sh, blk) in drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h Y Add SRI(DC_LB_MEM_SIZE, LB, id), \ to #define XFM_COMMON_REG_LIST_DCE60(id) drm/amd/display/dc/dce/dce_transform.h @159 Y Add XFM_SF(DATA_FORMAT, INTERLEAVE_EN, mask_sh), \ to #define XFM_COMMON_MASK_SH_LIST_DCE60(mask_sh) drm/amd/display/dc/dce/dce_transform.h @271 Y Add XFM_SF(DC_LB_MEM_SIZE, DC_LB_MEMORY_SIZE, mask_sh), \ to #define XFM_COMMON_MASK_SH_LIST_DCE60(mask_sh) \ Y Add INTERLEAVE_EN to #define XFM_REG_FIELD_LIST(type) \ ? Rework dce_mem_input_registers {} in drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h ? Rework @@ -286,6 +358,7 @@ struct dce_mem_input_registers {} ? Remove dce60_mem_input_construct and use dce_mem_input_construct ? Remove dce60_transform_construct and use dce_transform_construct O Expand all /* Registers that spilled out of sid.h */ in drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h O Remove the duplicate DPG_PIPE_ARBITRATION_CONTROL3 definitions in drm/amd/include/asic_reg/dce/dce_6_0_d.h LVDS discussion https://bugs.freedesktop.org/show_bug.cgi?id=105880 menu Status #dri-develX hwentlanX [21:18] Hi Harry, [21:20] Hi Mauro [21:21] so sorry I haven't had time to try to give you more info on those DCE 6 registers [21:23] Hi Harry, thanks for chat [21:23] I wanted to tell you that the IRQ vblank issue is solved [21:24] now I'm proceeding (even if at a slow pace using some hours in the evenings and in the weekend [21:24] ) [21:25] that's great work and good to hear [21:26] with the necessary changes to use the dce_6_d.h and dce_6_0_sh_mask.h [21:26] registers/masks [21:27] in the added dce60/dce60_resources.c source [21:27] and I wanted to check if my approach is correct [21:28] WIP: drm/amd/display: dc/dce: preliminar DCE6 macro fixes [21:29] here follows the description of changes: [21:29] Add support for DCE6 specific macros CLK_COMMON_REG_LIST_DCE60_BASE(), XFM_COMMON_REG_LIST_DCE60(), XFM_COMMON_MASK_SH_LIST_DCE60(), OPP_DCE_60_REG_LIST(), OPP_COMMON_MASK_SH_LIST_DCE_60(), IPP_DCE60_MASK_SH_LIST_DCE_COMMON_BASE() [21:30] plus use of dce6's DPG_PIPE_ARBITRATION_CONTROL3 registers for watermarks [21:31] the way these macros are set up the _DCE_BASE is generally intended for any registers common to all DCE generations [21:31] and with integration of the register/masks which are missing in dce6 headers, but present in radeonsi sid.h [21:32] so you might want to simply name it CLK_COMMON_REG_LIST_DCE60 and inside include the CLK_COMMON_REG_LIST_DCE_BASE if that's possible for DCE6 [21:33] but that's just a nitpick... otherwise this approach sounds good to me [21:33] In this moment I'm adding the macros as dedicated not to mess with existing code DCE80 to DCE110 [21:34] and I saw that the same code style was applied for cases where changes were too intrusive in *COMMON* macros [21:35] that's why DCE60 appears explicitly and changes are more easy to read [21:35] Ok, I will proceed with that part, but I have some doubts [21:36] Should I just skip the macro entries where registers are not present in dce_6*.h headers? [21:36] that's absolutely right. if the differences are too big best to just roll a DCE60 specific version [21:36] yes, you should be able to just skip those [21:37] In my understanding when I was using dce8 headers all the code for non existing registers was just producing "no op" [21:38] should I worry about the renamed registed of course and use the registers/logic found in amdgpu corresponding code [21:39] Almost finished the chat session [21:39] The other doubt I have is about the status of LVDS and VGA connectors [21:40] I have seen that Alex Deucher has now a patch for LVDS support [21:40] here https://bugs.freedesktop.org/attachment.cgi?id=141128 [21:40] but what about VGA connector? [21:41] there's still no update on vga [21:42] to be honest, i doubt i'll find time for it and it's not on our official roadmap [21:42] yeah, generally we're doing a no op if a register doesn't exist on a HW generation [21:43] Is it a good approach for me to replicate the LVDS patch changes or is it more complex than that? [21:43] the idea with these register structs and macros defining them is that we can re-use common code to program them, even though the actual register offsets might be different and even though some registers don't exist on some HW [21:43] i think you should be able to just replicate the LVDS stuff for DCE 6 [21:44] I don't know if for VGA some encoder code is necessary on top of handling connector cases in addition to LVDS [21:46] but in this old tree https://cgit.freedesktop.org/~agd5f/linux/tree/drivers/gpu/drm/amd/dal?h=amd-15.31 [21:47] for vga we'll need analog encoder support [21:47] good find :) [21:48] Alex Deucher commented in bugzilla that "I think some of the older DAL2 code had some support for these encoders. You could use that or the non-DC code as reference. Old DAL2 code for reference: https://cgit.freedesktop.org/~agd5f/linux/tree/drivers/gpu/drm/amd/dal?h=amd-15.31 [21:49] it's not quite dal2. that was all closed-source, but it was very much based on it. [21:49] i'm not sure if i remember right, but i'm not sure we've ever tested the VGA code with that driver (even though we implemented it) [21:50] and is there a way to identity the commits in that tree or in other trees? [21:50] by means of VGA or DAC? [21:50] or 'connector' [21:52] git log --grep VGA -- drivers/gpu/drm/amd/dal [21:52] or git log -- drivers/gpu/drm/amd/dal/encoder/analog_encoder.c (or other relevant files) [21:52] might want to grep for 'analog' in the git log for dal as well [21:53] Many thanks Harry! I have sufficient material to proceed [21:53] no problem [21:53] Sorry if I'm taking so long to complete [21:53] thanks to you. you're doing some great work [21:54] and thanks for you time and kindness [21:54] If I see you at xdc again I'll buy you a beer [21:54] Just one last question which nickname uses Alex Deucher in here? [21:55] agd5f [21:55] thanks, same as the one used in cgit [21:56] Yup [21:56] I will catch with him for connector code, in case I need, sometimes I just worry too much instead of just trying [21:57] Have a nice afternoon and evening [21:57] Thanks, you too On dce6 registers: [20:31] Hi Harry, [20:33] Hi Mauro [20:33] I've completed the preliminary build with dce6 headers by defining all ad hoc register macros [20:34] I found some register mismatches/renames [20:35] and I tried to fix them as I could, but now the screen is blank [20:36] I'll try to ask questions to identify the problem [20:37] you were able to light up with your previous patch set? [20:37] Yes, with the V_BLANK irq fixed (my patches v3) [20:38] but still based on dce8 headers [20:39] the only problem I see is a temporary shift on the left of all image when playing Sky Force Reloaded, but only in precise instant when there are lots of explosions [20:42] apart from that the only essential register differences to be sanitized are: [20:42] might be worthwhile to trace the register programming and see what differs [20:42] there's a amdgpu_dc_wreg trace event that should log register writes [20:42] dce8 LB_DATA_FORMAT/ dce6 DATA_FORMAT [20:44] dce8 DPG_WATERMARK_MASK_CONTROL / dce6 DPG_PIPE_ARBITRATION_CONTROL3 (is it? ) [20:46] dce8 LB_MEMORY_CTRL / dce6 LB_MEMORY_SPLIT (missing mask and shifts, are they identical to LB_MEMORY_CTRL ones?) [20:50] dce6 doesn't seem to have LB_MEMORY_SIZE in LB_MEMORY_SPLIT [20:50] that one seams to be in the LB_MEM_SIZE register [20:50] with mask 7ff (rather than fff) [20:51] that may be missing now [20:52] PIPE_ARBITRATION_CONTROL3 is also not quite like WATERMARK_MASK_CONTROL [20:53] it only has URGENCY_WATERMARK_MASK at bit 0x00030000L [20:55] but I'm unable to find LB_MEM_SIZE register in include/asic_reg/dce/dce_6_0_d.h [20:56] I had got the URGENCY_WATERMARK_MASK wrong because I copied from dce8's DPG_WATERMARK_MASK_CONTROL [20:56] that is two possible root causes already [20:57] for watermarks i recommend to set safe watermarks. we program this (in sequence) for our windows dce6 driver: [20:57] https://www.irccloud.com/pastebin/WxfvOAfD/ [20:58] How may I use amdgpu_dc_wreg trace if the screen is not appearing, is it to trace my v3 patches with dce8 headers, correct? [20:59] i haven't really worked with the traces but usually i'd boot with modprobe.blacklist=amdgpu to console, then set up my logging over ssh, then "modprobe amdgpu" [21:00] worst case you can add a printk instead of the traces and simple get dmesg over ssh [21:02] ah, thanks a lot, in my android-x86 setup I could use serial console [21:02] for dce6 LB registers: [21:02] https://www.irccloud.com/pastebin/LvChUynw/ [21:03] Many thanks!!!! [21:04] No problem. Hope it helps [21:04] What about DATA_FORMAT in dce6 is it just a rename with no changes in the masks? [21:06] Then I have some doubt on the missing DPREFCLK_CNTL in dce_clk_mgr.h [21:07] which was present in dce8 [21:08] Oh, I forgot an important thing how do I handle the case of dce8 DPG_WATERMARK_MASK_CONTROL / dce6 DPG_PIPE_ARBITRATION_CONTROL3 together [21:10] in dce/dce_mem_input.c [21:10] ? [21:11] INTERLEAVE_EN in DATA_FORMAT (which i think is the only one we care about) is shifted: [21:11] https://www.irccloud.com/pastebin/Og7LnBww/ [21:11] Will if (REG(DPG_WATERMARK_MASK_CONTROL)) {...} else {...} work? [21:12] for dce8 it's on bit 0 [21:13] if registers differ enough we usually create an ASIC-specific function [21:14] like program_urgency_watermark() but named program_urgency_watermark_dce60( ), correct? [21:14] it looks like dce6 differs a fair bit [21:15] yeah, ideally with a new dce60/dce60_mem_input.c [21:16] see see dce80_tg_funcs for an example. it mostly uses common definitions for functions (all the dce110_ ones) but assigns some function pointers to dce80 specific versions [21:17] the other way could have been using switch (asic_type) but thay way is not used [21:19] Do you want to try (in spare time, for playing and relaxing) an oreo-x86 iso with kernel-5.0rc5/rc6 with [21:19] for the DPREFCLK_CNTL, i'm really no expert on clocks. i think you're probably fine without it [21:19] Yes, if it does not exist at all, I should be ok [21:20] ...oreo-x86 iso with kernel-5.0rc5/rc6 with drm_hwcomposer/gbm_gralloc and the patches? [21:23] Many many thanks, for me it is a joy to finalize the patches [21:23] I'd have to find a dce6 card but I'd be curious to try out. [21:23] Not sure how much time I'd find and how relaxing it'd be :) [21:24] You're doing excellent work. I tried Android x86 after your talk and was quite impressed [21:24] As a side note, there are games which are good for that, even one of our directors at Vodafone [21:24] plays with Clash Royale [21:25] fast games and you can stop before it's too late :-) [21:26] besides that oreo-x86 r1 is in good shape for all radeon to amdgpu ASICs [21:27] even Vulkan can be used becasue of a dma-bufs implementation (drm_framebuffer) [21:27] but I like to finish what I started [21:28] to be able to use also drm_hwcomposer [21:30] As soon I get back the light on screen, I'll keep you posted [21:31] and start with NUTMEG and DAC encoder [21:31] Good afternoon (good night for me) sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev sudo apt install libgtk2.0-dev libglib2.0-dev libglade2-dev cp /boot/config-$(uname -r) .config make gconfig [Enable in graphics drivers Display CONFIG_AMD_DC_SI=y] make -j `getconf _NPROCESSORS_ONLN` deb-pkg LOCALVERSION=-amddcsi sudo dpkg -i linux-headers-5.0.0-amddcsi_5.0.0-amddcsi-1_amd64.deb \ linux-image-5.0.0-amddcsi_5.0.0-amddcsi-1_amd64.deb linux-libc-dev_5.0.0-amddcsi-1_amd64.deb TRACING the register writes --------------------------- https://riptutorial.com/linux-kernel/example/11983/tracing-i2c-events trace_event=amdgpu_dm:amdgpu_dc_wreg Android Terminal su echo amdgpu_dm:amdgpu_dc_wreg > /sys/kernel/debug/tracing/set_event or echo 1 > /sys/kernel/debug/tracing/events/amdgpu_dm/amdgpu_dc_wreg/enable echo 1 > /sys/kernel/debug/tracing/tracing_on cat /sys/kernel/debug/tracing/trace su echo amdgpu:amdgpu_mm_wreg > /sys/kernel/debug/tracing/set_event echo 1 > /sys/kernel/debug/tracing/tracing_on cat /sys/kernel/debug/tracing/trace Ubuntu terminal sudo bash -c "echo amdgpu_dm:amdgpu_dc_wreg > /sys/kernel/debug/tracing/set_event" sudo bash -c "echo 1 > /sys/kernel/debug/tracing/tracing_on" Also check: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/radeon/sid.h https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/amd/amdgpu/sid.h https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/amd/amdgpu/si_enums.h https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c DPG_PIPE_ARBITRATION_CONTROL3.URGENCY_WATERMARK_MASK = 1 DPG_PIPE_URGENCY_CONTROL.LOW_WATERMARK = 0xffff DPG_PIPE_URGENCY_CONTROL.HIGH_WATERMARK = 0xffff DPG_PIPE_ARBITRATION_CONTROL3.URGENCY_WATERMARK_MASK = 2 DPG_PIPE_URGENCY_CONTROL.LOW_WATERMARK = 0xffff DPG_PIPE_URGENCY_CONTROL.HIGH_WATERMARK = 0xffff LB0.PRIORITY_A_CNT.PRIORITY_MARK_A = 0x7fff LB0.PRIORITY_B_CNT.PRIORITY_MARK_B = 0x7fff #define mmDC_LB_MEMORY_SPLIT 0x1AC3 #define mmLB0_DC_LB_MEMORY_SPLIT 0x1AC3 #define mmLB1_DC_LB_MEMORY_SPLIT 0x1DC3 #define mmLB2_DC_LB_MEMORY_SPLIT 0x40C3 #define mmLB3_DC_LB_MEMORY_SPLIT 0x43C3 #define mmLB4_DC_LB_MEMORY_SPLIT 0x46C3 #define mmLB5_DC_LB_MEMORY_SPLIT 0x49C3 #define mmDC_LB_MEM_SIZE 0x1AC4 #define mmLB0_DC_LB_MEM_SIZE 0x1AC4 #define mmLB1_DC_LB_MEM_SIZE 0x1DC4 #define mmLB2_DC_LB_MEM_SIZE 0x40C4 #define mmLB3_DC_LB_MEM_SIZE 0x43C4 #define mmLB4_DC_LB_MEM_SIZE 0x46C4 #define mmLB5_DC_LB_MEM_SIZE 0x49C4 ci_hawaii_p/ci_hawaii_mask.h:69709:#define LB_DATA_FORMAT__INTERLEAVE_EN_MASK 0x00000008L ci_hawaii_p/ci_hawaii_s.h:69709:#define LB_DATA_FORMAT__INTERLEAVE_EN__SHIFT 0x00000003 drm boot logs: ------------------- BIOS signature incorrect 10-09 21:10:12.618 0 0 I modprobe: amdgpu 10-09 21:10:13.027 0 0 I : [drm] amdgpu kernel modesetting enabled. 10-09 21:10:13.027 0 0 I : [drm] initializing kernel modesetting (VERDE 0x1002:0x683F 0x174B:0xE213 0x00). 10-09 21:10:13.027 0 0 I : [drm] register mmio base: 0xFEA80000 10-09 21:10:13.027 0 0 I : [drm] register mmio size: 262144 10-09 21:10:13.027 0 0 I : [drm] add ip block number 0 10-09 21:10:13.027 0 0 I : [drm] add ip block number 1 10-09 21:10:13.028 0 0 I : [drm] add ip block number 2 10-09 21:10:13.028 0 0 I : [drm] add ip block number 3 10-09 21:10:13.028 0 0 I : [drm] add ip block number 4 10-09 21:10:13.028 0 0 I : [drm] add ip block number 5 10-09 21:10:13.028 0 0 I : [drm] add ip block number 6 10-09 21:10:13.054 0 0 I : [drm] BIOS signature incorrect 5b 7 [This happens also with BONAIRE and other chipsets, maybe it's not a problem] NOTE: it's just the UVC and VCE related IP blocks not added because of missing firmware DM_PPLIB: the problem you also observed, it could make sense to print the supported power state clock frequencies as per amdgpu driver. https://lists.freedesktop.org/archives/amd-gfx/2018-July/024302.html 10-09 21:10:14.427 0 0 E : [drm:dm_pp_get_static_clocks [amdgpu]] *ERROR* DM_PPLIB: invalid powerlevel state: 0! NOTE: the Error is not fatal and it does not seem to affect performance in the Benchmarks DOUBT: I think that it would make sense to set powerlevel "state 0" as safe default, while I do not understrand why 0 "invalid power level" is used Anyway it does not represent a real problem. [drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c] @@195 static enum dm_pp_clocks_state pp_to_dc_powerlevel_state( enum PP_DAL_POWERLEVEL max_clocks_state) { switch (max_clocks_state) { case PP_DAL_POWERLEVEL_0: return DM_PP_CLOCKS_DPM_STATE_LEVEL_0; case PP_DAL_POWERLEVEL_1: return DM_PP_CLOCKS_DPM_STATE_LEVEL_1; case PP_DAL_POWERLEVEL_2: return DM_PP_CLOCKS_DPM_STATE_LEVEL_2; case PP_DAL_POWERLEVEL_3: return DM_PP_CLOCKS_DPM_STATE_LEVEL_3; case PP_DAL_POWERLEVEL_4: return DM_PP_CLOCKS_DPM_STATE_LEVEL_4; case PP_DAL_POWERLEVEL_5: return DM_PP_CLOCKS_DPM_STATE_LEVEL_5; case PP_DAL_POWERLEVEL_6: return DM_PP_CLOCKS_DPM_STATE_LEVEL_6; case PP_DAL_POWERLEVEL_7: return DM_PP_CLOCKS_DPM_STATE_LEVEL_7; default: DRM_ERROR("DM_PPLIB: invalid powerlevel state: %d!\n", max_clocks_state); return DM_PP_CLOCKS_STATE_INVALID; } } ... @@456 bool dm_pp_get_static_clocks( const struct dc_context *ctx, struct dm_pp_static_clock_info *static_clk_info) { struct amdgpu_device *adev = ctx->driver_context; struct amd_pp_clock_info pp_clk_info = {0}; int ret = 0; if (adev->powerplay.pp_funcs->get_current_clocks) ret = adev->powerplay.pp_funcs->get_current_clocks( adev->powerplay.pp_handle, &pp_clk_info); if (ret) return false; static_clk_info->max_clocks_state = pp_to_dc_powerlevel_state(pp_clk_info.max_clocks_state); [here static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock * 10; static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock * 10; return true; } Possible problem with link encoder: 10-09 21:10:14.427 0 0 W [drm] dce110_link_encoder_construct: Failed to get encoder_cap_info from VBIOS with error code 4! 10-09 21:10:14.427 0 0 W [drm] dce110_link_encoder_construct: Failed to get encoder_cap_info from VBIOS with error code 4! NOTE: the warning also appears with Tonga and Vega, it does not seem to cause issues, even if the message log is almost useless. Possible problem with pageflip irq/events: 10-09 21:11:08.699 0 0 D [drm:prepare_flip_isr [amdgpu]] crtc: 0, pflip_stat:AMDGPU_FLIP_SUBMITTED 10-09 21:11:08.699 0 0 D : [drm:dm_pflip_high_irq [amdgpu]] dm_pflip_high_irq - crtc :0[5eb4ac74], pflip_stat:AMDGPU_FLIP_NONE 10-09 21:11:08.699 0 0 D : [drm:drm_atomic_state_default_clear [drm]] Clearing atomic state 6a2561bd 10-09 21:11:08.699 0 0 D : [drm:dm_pflip_high_irq [amdgpu]] amdgpu_crtc->pflip_status = 0 !=AMDGPU_FLIP_SUBMITTED(2) on crtc:0[5eb4ac74] 10-09 21:11:08.699 0 0 D : [drm:__drm_atomic_state_free [drm]] Freeing atomic state 6a2561bd Observed problem with "top vblank/pageflip race condition" ---------------------------------------------------------- I have observed with AMD DC a problem of tearing with top vsync, appearing and disappearing, with "two fronts", one with rectangular tearing, and another with triangular/trapezoidal tearing. Images in the attachment show the two fronts. The problem is present with GCN1.0 Southern Islands (Cape Verde, Tahiti), but also with GCN 2nd Generation (Bonaire) so it may be a common problem to DCE8 and DCE6. From maling list: ---------------------- patch02 drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c did not apply but seems kind of benign. WITH THE LINUX TSC FIX (or displayport programming won't work!!!) Very important thing: I run it with the linux tsc fix, or all linux timings will be wrong and no displayport programing will happen. This fix is not in current vanilla amd-staging-drm-next. [Could the TSC problem cause the black screen/restart on a Lenovo G50-45 AMD Radeon R4 (Beema) with AMD DC? But this is a problem with GCN 2nd gen, not of the AMD DC SI patches] I did hack a bit your patch set on amd-staging-drm-next to make it go through the asic init and I managed to get a x11 display with lines kind of garbled, but you can still understand easily what's on the screen. It _seems_ there is not that much additional work to do in order to make it properly work. [Do you know what could be the problem, how to debug it and troubleshoot it?] Did add SI handling in some raven firmware loader function. In drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c, "load_dmcu_fw" function augmented with SI chip asic_type. [Is it already in the linux.patch?] I checked the kernel log, and like you said, I got errors in DM_PPLIB due to an invalid powerlevel and atombios/vbios table parsing regarding connectors. [I have not seen the problem with connectors, yet] I should add that the "timings" and bandwidths computations are based on framebuffer tiling (for cache efficiency) and if there is audio data in the link stream (displayport or hdmi). In DC, if dce6 is not dealed properly in this "timings" and "bandwidth" code, mecanic dce8->dce6 mapping may work. The lines may be garbled in your driver code because, if I recall properly, "line buffer" programing in dce8 is not the same than in dce6 (look for registers with the "LB" abbreviation). Or some slight differences in framebuffer tiling. [Will check these in the header/masks for dce_v6_0] UVD/VCE on SI with amdgpu would need new firmware. And so far AMD never had time to actually look into releasing that firmware [Has something changed?] For reference Sylvain's radeon driver for DCE6: https://git.launchpad.net/linux-gpu-amd-si/log/ in order to check all aspects with display been covered. [Additional step of review of AMD DC patches, after having compared with Raven DCN 1.0 and DCE8 Bonaire patches] DOUBTS: ------- Does Hainan have DCE6 or not? No, it would require Virtual DCE block Is it better to try to use the DCE6 header/masks definitions dc/dce60_resources and dc/irq in order to have code path separation? Yes RELEVANT COMMITS which could make sense to split: ------------------------------------------------- drm/amdgpu/cik: add IP modules for DC for APUs => drm/amdgpu/si: add IP modules for DC drm/amd: add dce8 enum register header => drm/amd: add dce6 enum register header drm/amd/display/dc: add resource support for DCE8=> drm/amd/display/dc: add resource support for DCE6 drm/amd/dal: Implement irq for dce8 => drm/amd/display: Implement irq for dce6 CHECKLIST: --------- 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 8c821854a19a..efd5d7ea2a77 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -514,6 +514,11 @@ static int load_dmcu_fw(struct amdgpu_device *adev) const struct dmcu_firmware_header_v1_0 *hdr; switch(adev->asic_type) { +#if defined(CONFIG_DRM_AMD_DC_SI) + case CHIP_TAHITI: + case CHIP_PITCAIRN: + case CHIP_VERDE: + case CHIP_OLAND: + case CHIP_HAINAN: /* NOTE: HAINAN was removed * +#endif case CHIP_BONAIRE: case CHIP_HAWAII: case CHIP_KAVERI: [drivers/gpu/drm/amd/display/dc/dce/dce_transform.h] +#if defined(CONFIG_DRM_AMD_DC_SI) +#define XFM_COMMON_REG_LIST_DCE60(id) \ + XFM_COMMON_REG_LIST_DCE_BASE(id), \ + SRI(DCFE_MEM_LIGHT_SLEEP_CNTL, CRTC, id) +#endif +#if defined(CONFIG_DRM_AMD_DC_SI) +#define XFM_COMMON_MASK_SH_LIST_DCE60(mask_sh) \ + XFM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \ + OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, REGAMMA_LUT_LIGHT_SLEEP_DIS, mask_sh),\ + OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, DCP_LUT_LIGHT_SLEEP_DIS, mask_sh),\ + OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, REGAMMA_LUT_MEM_PWR_STATE, mask_sh) +#endif [drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h] +#if defined(CONFIG_DRM_AMD_DC_SI) +#define LE_DCE60_REG_LIST(id)\ + SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ + LE_COMMON_REG_LIST_BASE(id) +#endif [drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h] ./drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h:49:#define DMCU_DCE80_REG_LIST() \ [drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h] ./drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h:34:#define HWSEQ_DCEF_REG_LIST_DCE8() \ ./drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h:96:#define HWSEQ_DCE8_REG_LIST() \ ./drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h:97: HWSEQ_DCEF_REG_LIST_DCE8(), \ ./drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h:313:#define HWSEQ_DCE8_MASK_SH_LIST(mask_sh)\ [VBLANK IRQ fixed] /home/utente/oreo-x86_kernel/kernel/drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.c:268:1: error: 'mmCRTC0_CRTC_VERTICAL_INTERRUPT0_CONTROL' undeclared here (not in a function) /home/utente/oreo-x86_kernel/kernel/drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.c:268:2: error: 'CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_INT_ENABLE_MASK' undeclared here (not in a function) /home/utente/oreo-x86_kernel/kernel/drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.c:268:2: error: 'CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_CLEAR_MASK' undeclared here (not in a function) /home/utente/oreo-x86_kernel/kernel/drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.c:269:1: error: 'mmCRTC1_CRTC_VERTICAL_INTERRUPT0_CONTROL' undeclared here (not in a function) /home/utente/oreo-x86_kernel/kernel/drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.c:270:1: error: 'mmCRTC2_CRTC_VERTICAL_INTERRUPT0_CONTROL' undeclared here (not in a function) /home/utente/oreo-x86_kernel/kernel/drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.c:271:1: error: 'mmCRTC3_CRTC_VERTICAL_INTERRUPT0_CONTROL' undeclared here (not in a function) /home/utente/oreo-x86_kernel/kernel/drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.c:272:1: error: 'mmCRTC4_CRTC_VERTICAL_INTERRUPT0_CONTROL' undeclared here (not in a function) /home/utente/oreo-x86_kernel/kernel/drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.c:273:1: error: 'mmCRTC5_CRTC_VERTICAL_INTERRUPT0_CONTROL' undeclared here (not in a function) /home/utente/oreo-x86_kernel/kernel/scripts/Makefile.build:305: recipe for target 'drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.o' failed make[5]: *** [drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dce60/irq_service_dce60.o] Error 1 -CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_INT_ENABLE_MASK +?seems trivial but who knows? -CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_CLEAR_MASK +?seems trivial but who knows? NOTE: I think this is the very basic VBI Vertical Blank Interrupt signal handling, which should be there in dce6 registers/masks, but some hint/documentation is necessary for me. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c /* Register IRQ sources and initialize IRQ callbacks */ @@ -49,6 +49,16 @@ +#if defined(CONFIG_DRM_AMD_DC_SI) +#include "ivsrcid/irqsrcs_dce_6_0.h" + +#include "raven1/DCN/dce_6_0_offset.h" +#include "raven1/DCN/dce_6_0_sh_mask.h" +#include "vega10/soc15ip.h" + +#include "soc15_common.h" +#endif ATTENTION NOTE: the above DCN ad hoc treatment is not necessary, there are only two irq handled in dc/irq/dce80 to be mapped in dc/irq/dce60 @@ -930,7 +940,8 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) @@ -1003,6 +1014,92 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) @@ -1172,6 +1269,14 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) @@ -1447,6 +1552,14 @@ static int dm_early_init(void *handle) [GFX6 programming???] @@ 2089 /* Fill GFX6 params */ MISSING!!! /* Fill GFX6 params */ if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) { unsigned int bankw, bankh, mtaspect, tile_split, num_banks; bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH); bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT); mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT); tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT); num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS); /* XXX fix me for VI */ plane_state->tiling_info.gfx6.num_banks = num_banks; plane_state->tiling_info.gfx6.array_mode = DC_ARRAY_2D_TILED_THIN1; plane_state->tiling_info.gfx6.tile_split = tile_split; plane_state->tiling_info.gfx6.bank_width = bankw; plane_state->tiling_info.gfx6.bank_height = bankh; plane_state->tiling_info.gfx6.tile_aspect = mtaspect; plane_state->tiling_info.gfx6.tile_mode = DC_ADDR_SURF_MICRO_TILING_DISPLAY; } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_1D_TILED_THIN1) { plane_state->tiling_info.gfx6.array_mode = DC_ARRAY_1D_TILED_THIN1; } plane_state->tiling_info.gfx6.pipe_config = AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); NOTE: check the plane model somewhere ? [Bandwidth and Watermarks] drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -3,8 +3,16 @@ # It calculates Bandwidth and Watermarks values for HW programming drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -39,6 +39,9 @@ @@ -69,6 +72,11 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) @@ -105,6 +113,13 @@ struct resource_pool *dc_create_resource_pool( @@ -1188,6 +1203,10 @@ static int acquire_first_free_pipe( 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_SI) + #define ABM_DCN6_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_SI) + #define ABM_MASK_SH_LIST_DCE6(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 + drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -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_SI) + 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 pixel 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 + 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_SI) +#define CS_COMMON_REG_LIST_DCE6_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_DCE6(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 + 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_SI) +#define CLK_DCE6_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 + drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h 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_SI) +#define HWSEQ_DCE6_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_SI) /* seems just a commented line */ + /* 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_SI) +#define HWSEQ_DCE6_MASK_SH_LIST(mask_sh)\ + HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\ + HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, OTG0_) +#endif + 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_DCE60_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_DCE60_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 + 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_SI) +#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_SI) +#define SE_COMMON_MASK_SH_LIST_DCE60(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; drivers/gpu/drm/amd/display/include/dal_asic_id.h @@ -109,6 +109,19 @@ drivers/gpu/drm/amd/display/include/dal_types.h @@ -39,7 +39,10 @@ enum dce_version {