Commit 26a9f531 authored by Paul Hsieh's avatar Paul Hsieh Committed by Alex Deucher
Browse files

drm/amd/display: Correct DML calculation to align HW formula



[Why]
In 2560x1440@240p eDP panel, some use cases will enable MPC
combine with RGB MPO then underflow happened. This case is
not allowed from HW formula. 

[How]
Correct eDP, DP and DP2 output bpp calculation to align HW
formula.

Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarPaul Hsieh <Paul.Hsieh@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e68d1e07
Loading
Loading
Loading
Loading
+196 −102
Original line number Diff line number Diff line
@@ -4307,11 +4307,11 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
							v->AudioSampleRate[k],
							v->AudioSampleLayout[k],
							v->ODMCombineEnablePerState[i][k]);
				} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
				} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) {
					if (v->DSCEnable[k] == true) {
						v->RequiresDSC[i][k] = true;
						v->LinkDSCEnable = true;
						if (v->Output[k] == dm_dp) {
						if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) {
							v->RequiresFEC[i][k] = true;
						} else {
							v->RequiresFEC[i][k] = false;
@@ -4319,13 +4319,18 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
					} else {
						v->RequiresDSC[i][k] = false;
						v->LinkDSCEnable = false;
						if (v->Output[k] == dm_dp2p0) {
							v->RequiresFEC[i][k] = true;
						} else {
							v->RequiresFEC[i][k] = false;
						}

					}
					if (v->Output[k] == dm_dp2p0) {
						v->Outbpp = BPP_INVALID;
					if (v->PHYCLKPerState[i] >= 270.0) {
						if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) &&
							v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) {
							v->Outbpp = TruncToValidBPP(
								(1.0 - v->Downspreading / 100.0) * 2700,
									(1.0 - v->Downspreading / 100.0) * 10000,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
@@ -4339,13 +4344,35 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
									v->AudioSampleRate[k],
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 &&
								v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
								v->RequiresDSC[i][k] = true;
								v->LinkDSCEnable = true;
								v->Outbpp = TruncToValidBPP(
										(1.0 - v->Downspreading / 100.0) * 10000,
										v->OutputLinkDPLanes[k],
										v->HTotal[k],
										v->HActive[k],
										v->PixelClockBackEnd[k],
										v->ForcedOutputLinkBPP[k],
										v->LinkDSCEnable,
										v->Output[k],
										v->OutputFormat[k],
										v->DSCInputBitPerComponent[k],
										v->NumberOfDSCSlices[k],
										v->AudioSampleRate[k],
										v->AudioSampleLayout[k],
										v->ODMCombineEnablePerState[i][k]);
							}
							v->OutputBppPerState[i][k] = v->Outbpp;
							// TODO: Need some other way to handle this nonsense
						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10"
						}
					if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
						if (v->Outbpp == BPP_INVALID &&
							(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) &&
							v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) {
							v->Outbpp = TruncToValidBPP(
								(1.0 - v->Downspreading / 100.0) * 5400,
									(1.0 - v->Downspreading / 100.0) * 13500,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
@@ -4359,13 +4386,54 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
									v->AudioSampleRate[k],
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 &&
								v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
								v->RequiresDSC[i][k] = true;
								v->LinkDSCEnable = true;
								v->Outbpp = TruncToValidBPP(
										(1.0 - v->Downspreading / 100.0) * 13500,
										v->OutputLinkDPLanes[k],
										v->HTotal[k],
										v->HActive[k],
										v->PixelClockBackEnd[k],
										v->ForcedOutputLinkBPP[k],
										v->LinkDSCEnable,
										v->Output[k],
										v->OutputFormat[k],
										v->DSCInputBitPerComponent[k],
										v->NumberOfDSCSlices[k],
										v->AudioSampleRate[k],
										v->AudioSampleLayout[k],
										v->ODMCombineEnablePerState[i][k]);
							}
							v->OutputBppPerState[i][k] = v->Outbpp;
							// TODO: Need some other way to handle this nonsense
						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5"
						}
					if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
						if (v->Outbpp == BPP_INVALID &&
							(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) &&
							v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) {
							v->Outbpp = TruncToValidBPP(
								(1.0 - v->Downspreading / 100.0) * 8100,
									(1.0 - v->Downspreading / 100.0) * 20000,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
									v->PixelClockBackEnd[k],
									v->ForcedOutputLinkBPP[k],
									v->LinkDSCEnable,
									v->Output[k],
									v->OutputFormat[k],
									v->DSCInputBitPerComponent[k],
									v->NumberOfDSCSlices[k],
									v->AudioSampleRate[k],
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true &&
								v->ForcedOutputLinkBPP[k] == 0) {
								v->RequiresDSC[i][k] = true;
								v->LinkDSCEnable = true;
								v->Outbpp = TruncToValidBPP(
										(1.0 - v->Downspreading / 100.0) * 20000,
										v->OutputLinkDPLanes[k],
										v->HTotal[k],
										v->HActive[k],
@@ -4379,14 +4447,37 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
										v->AudioSampleRate[k],
										v->AudioSampleLayout[k],
										v->ODMCombineEnablePerState[i][k]);
							}
							v->OutputBppPerState[i][k] = v->Outbpp;
							// TODO: Need some other way to handle this nonsense
						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20"
						}
					if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
					} else {
						v->Outbpp = BPP_INVALID;
						if (v->PHYCLKPerState[i] >= 270.0) {
							v->Outbpp = TruncToValidBPP(
								(1.0 - v->Downspreading / 100.0) * 10000,
								4,
									(1.0 - v->Downspreading / 100.0) * 2700,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
									v->PixelClockBackEnd[k],
									v->ForcedOutputLinkBPP[k],
									v->LinkDSCEnable,
									v->Output[k],
									v->OutputFormat[k],
									v->DSCInputBitPerComponent[k],
									v->NumberOfDSCSlices[k],
									v->AudioSampleRate[k],
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							v->OutputBppPerState[i][k] = v->Outbpp;
							// TODO: Need some other way to handle this nonsense
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
						}
						if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
							v->Outbpp = TruncToValidBPP(
									(1.0 - v->Downspreading / 100.0) * 5400,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
									v->PixelClockBackEnd[k],
@@ -4400,12 +4491,13 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							v->OutputBppPerState[i][k] = v->Outbpp;
						//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
							// TODO: Need some other way to handle this nonsense
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
						}
					if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
						if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
							v->Outbpp = TruncToValidBPP(
								12000,
								4,
									(1.0 - v->Downspreading / 100.0) * 8100,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
									v->PixelClockBackEnd[k],
@@ -4419,7 +4511,9 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							v->OutputBppPerState[i][k] = v->Outbpp;
						//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
							// TODO: Need some other way to handle this nonsense
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
						}
					}
				}
			} else {
+196 −102
Original line number Diff line number Diff line
@@ -4405,11 +4405,11 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
							v->AudioSampleRate[k],
							v->AudioSampleLayout[k],
							v->ODMCombineEnablePerState[i][k]);
				} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
				} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) {
					if (v->DSCEnable[k] == true) {
						v->RequiresDSC[i][k] = true;
						v->LinkDSCEnable = true;
						if (v->Output[k] == dm_dp) {
						if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) {
							v->RequiresFEC[i][k] = true;
						} else {
							v->RequiresFEC[i][k] = false;
@@ -4417,13 +4417,18 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
					} else {
						v->RequiresDSC[i][k] = false;
						v->LinkDSCEnable = false;
						if (v->Output[k] == dm_dp2p0) {
							v->RequiresFEC[i][k] = true;
						} else {
							v->RequiresFEC[i][k] = false;
						}

					}
					if (v->Output[k] == dm_dp2p0) {
						v->Outbpp = BPP_INVALID;
					if (v->PHYCLKPerState[i] >= 270.0) {
						if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) &&
							v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) {
							v->Outbpp = TruncToValidBPP(
								(1.0 - v->Downspreading / 100.0) * 2700,
									(1.0 - v->Downspreading / 100.0) * 10000,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
@@ -4437,13 +4442,35 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
									v->AudioSampleRate[k],
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 &&
								v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
								v->RequiresDSC[i][k] = true;
								v->LinkDSCEnable = true;
								v->Outbpp = TruncToValidBPP(
										(1.0 - v->Downspreading / 100.0) * 10000,
										v->OutputLinkDPLanes[k],
										v->HTotal[k],
										v->HActive[k],
										v->PixelClockBackEnd[k],
										v->ForcedOutputLinkBPP[k],
										v->LinkDSCEnable,
										v->Output[k],
										v->OutputFormat[k],
										v->DSCInputBitPerComponent[k],
										v->NumberOfDSCSlices[k],
										v->AudioSampleRate[k],
										v->AudioSampleLayout[k],
										v->ODMCombineEnablePerState[i][k]);
							}
							v->OutputBppPerState[i][k] = v->Outbpp;
							// TODO: Need some other way to handle this nonsense
						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10"
						}
					if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
						if (v->Outbpp == BPP_INVALID &&
							(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) &&
							v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) {
							v->Outbpp = TruncToValidBPP(
								(1.0 - v->Downspreading / 100.0) * 5400,
									(1.0 - v->Downspreading / 100.0) * 13500,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
@@ -4457,13 +4484,54 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
									v->AudioSampleRate[k],
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 &&
								v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
								v->RequiresDSC[i][k] = true;
								v->LinkDSCEnable = true;
								v->Outbpp = TruncToValidBPP(
										(1.0 - v->Downspreading / 100.0) * 13500,
										v->OutputLinkDPLanes[k],
										v->HTotal[k],
										v->HActive[k],
										v->PixelClockBackEnd[k],
										v->ForcedOutputLinkBPP[k],
										v->LinkDSCEnable,
										v->Output[k],
										v->OutputFormat[k],
										v->DSCInputBitPerComponent[k],
										v->NumberOfDSCSlices[k],
										v->AudioSampleRate[k],
										v->AudioSampleLayout[k],
										v->ODMCombineEnablePerState[i][k]);
							}
							v->OutputBppPerState[i][k] = v->Outbpp;
							// TODO: Need some other way to handle this nonsense
						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5"
						}
					if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
						if (v->Outbpp == BPP_INVALID &&
							(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) &&
							v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) {
							v->Outbpp = TruncToValidBPP(
								(1.0 - v->Downspreading / 100.0) * 8100,
									(1.0 - v->Downspreading / 100.0) * 20000,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
									v->PixelClockBackEnd[k],
									v->ForcedOutputLinkBPP[k],
									v->LinkDSCEnable,
									v->Output[k],
									v->OutputFormat[k],
									v->DSCInputBitPerComponent[k],
									v->NumberOfDSCSlices[k],
									v->AudioSampleRate[k],
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true &&
								v->ForcedOutputLinkBPP[k] == 0) {
								v->RequiresDSC[i][k] = true;
								v->LinkDSCEnable = true;
								v->Outbpp = TruncToValidBPP(
										(1.0 - v->Downspreading / 100.0) * 20000,
										v->OutputLinkDPLanes[k],
										v->HTotal[k],
										v->HActive[k],
@@ -4477,14 +4545,37 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
										v->AudioSampleRate[k],
										v->AudioSampleLayout[k],
										v->ODMCombineEnablePerState[i][k]);
							}
							v->OutputBppPerState[i][k] = v->Outbpp;
							// TODO: Need some other way to handle this nonsense
						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20"
						}
					if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
					} else {
						v->Outbpp = BPP_INVALID;
						if (v->PHYCLKPerState[i] >= 270.0) {
							v->Outbpp = TruncToValidBPP(
								(1.0 - v->Downspreading / 100.0) * 10000,
								4,
									(1.0 - v->Downspreading / 100.0) * 2700,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
									v->PixelClockBackEnd[k],
									v->ForcedOutputLinkBPP[k],
									v->LinkDSCEnable,
									v->Output[k],
									v->OutputFormat[k],
									v->DSCInputBitPerComponent[k],
									v->NumberOfDSCSlices[k],
									v->AudioSampleRate[k],
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							v->OutputBppPerState[i][k] = v->Outbpp;
							// TODO: Need some other way to handle this nonsense
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
						}
						if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
							v->Outbpp = TruncToValidBPP(
									(1.0 - v->Downspreading / 100.0) * 5400,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
									v->PixelClockBackEnd[k],
@@ -4498,12 +4589,13 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							v->OutputBppPerState[i][k] = v->Outbpp;
						//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
							// TODO: Need some other way to handle this nonsense
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
						}
					if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
						if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
							v->Outbpp = TruncToValidBPP(
								12000,
								4,
									(1.0 - v->Downspreading / 100.0) * 8100,
									v->OutputLinkDPLanes[k],
									v->HTotal[k],
									v->HActive[k],
									v->PixelClockBackEnd[k],
@@ -4517,7 +4609,9 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
									v->AudioSampleLayout[k],
									v->ODMCombineEnablePerState[i][k]);
							v->OutputBppPerState[i][k] = v->Outbpp;
						//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
							// TODO: Need some other way to handle this nonsense
							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
						}
					}
				}
			} else {