forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
....@@ -23,6 +23,9 @@
2323 *
2424 */
2525
26
+#include <linux/delay.h>
27
+#include <linux/slab.h>
28
+
2629 #include "core_types.h"
2730 #include "link_encoder.h"
2831 #include "dce_dmcu.h"
....@@ -51,8 +54,16 @@
5154 #define PSR_SET_WAITLOOP 0x31
5255 #define MCP_INIT_DMCU 0x88
5356 #define MCP_INIT_IRAM 0x89
54
-#define MCP_DMCU_VERSION 0x90
57
+#define MCP_SYNC_PHY_LOCK 0x90
58
+#define MCP_SYNC_PHY_UNLOCK 0x91
59
+#define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */
5560 #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L
61
+
62
+// PSP FW version
63
+#define mmMP0_SMN_C2PMSG_58 0x1607A
64
+
65
+//Register access policy version
66
+#define mmMP0_SMN_C2PMSG_91 0x1609B
5667
5768 static bool dce_dmcu_init(struct dmcu *dmcu)
5869 {
....@@ -214,9 +225,6 @@
214225 link->link_enc->funcs->psr_program_secondary_packet(link->link_enc,
215226 psr_context->sdpTransmitLineNumDeadline);
216227
217
- if (psr_context->psr_level.bits.SKIP_SMU_NOTIFICATION)
218
- REG_UPDATE(SMU_INTERRUPT_CONTROL, DC_SMU_INT_ENABLE, 1);
219
-
220228 /* waitDMCUReadyForCmd */
221229 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
222230 dmcu_wait_reg_ready_interval,
....@@ -316,38 +324,11 @@
316324 return;
317325 }
318326
319
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
320
-static void dcn10_get_dmcu_state(struct dmcu *dmcu)
321
-{
322
- struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
323
- uint32_t dmcu_state_offset = 0xf6;
324
-
325
- /* Enable write access to IRAM */
326
- REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
327
- IRAM_HOST_ACCESS_EN, 1,
328
- IRAM_RD_ADDR_AUTO_INC, 1);
329
-
330
- REG_WAIT(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, 0, 2, 10);
331
-
332
- /* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */
333
- REG_WRITE(DMCU_IRAM_RD_CTRL, dmcu_state_offset);
334
-
335
- /* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
336
- dmcu->dmcu_state = REG_READ(DMCU_IRAM_RD_DATA);
337
-
338
- /* Disable write access to IRAM to allow dynamic sleep state */
339
- REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
340
- IRAM_HOST_ACCESS_EN, 0,
341
- IRAM_RD_ADDR_AUTO_INC, 0);
342
-}
343
-
327
+#if defined(CONFIG_DRM_AMD_DC_DCN)
344328 static void dcn10_get_dmcu_version(struct dmcu *dmcu)
345329 {
346330 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
347331 uint32_t dmcu_version_offset = 0xf1;
348
-
349
- /* Clear scratch */
350
- REG_WRITE(DC_DMCU_SCRATCH, 0);
351332
352333 /* Enable write access to IRAM */
353334 REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
....@@ -359,83 +340,132 @@
359340 /* Write address to IRAM_RD_ADDR and read from DATA register */
360341 REG_WRITE(DMCU_IRAM_RD_CTRL, dmcu_version_offset);
361342 dmcu->dmcu_version.interface_version = REG_READ(DMCU_IRAM_RD_DATA);
362
- dmcu->dmcu_version.year = ((REG_READ(DMCU_IRAM_RD_DATA) << 8) |
343
+ dmcu->dmcu_version.abm_version = REG_READ(DMCU_IRAM_RD_DATA);
344
+ dmcu->dmcu_version.psr_version = REG_READ(DMCU_IRAM_RD_DATA);
345
+ dmcu->dmcu_version.build_version = ((REG_READ(DMCU_IRAM_RD_DATA) << 8) |
363346 REG_READ(DMCU_IRAM_RD_DATA));
364
- dmcu->dmcu_version.month = REG_READ(DMCU_IRAM_RD_DATA);
365
- dmcu->dmcu_version.date = REG_READ(DMCU_IRAM_RD_DATA);
366347
367348 /* Disable write access to IRAM to allow dynamic sleep state */
368349 REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
369350 IRAM_HOST_ACCESS_EN, 0,
370351 IRAM_RD_ADDR_AUTO_INC, 0);
352
+}
371353
372
- /* Send MCP command message to DMCU to get version reply from FW.
373
- * We expect this version should match the one in IRAM, otherwise
374
- * something is wrong with DMCU and we should fail and disable UC.
375
- */
354
+static void dcn10_dmcu_enable_fractional_pwm(struct dmcu *dmcu,
355
+ uint32_t fractional_pwm)
356
+{
357
+ struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
358
+
359
+ /* Wait until microcontroller is ready to process interrupt */
376360 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
377361
378
- /* Set command to get DMCU version from microcontroller */
362
+ /* Set PWM fractional enable/disable */
363
+ REG_WRITE(MASTER_COMM_DATA_REG1, fractional_pwm);
364
+
365
+ /* Set command to enable or disable fractional PWM microcontroller */
379366 REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,
380
- MCP_DMCU_VERSION);
367
+ MCP_BL_SET_PWM_FRAC);
381368
382369 /* Notify microcontroller of new command */
383370 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
384371
385372 /* Ensure command has been executed before continuing */
386373 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
387
-
388
- /* Somehow version does not match, so fail and return version 0 */
389
- if (dmcu->dmcu_version.interface_version != REG_READ(DC_DMCU_SCRATCH))
390
- dmcu->dmcu_version.interface_version = 0;
391374 }
392375
393376 static bool dcn10_dmcu_init(struct dmcu *dmcu)
394377 {
395378 struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
379
+ const struct dc_config *config = &dmcu->ctx->dc->config;
380
+ bool status = false;
381
+ struct dc_context *ctx = dmcu->ctx;
382
+ unsigned int i;
383
+ // 5 4 3 2 1 0
384
+ // F E D C B A - bit 0 is A, bit 5 is F
385
+ unsigned int tx_interrupt_mask = 0;
396386
397
- /* DMCU FW should populate the scratch register if running */
398
- if (REG_READ(DC_DMCU_SCRATCH) == 0)
399
- return false;
387
+ PERF_TRACE();
388
+ /* Definition of DC_DMCU_SCRATCH
389
+ * 0 : firmare not loaded
390
+ * 1 : PSP load DMCU FW but not initialized
391
+ * 2 : Firmware already initialized
392
+ */
393
+ dmcu->dmcu_state = REG_READ(DC_DMCU_SCRATCH);
400394
401
- /* Check state is uninitialized */
402
- dcn10_get_dmcu_state(dmcu);
395
+ for (i = 0; i < ctx->dc->link_count; i++) {
396
+ if (ctx->dc->links[i]->link_enc->features.flags.bits.DP_IS_USB_C) {
397
+ if (ctx->dc->links[i]->link_enc->transmitter >= TRANSMITTER_UNIPHY_A &&
398
+ ctx->dc->links[i]->link_enc->transmitter <= TRANSMITTER_UNIPHY_F) {
399
+ tx_interrupt_mask |= 1 << ctx->dc->links[i]->link_enc->transmitter;
400
+ }
401
+ }
402
+ }
403403
404
- /* If microcontroller is already initialized, do nothing */
405
- if (dmcu->dmcu_state == DMCU_RUNNING)
406
- return true;
404
+ switch (dmcu->dmcu_state) {
405
+ case DMCU_UNLOADED:
406
+ status = false;
407
+ break;
408
+ case DMCU_LOADED_UNINITIALIZED:
409
+ /* Wait until microcontroller is ready to process interrupt */
410
+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
407411
408
- /* Retrieve and cache the DMCU firmware version. */
409
- dcn10_get_dmcu_version(dmcu);
412
+ /* Set initialized ramping boundary value */
413
+ REG_WRITE(MASTER_COMM_DATA_REG1, 0xFFFF);
410414
411
- /* Check interface version to confirm firmware is loaded and running */
412
- if (dmcu->dmcu_version.interface_version == 0)
413
- return false;
415
+ /* Set backlight ramping stepsize */
416
+ REG_WRITE(MASTER_COMM_DATA_REG2, abm_gain_stepsize);
414417
415
- /* Wait until microcontroller is ready to process interrupt */
416
- REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
418
+ REG_WRITE(MASTER_COMM_DATA_REG3, tx_interrupt_mask);
417419
418
- /* Set initialized ramping boundary value */
419
- REG_WRITE(MASTER_COMM_DATA_REG1, 0xFFFF);
420
-
421
- /* Set command to initialize microcontroller */
422
- REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,
420
+ /* Set command to initialize microcontroller */
421
+ REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,
423422 MCP_INIT_DMCU);
424423
425
- /* Notify microcontroller of new command */
426
- REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
424
+ /* Notify microcontroller of new command */
425
+ REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
427426
428
- /* Ensure command has been executed before continuing */
429
- REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
427
+ /* Ensure command has been executed before continuing */
428
+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
430429
431
- // Check state is initialized
432
- dcn10_get_dmcu_state(dmcu);
430
+ // Check state is initialized
431
+ dmcu->dmcu_state = REG_READ(DC_DMCU_SCRATCH);
433432
434
- // If microcontroller is not in running state, fail
435
- if (dmcu->dmcu_state != DMCU_RUNNING)
433
+ // If microcontroller is not in running state, fail
434
+ if (dmcu->dmcu_state == DMCU_RUNNING) {
435
+ /* Retrieve and cache the DMCU firmware version. */
436
+ dcn10_get_dmcu_version(dmcu);
437
+
438
+ /* Initialize DMCU to use fractional PWM or not */
439
+ dcn10_dmcu_enable_fractional_pwm(dmcu,
440
+ (config->disable_fractional_pwm == false) ? 1 : 0);
441
+ status = true;
442
+ } else {
443
+ status = false;
444
+ }
445
+
446
+ break;
447
+ case DMCU_RUNNING:
448
+ status = true;
449
+ break;
450
+ default:
451
+ status = false;
452
+ break;
453
+ }
454
+
455
+ PERF_TRACE();
456
+ return status;
457
+}
458
+
459
+static bool dcn21_dmcu_init(struct dmcu *dmcu)
460
+{
461
+ struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
462
+ uint32_t dmcub_psp_version = REG_READ(DMCUB_SCRATCH15);
463
+
464
+ if (dmcu->auto_load_dmcu && dmcub_psp_version == 0) {
436465 return false;
466
+ }
437467
438
- return true;
468
+ return dcn10_dmcu_init(dmcu);
439469 }
440470
441471 static bool dcn10_dmcu_load_iram(struct dmcu *dmcu,
....@@ -523,9 +553,6 @@
523553 if (dmcu->dmcu_state != DMCU_RUNNING)
524554 return;
525555
526
- dcn10_get_dmcu_psr_state(dmcu, &psr_state);
527
- if (psr_state == 0 && !enable)
528
- return;
529556 /* waitDMCUReadyForCmd */
530557 REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
531558 dmcu_wait_reg_ready_interval,
....@@ -633,7 +660,7 @@
633660 link->link_enc->funcs->psr_program_secondary_packet(link->link_enc,
634661 psr_context->sdpTransmitLineNumDeadline);
635662
636
- if (psr_context->psr_level.bits.SKIP_SMU_NOTIFICATION)
663
+ if (psr_context->allow_smu_optimizations)
637664 REG_UPDATE(SMU_INTERRUPT_CONTROL, DC_SMU_INT_ENABLE, 1);
638665
639666 /* waitDMCUReadyForCmd */
....@@ -654,6 +681,7 @@
654681 psr_context->psrFrameCaptureIndicationReq;
655682 masterCmdData1.bits.aux_chan = psr_context->channel;
656683 masterCmdData1.bits.aux_repeat = psr_context->aux_repeats;
684
+ masterCmdData1.bits.allow_smu_optimizations = psr_context->allow_smu_optimizations;
657685 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1),
658686 masterCmdData1.u32All);
659687
....@@ -673,6 +701,7 @@
673701 masterCmdData3.bits.psr_level = psr_context->psr_level.u32all;
674702 dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG3),
675703 masterCmdData3.u32All);
704
+
676705
677706 /* setDMCUParam_Cmd */
678707 REG_UPDATE(MASTER_COMM_CMD_REG,
....@@ -730,7 +759,55 @@
730759 return true;
731760 }
732761
733
-#endif
762
+
763
+
764
+static bool dcn20_lock_phy(struct dmcu *dmcu)
765
+{
766
+ struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
767
+
768
+ /* If microcontroller is not running, do nothing */
769
+ if (dmcu->dmcu_state != DMCU_RUNNING)
770
+ return false;
771
+
772
+ /* waitDMCUReadyForCmd */
773
+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);
774
+
775
+ /* setDMCUParam_Cmd */
776
+ REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_SYNC_PHY_LOCK);
777
+
778
+ /* notifyDMCUMsg */
779
+ REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
780
+
781
+ /* waitDMCUReadyForCmd */
782
+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);
783
+
784
+ return true;
785
+}
786
+
787
+static bool dcn20_unlock_phy(struct dmcu *dmcu)
788
+{
789
+ struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
790
+
791
+ /* If microcontroller is not running, do nothing */
792
+ if (dmcu->dmcu_state != DMCU_RUNNING)
793
+ return false;
794
+
795
+ /* waitDMCUReadyForCmd */
796
+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);
797
+
798
+ /* setDMCUParam_Cmd */
799
+ REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_SYNC_PHY_UNLOCK);
800
+
801
+ /* notifyDMCUMsg */
802
+ REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
803
+
804
+ /* waitDMCUReadyForCmd */
805
+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);
806
+
807
+ return true;
808
+}
809
+
810
+#endif //(CONFIG_DRM_AMD_DC_DCN)
734811
735812 static const struct dmcu_funcs dce_funcs = {
736813 .dmcu_init = dce_dmcu_init,
....@@ -743,7 +820,7 @@
743820 .is_dmcu_initialized = dce_is_dmcu_initialized
744821 };
745822
746
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
823
+#if defined(CONFIG_DRM_AMD_DC_DCN)
747824 static const struct dmcu_funcs dcn10_funcs = {
748825 .dmcu_init = dcn10_dmcu_init,
749826 .load_iram = dcn10_dmcu_load_iram,
....@@ -753,6 +830,32 @@
753830 .set_psr_wait_loop = dcn10_psr_wait_loop,
754831 .get_psr_wait_loop = dcn10_get_psr_wait_loop,
755832 .is_dmcu_initialized = dcn10_is_dmcu_initialized
833
+};
834
+
835
+static const struct dmcu_funcs dcn20_funcs = {
836
+ .dmcu_init = dcn10_dmcu_init,
837
+ .load_iram = dcn10_dmcu_load_iram,
838
+ .set_psr_enable = dcn10_dmcu_set_psr_enable,
839
+ .setup_psr = dcn10_dmcu_setup_psr,
840
+ .get_psr_state = dcn10_get_dmcu_psr_state,
841
+ .set_psr_wait_loop = dcn10_psr_wait_loop,
842
+ .get_psr_wait_loop = dcn10_get_psr_wait_loop,
843
+ .is_dmcu_initialized = dcn10_is_dmcu_initialized,
844
+ .lock_phy = dcn20_lock_phy,
845
+ .unlock_phy = dcn20_unlock_phy
846
+};
847
+
848
+static const struct dmcu_funcs dcn21_funcs = {
849
+ .dmcu_init = dcn21_dmcu_init,
850
+ .load_iram = dcn10_dmcu_load_iram,
851
+ .set_psr_enable = dcn10_dmcu_set_psr_enable,
852
+ .setup_psr = dcn10_dmcu_setup_psr,
853
+ .get_psr_state = dcn10_get_dmcu_psr_state,
854
+ .set_psr_wait_loop = dcn10_psr_wait_loop,
855
+ .get_psr_wait_loop = dcn10_get_psr_wait_loop,
856
+ .is_dmcu_initialized = dcn10_is_dmcu_initialized,
857
+ .lock_phy = dcn20_lock_phy,
858
+ .unlock_phy = dcn20_unlock_phy
756859 };
757860 #endif
758861
....@@ -773,6 +876,26 @@
773876 dmcu_dce->dmcu_shift = dmcu_shift;
774877 dmcu_dce->dmcu_mask = dmcu_mask;
775878 }
879
+
880
+#if defined(CONFIG_DRM_AMD_DC_DCN)
881
+static void dcn21_dmcu_construct(
882
+ struct dce_dmcu *dmcu_dce,
883
+ struct dc_context *ctx,
884
+ const struct dce_dmcu_registers *regs,
885
+ const struct dce_dmcu_shift *dmcu_shift,
886
+ const struct dce_dmcu_mask *dmcu_mask)
887
+{
888
+ uint32_t psp_version = 0;
889
+
890
+ dce_dmcu_construct(dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);
891
+
892
+ if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
893
+ psp_version = dm_read_reg(ctx, mmMP0_SMN_C2PMSG_58);
894
+ dmcu_dce->base.auto_load_dmcu = ((psp_version & 0x00FF00FF) > 0x00110029);
895
+ dmcu_dce->base.psp_version = psp_version;
896
+ }
897
+}
898
+#endif
776899
777900 struct dmcu *dce_dmcu_create(
778901 struct dc_context *ctx,
....@@ -795,14 +918,14 @@
795918 return &dmcu_dce->base;
796919 }
797920
798
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
921
+#if defined(CONFIG_DRM_AMD_DC_DCN)
799922 struct dmcu *dcn10_dmcu_create(
800923 struct dc_context *ctx,
801924 const struct dce_dmcu_registers *regs,
802925 const struct dce_dmcu_shift *dmcu_shift,
803926 const struct dce_dmcu_mask *dmcu_mask)
804927 {
805
- struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL);
928
+ struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);
806929
807930 if (dmcu_dce == NULL) {
808931 BREAK_TO_DEBUGGER();
....@@ -816,6 +939,48 @@
816939
817940 return &dmcu_dce->base;
818941 }
942
+
943
+struct dmcu *dcn20_dmcu_create(
944
+ struct dc_context *ctx,
945
+ const struct dce_dmcu_registers *regs,
946
+ const struct dce_dmcu_shift *dmcu_shift,
947
+ const struct dce_dmcu_mask *dmcu_mask)
948
+{
949
+ struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);
950
+
951
+ if (dmcu_dce == NULL) {
952
+ BREAK_TO_DEBUGGER();
953
+ return NULL;
954
+ }
955
+
956
+ dce_dmcu_construct(
957
+ dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);
958
+
959
+ dmcu_dce->base.funcs = &dcn20_funcs;
960
+
961
+ return &dmcu_dce->base;
962
+}
963
+
964
+struct dmcu *dcn21_dmcu_create(
965
+ struct dc_context *ctx,
966
+ const struct dce_dmcu_registers *regs,
967
+ const struct dce_dmcu_shift *dmcu_shift,
968
+ const struct dce_dmcu_mask *dmcu_mask)
969
+{
970
+ struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);
971
+
972
+ if (dmcu_dce == NULL) {
973
+ BREAK_TO_DEBUGGER();
974
+ return NULL;
975
+ }
976
+
977
+ dcn21_dmcu_construct(
978
+ dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);
979
+
980
+ dmcu_dce->base.funcs = &dcn21_funcs;
981
+
982
+ return &dmcu_dce->base;
983
+}
819984 #endif
820985
821986 void dce_dmcu_destroy(struct dmcu **dmcu)