* FAILED: patch "[PATCH] mach64: detect the dot clock divider correctly on sparc" failed to apply to 4.19-stable tree
@ 2018-11-19 10:47 gregkh
2018-11-19 16:41 ` Mikulas Patocka
0 siblings, 1 reply; 2+ messages in thread
From: gregkh @ 2018-11-19 10:47 UTC (permalink / raw)
To: mpatocka, b.zolnierkie, davem, syrjala; +Cc: stable
The patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
>From ceadddde8875bda7af3824244de3d93e386d08c1 Mon Sep 17 00:00:00 2001
From: Mikulas Patocka <mpatocka@redhat.com>
Date: Mon, 8 Oct 2018 12:57:34 +0200
Subject: [PATCH] mach64: detect the dot clock divider correctly on sparc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On Sun Ultra 5, it happens that the dot clock is not set up properly for
some videomodes. For example, if we set the videomode "r1024x768x60" in
the firmware, Linux would incorrectly set a videomode with refresh rate
180Hz when booting (suprisingly, my LCD monitor can display it, although
display quality is very low).
The reason is this: Older mach64 cards set the divider in the register
VCLK_POST_DIV. The register has four 2-bit fields (the field that is
actually used is specified in the lowest two bits of the register
CLOCK_CNTL). The 2 bits select divider "1, 2, 4, 8". On newer mach64 cards,
there's another bit added - the top four bits of PLL_EXT_CNTL extend the
divider selection, so we have possible dividers "1, 2, 4, 8, 3, 5, 6, 12".
The Linux driver clears the top four bits of PLL_EXT_CNTL and never sets
them, so it can work regardless if the card supports them. However, the
sparc64 firmware may set these extended dividers during boot - and the
mach64 driver detects incorrect dot clock in this case.
This patch makes the driver read the additional divider bit from
PLL_EXT_CNTL and calculate the initial refresh rate properly.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Acked-by: David S. Miller <davem@davemloft.net>
Reviewed-by: Ville Syrjälä <syrjala@sci.fi>
Cc: stable@vger.kernel.org
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
diff --git a/drivers/video/fbdev/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h
index 8235b285dbb2..d09bab3bf224 100644
--- a/drivers/video/fbdev/aty/atyfb.h
+++ b/drivers/video/fbdev/aty/atyfb.h
@@ -333,6 +333,8 @@ extern const struct aty_pll_ops aty_pll_ct; /* Integrated */
extern void aty_set_pll_ct(const struct fb_info *info, const union aty_pll *pll);
extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par);
+extern const u8 aty_postdividers[8];
+
/*
* Hardware cursor support
@@ -359,7 +361,6 @@ static inline void wait_for_idle(struct atyfb_par *par)
extern void aty_reset_engine(const struct atyfb_par *par);
extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
-extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par);
void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index a9a8272f7a6e..05111e90f168 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3087,17 +3087,18 @@ static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info,
/*
* PLL Reference Divider M:
*/
- M = pll_regs[2];
+ M = pll_regs[PLL_REF_DIV];
/*
* PLL Feedback Divider N (Dependent on CLOCK_CNTL):
*/
- N = pll_regs[7 + (clock_cntl & 3)];
+ N = pll_regs[VCLK0_FB_DIV + (clock_cntl & 3)];
/*
* PLL Post Divider P (Dependent on CLOCK_CNTL):
*/
- P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
+ P = aty_postdividers[((pll_regs[VCLK_POST_DIV] >> ((clock_cntl & 3) << 1)) & 3) |
+ ((pll_regs[PLL_EXT_CNTL] >> (2 + (clock_cntl & 3))) & 4)];
/*
* PLL Divider Q:
diff --git a/drivers/video/fbdev/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c
index 74a62aa193c0..f87cc81f4fa2 100644
--- a/drivers/video/fbdev/aty/mach64_ct.c
+++ b/drivers/video/fbdev/aty/mach64_ct.c
@@ -115,7 +115,7 @@ static void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par)
*/
#define Maximum_DSP_PRECISION 7
-static u8 postdividers[] = {1,2,4,8,3};
+const u8 aty_postdividers[8] = {1,2,4,8,3,5,6,12};
static int aty_dsp_gt(const struct fb_info *info, u32 bpp, struct pll_ct *pll)
{
@@ -222,7 +222,7 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll
pll->vclk_post_div += (q < 64*8);
pll->vclk_post_div += (q < 32*8);
}
- pll->vclk_post_div_real = postdividers[pll->vclk_post_div];
+ pll->vclk_post_div_real = aty_postdividers[pll->vclk_post_div];
// pll->vclk_post_div <<= 6;
pll->vclk_fb_div = q * pll->vclk_post_div_real / 8;
pllvclk = (1000000 * 2 * pll->vclk_fb_div) /
@@ -513,7 +513,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll)
u8 mclk_fb_div, pll_ext_cntl;
pll->ct.pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
pll_ext_cntl = aty_ld_pll_ct(PLL_EXT_CNTL, par);
- pll->ct.xclk_post_div_real = postdividers[pll_ext_cntl & 0x07];
+ pll->ct.xclk_post_div_real = aty_postdividers[pll_ext_cntl & 0x07];
mclk_fb_div = aty_ld_pll_ct(MCLK_FB_DIV, par);
if (pll_ext_cntl & PLL_MFB_TIMES_4_2B)
mclk_fb_div <<= 1;
@@ -535,7 +535,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll)
xpost_div += (q < 64*8);
xpost_div += (q < 32*8);
}
- pll->ct.xclk_post_div_real = postdividers[xpost_div];
+ pll->ct.xclk_post_div_real = aty_postdividers[xpost_div];
pll->ct.mclk_fb_div = q * pll->ct.xclk_post_div_real / 8;
#ifdef CONFIG_PPC
@@ -584,7 +584,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll)
mpost_div += (q < 64*8);
mpost_div += (q < 32*8);
}
- sclk_post_div_real = postdividers[mpost_div];
+ sclk_post_div_real = aty_postdividers[mpost_div];
pll->ct.sclk_fb_div = q * sclk_post_div_real / 8;
pll->ct.spll_cntl2 = mpost_div << 4;
#ifdef DEBUG
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: FAILED: patch "[PATCH] mach64: detect the dot clock divider correctly on sparc" failed to apply to 4.19-stable tree
2018-11-19 10:47 FAILED: patch "[PATCH] mach64: detect the dot clock divider correctly on sparc" failed to apply to 4.19-stable tree gregkh
@ 2018-11-19 16:41 ` Mikulas Patocka
0 siblings, 0 replies; 2+ messages in thread
From: Mikulas Patocka @ 2018-11-19 16:41 UTC (permalink / raw)
To: gregkh; +Cc: b.zolnierkie, davem, syrjala, stable
[-- Attachment #1: Type: TEXT/PLAIN, Size: 6509 bytes --]
On Mon, 19 Nov 2018, gregkh@linuxfoundation.org wrote:
>
> The patch below does not apply to the 4.19-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <stable@vger.kernel.org>.
It was already applied to 4.19-rc8. (it was likely submitted throught both
the sparc and framebuffer trees).
Mikulas
> thanks,
>
> greg k-h
>
> ------------------ original commit in Linus's tree ------------------
>
> >From ceadddde8875bda7af3824244de3d93e386d08c1 Mon Sep 17 00:00:00 2001
> From: Mikulas Patocka <mpatocka@redhat.com>
> Date: Mon, 8 Oct 2018 12:57:34 +0200
> Subject: [PATCH] mach64: detect the dot clock divider correctly on sparc
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> On Sun Ultra 5, it happens that the dot clock is not set up properly for
> some videomodes. For example, if we set the videomode "r1024x768x60" in
> the firmware, Linux would incorrectly set a videomode with refresh rate
> 180Hz when booting (suprisingly, my LCD monitor can display it, although
> display quality is very low).
>
> The reason is this: Older mach64 cards set the divider in the register
> VCLK_POST_DIV. The register has four 2-bit fields (the field that is
> actually used is specified in the lowest two bits of the register
> CLOCK_CNTL). The 2 bits select divider "1, 2, 4, 8". On newer mach64 cards,
> there's another bit added - the top four bits of PLL_EXT_CNTL extend the
> divider selection, so we have possible dividers "1, 2, 4, 8, 3, 5, 6, 12".
> The Linux driver clears the top four bits of PLL_EXT_CNTL and never sets
> them, so it can work regardless if the card supports them. However, the
> sparc64 firmware may set these extended dividers during boot - and the
> mach64 driver detects incorrect dot clock in this case.
>
> This patch makes the driver read the additional divider bit from
> PLL_EXT_CNTL and calculate the initial refresh rate properly.
>
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
> Acked-by: David S. Miller <davem@davemloft.net>
> Reviewed-by: Ville Syrjälä <syrjala@sci.fi>
> Cc: stable@vger.kernel.org
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
>
> diff --git a/drivers/video/fbdev/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h
> index 8235b285dbb2..d09bab3bf224 100644
> --- a/drivers/video/fbdev/aty/atyfb.h
> +++ b/drivers/video/fbdev/aty/atyfb.h
> @@ -333,6 +333,8 @@ extern const struct aty_pll_ops aty_pll_ct; /* Integrated */
> extern void aty_set_pll_ct(const struct fb_info *info, const union aty_pll *pll);
> extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par);
>
> +extern const u8 aty_postdividers[8];
> +
>
> /*
> * Hardware cursor support
> @@ -359,7 +361,6 @@ static inline void wait_for_idle(struct atyfb_par *par)
>
> extern void aty_reset_engine(const struct atyfb_par *par);
> extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
> -extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par);
>
> void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
> void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
> diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
> index a9a8272f7a6e..05111e90f168 100644
> --- a/drivers/video/fbdev/aty/atyfb_base.c
> +++ b/drivers/video/fbdev/aty/atyfb_base.c
> @@ -3087,17 +3087,18 @@ static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info,
> /*
> * PLL Reference Divider M:
> */
> - M = pll_regs[2];
> + M = pll_regs[PLL_REF_DIV];
>
> /*
> * PLL Feedback Divider N (Dependent on CLOCK_CNTL):
> */
> - N = pll_regs[7 + (clock_cntl & 3)];
> + N = pll_regs[VCLK0_FB_DIV + (clock_cntl & 3)];
>
> /*
> * PLL Post Divider P (Dependent on CLOCK_CNTL):
> */
> - P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
> + P = aty_postdividers[((pll_regs[VCLK_POST_DIV] >> ((clock_cntl & 3) << 1)) & 3) |
> + ((pll_regs[PLL_EXT_CNTL] >> (2 + (clock_cntl & 3))) & 4)];
>
> /*
> * PLL Divider Q:
> diff --git a/drivers/video/fbdev/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c
> index 74a62aa193c0..f87cc81f4fa2 100644
> --- a/drivers/video/fbdev/aty/mach64_ct.c
> +++ b/drivers/video/fbdev/aty/mach64_ct.c
> @@ -115,7 +115,7 @@ static void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par)
> */
>
> #define Maximum_DSP_PRECISION 7
> -static u8 postdividers[] = {1,2,4,8,3};
> +const u8 aty_postdividers[8] = {1,2,4,8,3,5,6,12};
>
> static int aty_dsp_gt(const struct fb_info *info, u32 bpp, struct pll_ct *pll)
> {
> @@ -222,7 +222,7 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll
> pll->vclk_post_div += (q < 64*8);
> pll->vclk_post_div += (q < 32*8);
> }
> - pll->vclk_post_div_real = postdividers[pll->vclk_post_div];
> + pll->vclk_post_div_real = aty_postdividers[pll->vclk_post_div];
> // pll->vclk_post_div <<= 6;
> pll->vclk_fb_div = q * pll->vclk_post_div_real / 8;
> pllvclk = (1000000 * 2 * pll->vclk_fb_div) /
> @@ -513,7 +513,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll)
> u8 mclk_fb_div, pll_ext_cntl;
> pll->ct.pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
> pll_ext_cntl = aty_ld_pll_ct(PLL_EXT_CNTL, par);
> - pll->ct.xclk_post_div_real = postdividers[pll_ext_cntl & 0x07];
> + pll->ct.xclk_post_div_real = aty_postdividers[pll_ext_cntl & 0x07];
> mclk_fb_div = aty_ld_pll_ct(MCLK_FB_DIV, par);
> if (pll_ext_cntl & PLL_MFB_TIMES_4_2B)
> mclk_fb_div <<= 1;
> @@ -535,7 +535,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll)
> xpost_div += (q < 64*8);
> xpost_div += (q < 32*8);
> }
> - pll->ct.xclk_post_div_real = postdividers[xpost_div];
> + pll->ct.xclk_post_div_real = aty_postdividers[xpost_div];
> pll->ct.mclk_fb_div = q * pll->ct.xclk_post_div_real / 8;
>
> #ifdef CONFIG_PPC
> @@ -584,7 +584,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll)
> mpost_div += (q < 64*8);
> mpost_div += (q < 32*8);
> }
> - sclk_post_div_real = postdividers[mpost_div];
> + sclk_post_div_real = aty_postdividers[mpost_div];
> pll->ct.sclk_fb_div = q * sclk_post_div_real / 8;
> pll->ct.spll_cntl2 = mpost_div << 4;
> #ifdef DEBUG
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-11-20 3:06 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-19 10:47 FAILED: patch "[PATCH] mach64: detect the dot clock divider correctly on sparc" failed to apply to 4.19-stable tree gregkh
2018-11-19 16:41 ` Mikulas Patocka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).