diff options
author | Amy Zhang <Amy.Zhang@amd.com> | 2017-05-31 16:53:01 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 18:07:50 -0400 |
commit | 9f72f51d701cd2dd87a157d972650924fe91ec80 (patch) | |
tree | 2706bf28e4fb81a5dd40e55ae0b999e6715316ac | |
parent | 1a2c82a2f161f68deb5f0519c315bfc92ede8e01 (diff) |
drm/amd/display: Refactor to call set PSR wait loop in dce_dmcu instead of dce_clocks
Signed-off-by: Amy Zhang <Amy.Zhang@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link.c | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc_types.h | 101 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 66 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h | 101 |
8 files changed, 213 insertions, 162 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 318aaa762f31..b2c8b572d57f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c | |||
@@ -1458,17 +1458,17 @@ bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state) | |||
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | bool dc_link_setup_psr(const struct dc_link *dc_link, | 1460 | bool dc_link_setup_psr(const struct dc_link *dc_link, |
1461 | const struct dc_stream *stream, struct psr_config *psr_config) | 1461 | const struct dc_stream *stream, struct psr_config *psr_config, |
1462 | struct psr_context *psr_context) | ||
1462 | { | 1463 | { |
1463 | struct core_link *link = DC_LINK_TO_CORE(dc_link); | 1464 | struct core_link *link = DC_LINK_TO_CORE(dc_link); |
1464 | struct dc_context *ctx = link->ctx; | 1465 | struct dc_context *ctx = link->ctx; |
1465 | struct core_dc *core_dc = DC_TO_CORE(ctx->dc); | 1466 | struct core_dc *core_dc = DC_TO_CORE(ctx->dc); |
1466 | struct dmcu *dmcu = core_dc->res_pool->dmcu; | 1467 | struct dmcu *dmcu = core_dc->res_pool->dmcu; |
1467 | struct core_stream *core_stream = DC_STREAM_TO_CORE(stream); | 1468 | struct core_stream *core_stream = DC_STREAM_TO_CORE(stream); |
1468 | struct psr_context psr_context = {0}; | ||
1469 | int i; | 1469 | int i; |
1470 | 1470 | ||
1471 | psr_context.controllerId = CONTROLLER_ID_UNDEFINED; | 1471 | psr_context->controllerId = CONTROLLER_ID_UNDEFINED; |
1472 | 1472 | ||
1473 | if (dc_link != NULL && | 1473 | if (dc_link != NULL && |
1474 | dmcu != NULL) { | 1474 | dmcu != NULL) { |
@@ -1503,9 +1503,9 @@ bool dc_link_setup_psr(const struct dc_link *dc_link, | |||
1503 | &psr_configuration.raw, | 1503 | &psr_configuration.raw, |
1504 | sizeof(psr_configuration.raw)); | 1504 | sizeof(psr_configuration.raw)); |
1505 | 1505 | ||
1506 | psr_context.channel = link->public.ddc->ddc_pin->hw_info.ddc_channel; | 1506 | psr_context->channel = link->public.ddc->ddc_pin->hw_info.ddc_channel; |
1507 | psr_context.transmitterId = link->link_enc->transmitter; | 1507 | psr_context->transmitterId = link->link_enc->transmitter; |
1508 | psr_context.engineId = link->link_enc->preferred_engine; | 1508 | psr_context->engineId = link->link_enc->preferred_engine; |
1509 | 1509 | ||
1510 | for (i = 0; i < MAX_PIPES; i++) { | 1510 | for (i = 0; i < MAX_PIPES; i++) { |
1511 | if (core_dc->current_context->res_ctx.pipe_ctx[i].stream | 1511 | if (core_dc->current_context->res_ctx.pipe_ctx[i].stream |
@@ -1513,7 +1513,7 @@ bool dc_link_setup_psr(const struct dc_link *dc_link, | |||
1513 | /* dmcu -1 for all controller id values, | 1513 | /* dmcu -1 for all controller id values, |
1514 | * therefore +1 here | 1514 | * therefore +1 here |
1515 | */ | 1515 | */ |
1516 | psr_context.controllerId = | 1516 | psr_context->controllerId = |
1517 | core_dc->current_context->res_ctx. | 1517 | core_dc->current_context->res_ctx. |
1518 | pipe_ctx[i].tg->inst + 1; | 1518 | pipe_ctx[i].tg->inst + 1; |
1519 | break; | 1519 | break; |
@@ -1521,60 +1521,60 @@ bool dc_link_setup_psr(const struct dc_link *dc_link, | |||
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | /* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/ | 1523 | /* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/ |
1524 | psr_context.phyType = PHY_TYPE_UNIPHY; | 1524 | psr_context->phyType = PHY_TYPE_UNIPHY; |
1525 | /*PhyId is associated with the transmitter id*/ | 1525 | /*PhyId is associated with the transmitter id*/ |
1526 | psr_context.smuPhyId = link->link_enc->transmitter; | 1526 | psr_context->smuPhyId = link->link_enc->transmitter; |
1527 | 1527 | ||
1528 | psr_context.crtcTimingVerticalTotal = stream->timing.v_total; | 1528 | psr_context->crtcTimingVerticalTotal = stream->timing.v_total; |
1529 | psr_context.vsyncRateHz = div64_u64(div64_u64((stream-> | 1529 | psr_context->vsyncRateHz = div64_u64(div64_u64((stream-> |
1530 | timing.pix_clk_khz * 1000), | 1530 | timing.pix_clk_khz * 1000), |
1531 | stream->timing.v_total), | 1531 | stream->timing.v_total), |
1532 | stream->timing.h_total); | 1532 | stream->timing.h_total); |
1533 | 1533 | ||
1534 | psr_context.psrSupportedDisplayConfig = true; | 1534 | psr_context->psrSupportedDisplayConfig = true; |
1535 | psr_context.psrExitLinkTrainingRequired = | 1535 | psr_context->psrExitLinkTrainingRequired = |
1536 | psr_config->psr_exit_link_training_required; | 1536 | psr_config->psr_exit_link_training_required; |
1537 | psr_context.sdpTransmitLineNumDeadline = | 1537 | psr_context->sdpTransmitLineNumDeadline = |
1538 | psr_config->psr_sdp_transmit_line_num_deadline; | 1538 | psr_config->psr_sdp_transmit_line_num_deadline; |
1539 | psr_context.psrFrameCaptureIndicationReq = | 1539 | psr_context->psrFrameCaptureIndicationReq = |
1540 | psr_config->psr_frame_capture_indication_req; | 1540 | psr_config->psr_frame_capture_indication_req; |
1541 | 1541 | ||
1542 | psr_context.skipPsrWaitForPllLock = 0; /* only = 1 in KV */ | 1542 | psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */ |
1543 | 1543 | ||
1544 | psr_context.numberOfControllers = | 1544 | psr_context->numberOfControllers = |
1545 | link->dc->res_pool->res_cap->num_timing_generator; | 1545 | link->dc->res_pool->res_cap->num_timing_generator; |
1546 | 1546 | ||
1547 | psr_context.rfb_update_auto_en = true; | 1547 | psr_context->rfb_update_auto_en = true; |
1548 | 1548 | ||
1549 | /* 2 frames before enter PSR. */ | 1549 | /* 2 frames before enter PSR. */ |
1550 | psr_context.timehyst_frames = 2; | 1550 | psr_context->timehyst_frames = 2; |
1551 | /* half a frame | 1551 | /* half a frame |
1552 | * (units in 100 lines, i.e. a value of 1 represents 100 lines) | 1552 | * (units in 100 lines, i.e. a value of 1 represents 100 lines) |
1553 | */ | 1553 | */ |
1554 | psr_context.hyst_lines = stream->timing.v_total / 2 / 100; | 1554 | psr_context->hyst_lines = stream->timing.v_total / 2 / 100; |
1555 | psr_context.aux_repeats = 10; | 1555 | psr_context->aux_repeats = 10; |
1556 | 1556 | ||
1557 | psr_context.psr_level.u32all = 0; | 1557 | psr_context->psr_level.u32all = 0; |
1558 | 1558 | ||
1559 | /* SMU will perform additional powerdown sequence. | 1559 | /* SMU will perform additional powerdown sequence. |
1560 | * For unsupported ASICs, set psr_level flag to skip PSR | 1560 | * For unsupported ASICs, set psr_level flag to skip PSR |
1561 | * static screen notification to SMU. | 1561 | * static screen notification to SMU. |
1562 | * (Always set for DAL2, did not check ASIC) | 1562 | * (Always set for DAL2, did not check ASIC) |
1563 | */ | 1563 | */ |
1564 | psr_context.psr_level.bits.SKIP_SMU_NOTIFICATION = 1; | 1564 | psr_context->psr_level.bits.SKIP_SMU_NOTIFICATION = 1; |
1565 | 1565 | ||
1566 | /* Complete PSR entry before aborting to prevent intermittent | 1566 | /* Complete PSR entry before aborting to prevent intermittent |
1567 | * freezes on certain eDPs | 1567 | * freezes on certain eDPs |
1568 | */ | 1568 | */ |
1569 | psr_context.psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1; | 1569 | psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1; |
1570 | 1570 | ||
1571 | /* Controls additional delay after remote frame capture before | 1571 | /* Controls additional delay after remote frame capture before |
1572 | * continuing power down, default = 0 | 1572 | * continuing power down, default = 0 |
1573 | */ | 1573 | */ |
1574 | psr_context.frame_delay = 0; | 1574 | psr_context->frame_delay = 0; |
1575 | 1575 | ||
1576 | link->psr_enabled = true; | 1576 | link->psr_enabled = true; |
1577 | dmcu->funcs->setup_psr(dmcu, link, &psr_context); | 1577 | dmcu->funcs->setup_psr(dmcu, link, psr_context); |
1578 | return true; | 1578 | return true; |
1579 | } else | 1579 | } else |
1580 | return false; | 1580 | return false; |
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 328bfcb7dbb8..a20ba01d9e7b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h | |||
@@ -705,7 +705,8 @@ bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable); | |||
705 | bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state); | 705 | bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state); |
706 | 706 | ||
707 | bool dc_link_setup_psr(const struct dc_link *dc_link, | 707 | bool dc_link_setup_psr(const struct dc_link *dc_link, |
708 | const struct dc_stream *stream, struct psr_config *psr_config); | 708 | const struct dc_stream *stream, struct psr_config *psr_config, |
709 | struct psr_context *psr_context); | ||
709 | 710 | ||
710 | /* Request DC to detect if there is a Panel connected. | 711 | /* Request DC to detect if there is a Panel connected. |
711 | * boot - If this call is during initial boot. | 712 | * boot - If this call is during initial boot. |
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index d2f3b9fd7a30..06354c36c499 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "dc_dp_types.h" | 31 | #include "dc_dp_types.h" |
32 | #include "dc_hw_types.h" | 32 | #include "dc_hw_types.h" |
33 | #include "dal_types.h" | 33 | #include "dal_types.h" |
34 | #include "grph_object_defs.h" | ||
34 | 35 | ||
35 | /* forward declarations */ | 36 | /* forward declarations */ |
36 | struct dc_surface; | 37 | struct dc_surface; |
@@ -493,6 +494,106 @@ struct psr_config { | |||
493 | unsigned int psr_sdp_transmit_line_num_deadline; | 494 | unsigned int psr_sdp_transmit_line_num_deadline; |
494 | }; | 495 | }; |
495 | 496 | ||
497 | union dmcu_psr_level { | ||
498 | struct { | ||
499 | unsigned int SKIP_CRC:1; | ||
500 | unsigned int SKIP_DP_VID_STREAM_DISABLE:1; | ||
501 | unsigned int SKIP_PHY_POWER_DOWN:1; | ||
502 | unsigned int SKIP_AUX_ACK_CHECK:1; | ||
503 | unsigned int SKIP_CRTC_DISABLE:1; | ||
504 | unsigned int SKIP_AUX_RFB_CAPTURE_CHECK:1; | ||
505 | unsigned int SKIP_SMU_NOTIFICATION:1; | ||
506 | unsigned int SKIP_AUTO_STATE_ADVANCE:1; | ||
507 | unsigned int DISABLE_PSR_ENTRY_ABORT:1; | ||
508 | unsigned int RESERVED:23; | ||
509 | } bits; | ||
510 | unsigned int u32all; | ||
511 | }; | ||
512 | |||
513 | enum physical_phy_id { | ||
514 | PHYLD_0, | ||
515 | PHYLD_1, | ||
516 | PHYLD_2, | ||
517 | PHYLD_3, | ||
518 | PHYLD_4, | ||
519 | PHYLD_5, | ||
520 | PHYLD_6, | ||
521 | PHYLD_7, | ||
522 | PHYLD_8, | ||
523 | PHYLD_9, | ||
524 | PHYLD_COUNT, | ||
525 | PHYLD_UNKNOWN = (-1L) | ||
526 | }; | ||
527 | |||
528 | enum phy_type { | ||
529 | PHY_TYPE_UNKNOWN = 1, | ||
530 | PHY_TYPE_PCIE_PHY = 2, | ||
531 | PHY_TYPE_UNIPHY = 3, | ||
532 | }; | ||
533 | |||
534 | struct psr_context { | ||
535 | /* ddc line */ | ||
536 | enum channel_id channel; | ||
537 | /* Transmitter id */ | ||
538 | enum transmitter transmitterId; | ||
539 | /* Engine Id is used for Dig Be source select */ | ||
540 | enum engine_id engineId; | ||
541 | /* Controller Id used for Dig Fe source select */ | ||
542 | enum controller_id controllerId; | ||
543 | /* Pcie or Uniphy */ | ||
544 | enum phy_type phyType; | ||
545 | /* Physical PHY Id used by SMU interpretation */ | ||
546 | enum physical_phy_id smuPhyId; | ||
547 | /* Vertical total pixels from crtc timing. | ||
548 | * This is used for static screen detection. | ||
549 | * ie. If we want to detect half a frame, | ||
550 | * we use this to determine the hyst lines. | ||
551 | */ | ||
552 | unsigned int crtcTimingVerticalTotal; | ||
553 | /* PSR supported from panel capabilities and | ||
554 | * current display configuration | ||
555 | */ | ||
556 | bool psrSupportedDisplayConfig; | ||
557 | /* Whether fast link training is supported by the panel */ | ||
558 | bool psrExitLinkTrainingRequired; | ||
559 | /* If RFB setup time is greater than the total VBLANK time, | ||
560 | * it is not possible for the sink to capture the video frame | ||
561 | * in the same frame the SDP is sent. In this case, | ||
562 | * the frame capture indication bit should be set and an extra | ||
563 | * static frame should be transmitted to the sink. | ||
564 | */ | ||
565 | bool psrFrameCaptureIndicationReq; | ||
566 | /* Set the last possible line SDP may be transmitted without violating | ||
567 | * the RFB setup time or entering the active video frame. | ||
568 | */ | ||
569 | unsigned int sdpTransmitLineNumDeadline; | ||
570 | /* The VSync rate in Hz used to calculate the | ||
571 | * step size for smooth brightness feature | ||
572 | */ | ||
573 | unsigned int vsyncRateHz; | ||
574 | unsigned int skipPsrWaitForPllLock; | ||
575 | unsigned int numberOfControllers; | ||
576 | /* Unused, for future use. To indicate that first changed frame from | ||
577 | * state3 shouldn't result in psr_inactive, but rather to perform | ||
578 | * an automatic single frame rfb_update. | ||
579 | */ | ||
580 | bool rfb_update_auto_en; | ||
581 | /* Number of frame before entering static screen */ | ||
582 | unsigned int timehyst_frames; | ||
583 | /* Partial frames before entering static screen */ | ||
584 | unsigned int hyst_lines; | ||
585 | /* # of repeated AUX transaction attempts to make before | ||
586 | * indicating failure to the driver | ||
587 | */ | ||
588 | unsigned int aux_repeats; | ||
589 | /* Controls hw blocks to power down during PSR active state */ | ||
590 | union dmcu_psr_level psr_level; | ||
591 | /* Controls additional delay after remote frame capture before | ||
592 | * continuing powerd own | ||
593 | */ | ||
594 | unsigned int frame_delay; | ||
595 | }; | ||
596 | |||
496 | struct colorspace_transform { | 597 | struct colorspace_transform { |
497 | struct fixed31_32 matrix[12]; | 598 | struct fixed31_32 matrix[12]; |
498 | bool enable_remap; | 599 | bool enable_remap; |
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 8bc0d0ff3a2e..04cd70172cc7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "dc.h" | 31 | #include "dc.h" |
32 | #include "core_dc.h" | 32 | #include "core_dc.h" |
33 | #include "dce_abm.h" | 33 | #include "dce_abm.h" |
34 | #include "dmcu.h" | ||
34 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | 35 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
35 | #include "dcn_calcs.h" | 36 | #include "dcn_calcs.h" |
36 | #include "core_dc.h" | 37 | #include "core_dc.h" |
@@ -331,44 +332,18 @@ static void dce_set_clock( | |||
331 | clk->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; | 332 | clk->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; |
332 | } | 333 | } |
333 | 334 | ||
334 | #define PSR_SET_WAITLOOP 0x31 | ||
335 | |||
336 | union dce110_dmcu_psr_config_data_wait_loop_reg1 { | ||
337 | struct { | ||
338 | unsigned int wait_loop:16; /* [15:0] */ | ||
339 | unsigned int reserved:16; /* [31:16] */ | ||
340 | } bits; | ||
341 | unsigned int u32; | ||
342 | }; | ||
343 | |||
344 | static void dce_psr_wait_loop( | ||
345 | struct dce_disp_clk *clk_dce, unsigned int display_clk_khz) | ||
346 | { | ||
347 | struct dc_context *ctx = clk_dce->base.ctx; | ||
348 | union dce110_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1; | ||
349 | |||
350 | /* waitDMCUReadyForCmd */ | ||
351 | REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 100); | ||
352 | |||
353 | masterCmdData1.u32 = 0; | ||
354 | masterCmdData1.bits.wait_loop = display_clk_khz / 1000 / 7; | ||
355 | dm_write_reg(ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32); | ||
356 | |||
357 | /* setDMCUParam_Cmd */ | ||
358 | REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP); | ||
359 | |||
360 | /* notifyDMCUMsg */ | ||
361 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | ||
362 | } | ||
363 | |||
364 | static void dce_psr_set_clock( | 335 | static void dce_psr_set_clock( |
365 | struct display_clock *clk, | 336 | struct display_clock *clk, |
366 | int requested_clk_khz) | 337 | int requested_clk_khz) |
367 | { | 338 | { |
368 | struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); | 339 | struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); |
340 | struct dc_context *ctx = clk_dce->base.ctx; | ||
341 | struct core_dc *core_dc = DC_TO_CORE(ctx->dc); | ||
342 | struct dmcu *dmcu = core_dc->res_pool->dmcu; | ||
369 | 343 | ||
370 | dce_set_clock(clk, requested_clk_khz); | 344 | dce_set_clock(clk, requested_clk_khz); |
371 | dce_psr_wait_loop(clk_dce, requested_clk_khz); | 345 | |
346 | dmcu->funcs->set_psr_wait_loop(dmcu, requested_clk_khz / 1000 / 7); | ||
372 | } | 347 | } |
373 | 348 | ||
374 | static void dce112_set_clock( | 349 | static void dce112_set_clock( |
@@ -380,6 +355,7 @@ static void dce112_set_clock( | |||
380 | struct dc_bios *bp = clk->ctx->dc_bios; | 355 | struct dc_bios *bp = clk->ctx->dc_bios; |
381 | struct core_dc *core_dc = DC_TO_CORE(clk->ctx->dc); | 356 | struct core_dc *core_dc = DC_TO_CORE(clk->ctx->dc); |
382 | struct abm *abm = core_dc->res_pool->abm; | 357 | struct abm *abm = core_dc->res_pool->abm; |
358 | struct dmcu *dmcu = core_dc->res_pool->dmcu; | ||
383 | 359 | ||
384 | /* Prepare to program display clock*/ | 360 | /* Prepare to program display clock*/ |
385 | memset(&dce_clk_params, 0, sizeof(dce_clk_params)); | 361 | memset(&dce_clk_params, 0, sizeof(dce_clk_params)); |
@@ -411,7 +387,8 @@ static void dce112_set_clock( | |||
411 | bp->funcs->set_dce_clock(bp, &dce_clk_params); | 387 | bp->funcs->set_dce_clock(bp, &dce_clk_params); |
412 | 388 | ||
413 | if (abm->funcs->is_dmcu_initialized(abm)) | 389 | if (abm->funcs->is_dmcu_initialized(abm)) |
414 | dce_psr_wait_loop(clk_dce, requested_clk_khz); | 390 | dmcu->funcs->set_psr_wait_loop(dmcu, |
391 | requested_clk_khz / 1000 / 7); | ||
415 | 392 | ||
416 | } | 393 | } |
417 | 394 | ||
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 03b51e256e21..0fe3ee8e29d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | |||
@@ -48,7 +48,9 @@ | |||
48 | #define PSR_ENABLE 0x20 | 48 | #define PSR_ENABLE 0x20 |
49 | #define PSR_EXIT 0x21 | 49 | #define PSR_EXIT 0x21 |
50 | #define PSR_SET 0x23 | 50 | #define PSR_SET 0x23 |
51 | #define PSR_SET_WAITLOOP 0x31 | ||
51 | #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L | 52 | #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L |
53 | unsigned int cached_wait_loop_number = 0; | ||
52 | 54 | ||
53 | bool dce_dmcu_load_iram(struct dmcu *dmcu, | 55 | bool dce_dmcu_load_iram(struct dmcu *dmcu, |
54 | unsigned int start_offset, | 56 | unsigned int start_offset, |
@@ -252,6 +254,34 @@ static void dce_dmcu_setup_psr(struct dmcu *dmcu, | |||
252 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | 254 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); |
253 | } | 255 | } |
254 | 256 | ||
257 | static void dce_psr_wait_loop( | ||
258 | struct dmcu *dmcu, | ||
259 | unsigned int wait_loop_number) | ||
260 | { | ||
261 | struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); | ||
262 | union dce_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1; | ||
263 | |||
264 | /* waitDMCUReadyForCmd */ | ||
265 | REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 100); | ||
266 | |||
267 | masterCmdData1.u32 = 0; | ||
268 | masterCmdData1.bits.wait_loop = wait_loop_number; | ||
269 | cached_wait_loop_number = wait_loop_number; | ||
270 | dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32); | ||
271 | |||
272 | /* setDMCUParam_Cmd */ | ||
273 | REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP); | ||
274 | |||
275 | /* notifyDMCUMsg */ | ||
276 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | ||
277 | } | ||
278 | |||
279 | static void dce_get_psr_wait_loop(unsigned int *psr_wait_loop_number) | ||
280 | { | ||
281 | *psr_wait_loop_number = cached_wait_loop_number; | ||
282 | return; | ||
283 | } | ||
284 | |||
255 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | 285 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
256 | bool dcn10_dmcu_load_iram(struct dmcu *dmcu, | 286 | bool dcn10_dmcu_load_iram(struct dmcu *dmcu, |
257 | unsigned int start_offset, | 287 | unsigned int start_offset, |
@@ -464,13 +494,43 @@ static void dcn10_dmcu_setup_psr(struct dmcu *dmcu, | |||
464 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | 494 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); |
465 | } | 495 | } |
466 | 496 | ||
497 | static void dcn10_psr_wait_loop( | ||
498 | struct dmcu *dmcu, | ||
499 | unsigned int wait_loop_number) | ||
500 | { | ||
501 | struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); | ||
502 | union dce_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1; | ||
503 | |||
504 | /* waitDMCUReadyForCmd */ | ||
505 | REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 100); | ||
506 | |||
507 | masterCmdData1.u32 = 0; | ||
508 | masterCmdData1.bits.wait_loop = wait_loop_number; | ||
509 | cached_wait_loop_number = wait_loop_number; | ||
510 | dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32); | ||
511 | |||
512 | /* setDMCUParam_Cmd */ | ||
513 | REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP); | ||
514 | |||
515 | /* notifyDMCUMsg */ | ||
516 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | ||
517 | } | ||
518 | |||
519 | static void dcn10_get_psr_wait_loop(unsigned int *psr_wait_loop_number) | ||
520 | { | ||
521 | *psr_wait_loop_number = cached_wait_loop_number; | ||
522 | return; | ||
523 | } | ||
524 | |||
467 | #endif | 525 | #endif |
468 | 526 | ||
469 | static const struct dmcu_funcs dce_funcs = { | 527 | static const struct dmcu_funcs dce_funcs = { |
470 | .load_iram = dce_dmcu_load_iram, | 528 | .load_iram = dce_dmcu_load_iram, |
471 | .set_psr_enable = dce_dmcu_set_psr_enable, | 529 | .set_psr_enable = dce_dmcu_set_psr_enable, |
472 | .setup_psr = dce_dmcu_setup_psr, | 530 | .setup_psr = dce_dmcu_setup_psr, |
473 | .get_psr_state = dce_get_dmcu_psr_state | 531 | .get_psr_state = dce_get_dmcu_psr_state, |
532 | .set_psr_wait_loop = dce_psr_wait_loop, | ||
533 | .get_psr_wait_loop = dce_get_psr_wait_loop | ||
474 | }; | 534 | }; |
475 | 535 | ||
476 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | 536 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
@@ -478,7 +538,9 @@ static const struct dmcu_funcs dcn10_funcs = { | |||
478 | .load_iram = dcn10_dmcu_load_iram, | 538 | .load_iram = dcn10_dmcu_load_iram, |
479 | .set_psr_enable = dcn10_dmcu_set_psr_enable, | 539 | .set_psr_enable = dcn10_dmcu_set_psr_enable, |
480 | .setup_psr = dcn10_dmcu_setup_psr, | 540 | .setup_psr = dcn10_dmcu_setup_psr, |
481 | .get_psr_state = dcn10_get_dmcu_psr_state | 541 | .get_psr_state = dcn10_get_dmcu_psr_state, |
542 | .set_psr_wait_loop = dcn10_psr_wait_loop, | ||
543 | .get_psr_wait_loop = dcn10_get_psr_wait_loop | ||
482 | }; | 544 | }; |
483 | #endif | 545 | #endif |
484 | 546 | ||
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 584682ba1f77..c421a0250016 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h | |||
@@ -197,6 +197,14 @@ union dce_dmcu_psr_config_data_reg3 { | |||
197 | unsigned int u32All; | 197 | unsigned int u32All; |
198 | }; | 198 | }; |
199 | 199 | ||
200 | union dce_dmcu_psr_config_data_wait_loop_reg1 { | ||
201 | struct { | ||
202 | unsigned int wait_loop:16; /* [15:0] */ | ||
203 | unsigned int reserved:16; /* [31:16] */ | ||
204 | } bits; | ||
205 | unsigned int u32; | ||
206 | }; | ||
207 | |||
200 | struct dmcu *dce_dmcu_create( | 208 | struct dmcu *dce_dmcu_create( |
201 | struct dc_context *ctx, | 209 | struct dc_context *ctx, |
202 | const struct dce_dmcu_registers *regs, | 210 | const struct dce_dmcu_registers *regs, |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h index dff0babb5cf7..6067f464d805 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h | |||
@@ -42,6 +42,9 @@ struct dmcu_funcs { | |||
42 | struct core_link *link, | 42 | struct core_link *link, |
43 | struct psr_context *psr_context); | 43 | struct psr_context *psr_context); |
44 | void (*get_psr_state)(struct dmcu *dmcu, uint32_t *psr_state); | 44 | void (*get_psr_state)(struct dmcu *dmcu, uint32_t *psr_state); |
45 | void (*set_psr_wait_loop)(struct dmcu *dmcu, | ||
46 | unsigned int wait_loop_number); | ||
47 | void (*get_psr_wait_loop)(unsigned int *psr_wait_loop_number); | ||
45 | }; | 48 | }; |
46 | 49 | ||
47 | #endif | 50 | #endif |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index 7307f96c7679..d330d38aff16 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h | |||
@@ -47,43 +47,6 @@ struct encoder_feature_support { | |||
47 | bool ycbcr420_supported; | 47 | bool ycbcr420_supported; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | enum physical_phy_id { | ||
51 | PHYLD_0, | ||
52 | PHYLD_1, | ||
53 | PHYLD_2, | ||
54 | PHYLD_3, | ||
55 | PHYLD_4, | ||
56 | PHYLD_5, | ||
57 | PHYLD_6, | ||
58 | PHYLD_7, | ||
59 | PHYLD_8, | ||
60 | PHYLD_9, | ||
61 | PHYLD_COUNT, | ||
62 | PHYLD_UNKNOWN = (-1L) | ||
63 | }; | ||
64 | |||
65 | enum phy_type { | ||
66 | PHY_TYPE_UNKNOWN = 1, | ||
67 | PHY_TYPE_PCIE_PHY = 2, | ||
68 | PHY_TYPE_UNIPHY = 3, | ||
69 | }; | ||
70 | |||
71 | union dmcu_psr_level { | ||
72 | struct { | ||
73 | unsigned int SKIP_CRC:1; | ||
74 | unsigned int SKIP_DP_VID_STREAM_DISABLE:1; | ||
75 | unsigned int SKIP_PHY_POWER_DOWN:1; | ||
76 | unsigned int SKIP_AUX_ACK_CHECK:1; | ||
77 | unsigned int SKIP_CRTC_DISABLE:1; | ||
78 | unsigned int SKIP_AUX_RFB_CAPTURE_CHECK:1; | ||
79 | unsigned int SKIP_SMU_NOTIFICATION:1; | ||
80 | unsigned int SKIP_AUTO_STATE_ADVANCE:1; | ||
81 | unsigned int DISABLE_PSR_ENTRY_ABORT:1; | ||
82 | unsigned int RESERVED:23; | ||
83 | } bits; | ||
84 | unsigned int u32all; | ||
85 | }; | ||
86 | |||
87 | union dpcd_psr_configuration { | 50 | union dpcd_psr_configuration { |
88 | struct { | 51 | struct { |
89 | unsigned char ENABLE : 1; | 52 | unsigned char ENABLE : 1; |
@@ -116,70 +79,6 @@ union psr_sink_psr_status { | |||
116 | unsigned char raw; | 79 | unsigned char raw; |
117 | }; | 80 | }; |
118 | 81 | ||
119 | struct psr_context { | ||
120 | /* ddc line */ | ||
121 | enum channel_id channel; | ||
122 | /* Transmitter id */ | ||
123 | enum transmitter transmitterId; | ||
124 | /* Engine Id is used for Dig Be source select */ | ||
125 | enum engine_id engineId; | ||
126 | /* Controller Id used for Dig Fe source select */ | ||
127 | enum controller_id controllerId; | ||
128 | /* Pcie or Uniphy */ | ||
129 | enum phy_type phyType; | ||
130 | /* Physical PHY Id used by SMU interpretation */ | ||
131 | enum physical_phy_id smuPhyId; | ||
132 | /* Vertical total pixels from crtc timing. | ||
133 | * This is used for static screen detection. | ||
134 | * ie. If we want to detect half a frame, | ||
135 | * we use this to determine the hyst lines. | ||
136 | */ | ||
137 | unsigned int crtcTimingVerticalTotal; | ||
138 | /* PSR supported from panel capabilities and | ||
139 | * current display configuration | ||
140 | */ | ||
141 | bool psrSupportedDisplayConfig; | ||
142 | /* Whether fast link training is supported by the panel */ | ||
143 | bool psrExitLinkTrainingRequired; | ||
144 | /* If RFB setup time is greater than the total VBLANK time, | ||
145 | * it is not possible for the sink to capture the video frame | ||
146 | * in the same frame the SDP is sent. In this case, | ||
147 | * the frame capture indication bit should be set and an extra | ||
148 | * static frame should be transmitted to the sink. | ||
149 | */ | ||
150 | bool psrFrameCaptureIndicationReq; | ||
151 | /* Set the last possible line SDP may be transmitted without violating | ||
152 | * the RFB setup time or entering the active video frame. | ||
153 | */ | ||
154 | unsigned int sdpTransmitLineNumDeadline; | ||
155 | /* The VSync rate in Hz used to calculate the | ||
156 | * step size for smooth brightness feature | ||
157 | */ | ||
158 | unsigned int vsyncRateHz; | ||
159 | unsigned int skipPsrWaitForPllLock; | ||
160 | unsigned int numberOfControllers; | ||
161 | /* Unused, for future use. To indicate that first changed frame from | ||
162 | * state3 shouldn't result in psr_inactive, but rather to perform | ||
163 | * an automatic single frame rfb_update. | ||
164 | */ | ||
165 | bool rfb_update_auto_en; | ||
166 | /* Number of frame before entering static screen */ | ||
167 | unsigned int timehyst_frames; | ||
168 | /* Partial frames before entering static screen */ | ||
169 | unsigned int hyst_lines; | ||
170 | /* # of repeated AUX transaction attempts to make before | ||
171 | * indicating failure to the driver | ||
172 | */ | ||
173 | unsigned int aux_repeats; | ||
174 | /* Controls hw blocks to power down during PSR active state */ | ||
175 | union dmcu_psr_level psr_level; | ||
176 | /* Controls additional delay after remote frame capture before | ||
177 | * continuing powerd own | ||
178 | */ | ||
179 | unsigned int frame_delay; | ||
180 | }; | ||
181 | |||
182 | |||
183 | struct link_encoder { | 82 | struct link_encoder { |
184 | const struct link_encoder_funcs *funcs; | 83 | const struct link_encoder_funcs *funcs; |
185 | int32_t aux_channel_offset; | 84 | int32_t aux_channel_offset; |