diff mbox series

[2/6] drm: bridge: samsung-dsim: Fix PMS Calculator on imx8m[mnp]

Message ID 20230415104104.5537-2-aford173@gmail.com (mailing list archive)
State New, archived
Headers show
Series [1/6] drm: bridge: samsung-dsim: Support multi-lane calculations | expand

Commit Message

Adam Ford April 15, 2023, 10:40 a.m. UTC
According to Table 13-45 of the i.MX8M Mini Reference Manual, the min
and max values for M and  the frequency range for the VCO_out
calculator were incorrect.  This also appears to be the case for the
imx8mn and imx8mp.

To fix this, make new variables to hold the min and max values of m
and the minimum value of VCO_out, and update the PMS calculator to
use these new variables instead of using hard-coded values to keep
the backwards compatibility with other parts using this driver.

Fixes: 4d562c70c4dc ("drm: bridge: samsung-dsim: Add i.MX8M Mini/Nano support")
Signed-off-by: Adam Ford <aford173@gmail.com>
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 22 ++++++++++++++++++++--
 include/drm/bridge/samsung-dsim.h     |  3 +++
 2 files changed, 23 insertions(+), 2 deletions(-)

Comments

Marek Vasut April 16, 2023, 10:07 p.m. UTC | #1
On 4/15/23 12:40, Adam Ford wrote:
> According to Table 13-45 of the i.MX8M Mini Reference Manual, the min
> and max values for M and  the frequency range for the VCO_out
> calculator were incorrect.  This also appears to be the case for the
> imx8mn and imx8mp.
> 
> To fix this, make new variables to hold the min and max values of m
> and the minimum value of VCO_out, and update the PMS calculator to
> use these new variables instead of using hard-coded values to keep
> the backwards compatibility with other parts using this driver.

[...]

>   static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
> @@ -470,6 +485,9 @@ static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
>   	 */
>   	.pll_p_offset = 14,
>   	.reg_values = imx8mm_dsim_reg_values,
> +	.m_min = 64,
> +	.m_max = 1023,
> +	.vco_min = 1050,

You might want to call this 'min_freq' since there is a 'max_freq' which 
seems to indicate what VCO max frequency is.

Note that the same datasheet contains the following information:
"
MIPI_DPHY_M_PLLPMS field descriptions

12–4 PMS_M
Specifies the PLL PMS value for the M divider
NOTE: The programmable divider range should be within 25 to 125 to 
ensure PLL stability.
NOTE: The M and P divider values should be considered together to ensure 
VCO ouput frequency
(VCO_out) range is between 350 MHz to 750 MHz.
Please refer to the topic DPHY PLL for more information.
"
Adam Ford April 16, 2023, 10:31 p.m. UTC | #2
On Sun, Apr 16, 2023 at 5:07 PM Marek Vasut <marex@denx.de> wrote:
>
> On 4/15/23 12:40, Adam Ford wrote:
> > According to Table 13-45 of the i.MX8M Mini Reference Manual, the min
> > and max values for M and  the frequency range for the VCO_out
> > calculator were incorrect.  This also appears to be the case for the
> > imx8mn and imx8mp.
> >
> > To fix this, make new variables to hold the min and max values of m
> > and the minimum value of VCO_out, and update the PMS calculator to
> > use these new variables instead of using hard-coded values to keep
> > the backwards compatibility with other parts using this driver.
>
> [...]
>
> >   static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
> > @@ -470,6 +485,9 @@ static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
> >        */
> >       .pll_p_offset = 14,
> >       .reg_values = imx8mm_dsim_reg_values,
> > +     .m_min = 64,
> > +     .m_max = 1023,
> > +     .vco_min = 1050,
>
> You might want to call this 'min_freq' since there is a 'max_freq' which
> seems to indicate what VCO max frequency is.
>
> Note that the same datasheet contains the following information:
> "
> MIPI_DPHY_M_PLLPMS field descriptions
>
> 12–4 PMS_M
> Specifies the PLL PMS value for the M divider
> NOTE: The programmable divider range should be within 25 to 125 to
> ensure PLL stability.

I was confused by this because this statement is not consistent with
the link they reference jumps me to the table where it reads M is
between 64 and 1023.

> NOTE: The M and P divider values should be considered together to ensure
> VCO ouput frequency
> (VCO_out) range is between 350 MHz to 750 MHz.
> Please refer to the topic DPHY PLL for more information.

I was confused by this too, because the NXP documentation reads the
350 - 750MHz that you state, but  "Table 13-45: DPHY PLL Parameters"
which immediately follows that sentence  on page 4158 shows VCO_out is
between 1050-2100 MHz.

I compared the PMS values for a variety of frequencies to those that
were set in the downstream NXP code, and the PMS values matched.
Maybe someone from NXP can explain the discrepancy.

adam

> "
Alexander Stein April 17, 2023, 7 a.m. UTC | #3
Hi,

Am Montag, 17. April 2023, 00:31:24 CEST schrieb Adam Ford:
> On Sun, Apr 16, 2023 at 5:07 PM Marek Vasut <marex@denx.de> wrote:
> > On 4/15/23 12:40, Adam Ford wrote:
> > > According to Table 13-45 of the i.MX8M Mini Reference Manual, the min
> > > and max values for M and  the frequency range for the VCO_out
> > > calculator were incorrect.  This also appears to be the case for the
> > > imx8mn and imx8mp.
> > > 
> > > To fix this, make new variables to hold the min and max values of m
> > > and the minimum value of VCO_out, and update the PMS calculator to
> > > use these new variables instead of using hard-coded values to keep
> > > the backwards compatibility with other parts using this driver.
> > 
> > [...]
> > 
> > >   static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data =
> > >   {
> > > 
> > > @@ -470,6 +485,9 @@ static const struct samsung_dsim_driver_data
> > > imx8mm_dsi_driver_data = {> > 
> > >        */
> > >       
> > >       .pll_p_offset = 14,
> > >       .reg_values = imx8mm_dsim_reg_values,
> > > 
> > > +     .m_min = 64,
> > > +     .m_max = 1023,
> > > +     .vco_min = 1050,
> > 
> > You might want to call this 'min_freq' since there is a 'max_freq' which
> > seems to indicate what VCO max frequency is.
> > 
> > Note that the same datasheet contains the following information:
> > "
> > MIPI_DPHY_M_PLLPMS field descriptions
> > 
> > 12–4 PMS_M
> > Specifies the PLL PMS value for the M divider
> > NOTE: The programmable divider range should be within 25 to 125 to
> > ensure PLL stability.
> 
> I was confused by this because this statement is not consistent with
> the link they reference jumps me to the table where it reads M is
> between 64 and 1023.
> 
> > NOTE: The M and P divider values should be considered together to ensure
> > VCO ouput frequency
> > (VCO_out) range is between 350 MHz to 750 MHz.
> > Please refer to the topic DPHY PLL for more information.
> 
> I was confused by this too, because the NXP documentation reads the
> 350 - 750MHz that you state, but  "Table 13-45: DPHY PLL Parameters"
> which immediately follows that sentence  on page 4158 shows VCO_out is
> between 1050-2100 MHz.
> 
> I compared the PMS values for a variety of frequencies to those that
> were set in the downstream NXP code, and the PMS values matched.
> Maybe someone from NXP can explain the discrepancy.

Also note that, according to Table 13-28 in RM (Rev 2 07/2022) for i.MX8M 
Nano, VCO_out and Fout has a maximum of 1500MHz only. Although the note above 
mentions a range  of 1050-2100MHz...

Best regards,
Alexander
Adam Ford April 18, 2023, 11:53 a.m. UTC | #4
On Mon, Apr 17, 2023 at 2:00 AM Alexander Stein
<alexander.stein@ew.tq-group.com> wrote:
>
> Hi,
>
> Am Montag, 17. April 2023, 00:31:24 CEST schrieb Adam Ford:
> > On Sun, Apr 16, 2023 at 5:07 PM Marek Vasut <marex@denx.de> wrote:
> > > On 4/15/23 12:40, Adam Ford wrote:
> > > > According to Table 13-45 of the i.MX8M Mini Reference Manual, the min
> > > > and max values for M and  the frequency range for the VCO_out
> > > > calculator were incorrect.  This also appears to be the case for the
> > > > imx8mn and imx8mp.
> > > >
> > > > To fix this, make new variables to hold the min and max values of m
> > > > and the minimum value of VCO_out, and update the PMS calculator to
> > > > use these new variables instead of using hard-coded values to keep
> > > > the backwards compatibility with other parts using this driver.
> > >
> > > [...]
> > >
> > > >   static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data =
> > > >   {
> > > >
> > > > @@ -470,6 +485,9 @@ static const struct samsung_dsim_driver_data
> > > > imx8mm_dsi_driver_data = {> >
> > > >        */
> > > >
> > > >       .pll_p_offset = 14,
> > > >       .reg_values = imx8mm_dsim_reg_values,
> > > >
> > > > +     .m_min = 64,
> > > > +     .m_max = 1023,
> > > > +     .vco_min = 1050,
> > >
> > > You might want to call this 'min_freq' since there is a 'max_freq' which
> > > seems to indicate what VCO max frequency is.
> > >
> > > Note that the same datasheet contains the following information:
> > > "
> > > MIPI_DPHY_M_PLLPMS field descriptions
> > >
> > > 12–4 PMS_M
> > > Specifies the PLL PMS value for the M divider
> > > NOTE: The programmable divider range should be within 25 to 125 to
> > > ensure PLL stability.
> >
> > I was confused by this because this statement is not consistent with
> > the link they reference jumps me to the table where it reads M is
> > between 64 and 1023.
> >
> > > NOTE: The M and P divider values should be considered together to ensure
> > > VCO ouput frequency
> > > (VCO_out) range is between 350 MHz to 750 MHz.
> > > Please refer to the topic DPHY PLL for more information.
> >
> > I was confused by this too, because the NXP documentation reads the
> > 350 - 750MHz that you state, but  "Table 13-45: DPHY PLL Parameters"
> > which immediately follows that sentence  on page 4158 shows VCO_out is
> > between 1050-2100 MHz.
> >
> > I compared the PMS values for a variety of frequencies to those that
> > were set in the downstream NXP code, and the PMS values matched.
> > Maybe someone from NXP can explain the discrepancy.
>
> Also note that, according to Table 13-28 in RM (Rev 2 07/2022) for i.MX8M
> Nano, VCO_out and Fout has a maximum of 1500MHz only. Although the note above
> mentions a range  of 1050-2100MHz...

I looked up the limits in NXP's downstream kernel [1] , and I believe
these values match the table in the reference manual instead of the
conflicting sentence.  I am guessing this is why the PMS values I get
match those of the NXP downstream kernel.

adam

[1] - https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/drivers/gpu/drm/imx/sec_mipi_pll_1432x.h#L38

>
> Best regards,
> Alexander
> --
> TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht München, HRB 105018
> Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
> http://www.tq-group.com/
>
>
Adam Ford April 20, 2023, 7:15 p.m. UTC | #5
On Tue, Apr 18, 2023 at 6:53 AM Adam Ford <aford173@gmail.com> wrote:
>
> On Mon, Apr 17, 2023 at 2:00 AM Alexander Stein
> <alexander.stein@ew.tq-group.com> wrote:
> >
> > Hi,
> >
> > Am Montag, 17. April 2023, 00:31:24 CEST schrieb Adam Ford:
> > > On Sun, Apr 16, 2023 at 5:07 PM Marek Vasut <marex@denx.de> wrote:
> > > > On 4/15/23 12:40, Adam Ford wrote:
> > > > > According to Table 13-45 of the i.MX8M Mini Reference Manual, the min
> > > > > and max values for M and  the frequency range for the VCO_out
> > > > > calculator were incorrect.  This also appears to be the case for the
> > > > > imx8mn and imx8mp.
> > > > >
> > > > > To fix this, make new variables to hold the min and max values of m
> > > > > and the minimum value of VCO_out, and update the PMS calculator to
> > > > > use these new variables instead of using hard-coded values to keep
> > > > > the backwards compatibility with other parts using this driver.
> > > >
> > > > [...]
> > > >
> > > > >   static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data =
> > > > >   {
> > > > >
> > > > > @@ -470,6 +485,9 @@ static const struct samsung_dsim_driver_data
> > > > > imx8mm_dsi_driver_data = {> >
> > > > >        */
> > > > >
> > > > >       .pll_p_offset = 14,
> > > > >       .reg_values = imx8mm_dsim_reg_values,
> > > > >
> > > > > +     .m_min = 64,
> > > > > +     .m_max = 1023,
> > > > > +     .vco_min = 1050,
> > > >
> > > > You might want to call this 'min_freq' since there is a 'max_freq' which
> > > > seems to indicate what VCO max frequency is.
> > > >
> > > > Note that the same datasheet contains the following information:
> > > > "
> > > > MIPI_DPHY_M_PLLPMS field descriptions
> > > >
> > > > 12–4 PMS_M
> > > > Specifies the PLL PMS value for the M divider
> > > > NOTE: The programmable divider range should be within 25 to 125 to
> > > > ensure PLL stability.
> > >
> > > I was confused by this because this statement is not consistent with
> > > the link they reference jumps me to the table where it reads M is
> > > between 64 and 1023.
> > >
> > > > NOTE: The M and P divider values should be considered together to ensure
> > > > VCO ouput frequency
> > > > (VCO_out) range is between 350 MHz to 750 MHz.
> > > > Please refer to the topic DPHY PLL for more information.
> > >
> > > I was confused by this too, because the NXP documentation reads the
> > > 350 - 750MHz that you state, but  "Table 13-45: DPHY PLL Parameters"
> > > which immediately follows that sentence  on page 4158 shows VCO_out is
> > > between 1050-2100 MHz.

I reached out to my NXP rep asking if the VCO_out is 350-750 or if it
should be 1050-2100, and received the following statement:

" Yes it is definitely wrong, the one that is part of the NOTE in
MIPI_DPHY_M_PLLPMS register table against PMS_P, PMS_M and PMS_S is
not correct. I will report this to Doc team, the one customer should
be take into account is the Table 13-40 DPHY PLL Parameters and the
Note above."

Table 13-40 (for the Nano) reads the VCO_out is 1050-2100, despite
other text stating 350-750MHz, so I believe this patch is appropriate.
I'll add the above statement to the commit message as confirmation
when I submit a V2 of this series.

adam
> > >
> > > I compared the PMS values for a variety of frequencies to those that
> > > were set in the downstream NXP code, and the PMS values matched.
> > > Maybe someone from NXP can explain the discrepancy.
> >
> > Also note that, according to Table 13-28 in RM (Rev 2 07/2022) for i.MX8M
> > Nano, VCO_out and Fout has a maximum of 1500MHz only. Although the note above
> > mentions a range  of 1050-2100MHz...
>
> I looked up the limits in NXP's downstream kernel [1] , and I believe
> these values match the table in the reference manual instead of the
> conflicting sentence.  I am guessing this is why the PMS values I get
> match those of the NXP downstream kernel.
>
> adam
>
> [1] - https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/drivers/gpu/drm/imx/sec_mipi_pll_1432x.h#L38
>
> >
> > Best regards,
> > Alexander
> > --
> > TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
> > Amtsgericht München, HRB 105018
> > Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
> > http://www.tq-group.com/
> >
> >
diff mbox series

Patch

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index 1ccbad4ea577..9fec32b44e05 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -406,6 +406,9 @@  static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {
 	.num_bits_resol = 11,
 	.pll_p_offset = 13,
 	.reg_values = reg_values,
+	.m_min = 41,
+	.m_max = 125,
+	.vco_min = 500,
 };
 
 static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {
@@ -419,6 +422,9 @@  static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {
 	.num_bits_resol = 11,
 	.pll_p_offset = 13,
 	.reg_values = reg_values,
+	.m_min = 41,
+	.m_max = 125,
+	.vco_min = 500,
 };
 
 static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {
@@ -430,6 +436,9 @@  static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {
 	.num_bits_resol = 11,
 	.pll_p_offset = 13,
 	.reg_values = reg_values,
+	.m_min = 41,
+	.m_max = 125,
+	.vco_min = 500,
 };
 
 static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = {
@@ -442,6 +451,9 @@  static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = {
 	.num_bits_resol = 12,
 	.pll_p_offset = 13,
 	.reg_values = exynos5433_reg_values,
+	.m_min = 41,
+	.m_max = 125,
+	.vco_min = 500,
 };
 
 static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {
@@ -454,6 +466,9 @@  static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {
 	.num_bits_resol = 12,
 	.pll_p_offset = 13,
 	.reg_values = exynos5422_reg_values,
+	.m_min = 41,
+	.m_max = 125,
+	.vco_min = 500,
 };
 
 static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
@@ -470,6 +485,9 @@  static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
 	 */
 	.pll_p_offset = 14,
 	.reg_values = imx8mm_dsim_reg_values,
+	.m_min = 64,
+	.m_max = 1023,
+	.vco_min = 1050,
 };
 
 static const struct samsung_dsim_driver_data *
@@ -548,12 +566,12 @@  static unsigned long samsung_dsim_pll_find_pms(struct samsung_dsim *dsi,
 			tmp = (u64)fout * (_p << _s);
 			do_div(tmp, fin);
 			_m = tmp;
-			if (_m < 41 || _m > 125)
+			if (_m < driver_data->m_min || _m > driver_data->m_max)
 				continue;
 
 			tmp = (u64)_m * fin;
 			do_div(tmp, _p);
-			if (tmp < 500 * MHZ ||
+			if (tmp < driver_data->vco_min  * MHZ ||
 			    tmp > driver_data->max_freq * MHZ)
 				continue;
 
diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h
index ba5484de2b30..a088d84579bc 100644
--- a/include/drm/bridge/samsung-dsim.h
+++ b/include/drm/bridge/samsung-dsim.h
@@ -59,6 +59,9 @@  struct samsung_dsim_driver_data {
 	unsigned int num_bits_resol;
 	unsigned int pll_p_offset;
 	const unsigned int *reg_values;
+	u16 m_min;
+	u16 m_max;
+	u64 vco_min;
 };
 
 struct samsung_dsim_host_ops {