Message ID | 20201221223225.14723-2-jae.hyun.yoo@linux.intel.com |
---|---|
State | New |
Headers | show |
Series | Fix kernel panic issues caused by AST2500 Video Engine | expand |
Hi Stephen, On 21/12/2020 23:32, Jae Hyun Yoo wrote: > Video engine uses eclk and vclk for its clock sources and its reset > control is coupled with eclk so the current clock enabling sequence works > like below. > > Enable eclk > De-assert Video Engine reset > 10ms delay > Enable vclk > > It introduces improper reset on the Video Engine hardware and eventually > the hardware generates unexpected DMA memory transfers that can corrupt > memory region in random and sporadic patterns. This issue is observed > very rarely on some specific AST2500 SoCs but it causes a critical > kernel panic with making a various shape of signature so it's extremely > hard to debug. Moreover, the issue is observed even when the video > engine is not actively used because udevd turns on the video engine > hardware for a short time to make a query in every boot. > > To fix this issue, this commit changes the clock handling logic to make > the reset de-assertion triggered after enabling both eclk and vclk. Also, > it adds clk_unprepare call for a case when probe fails. > > Fixes: d2b4387f3bdf ("media: platform: Add Aspeed Video Engine driver") > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> > Reviewed-by: Joel Stanley <joel@jms.id.au> > Reviewed-by: Eddie James <eajames@linux.ibm.com> > > clk: ast2600: fix reset settings for eclk and vclk > > Video engine reset setting should be coupled with eclk to match it > with the setting for previous Aspeed SoCs which is defined in > clk-aspeed.c since all Aspeed SoCs are sharing a single video engine > driver. Also, reset bit 6 is defined as 'Video Engine' reset in > datasheet so it should be de-asserted when eclk is enabled. This > commit fixes the setting. > > Fixes: d3d04f6c330a ("clk: Add support for AST2600 SoC") > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> > Reviewed-by: Joel Stanley <joel@jms.id.au> I think it makes sense to merge this via the media subsystem. Can you Ack this patch? Thanks! Hans > --- > Changes since v1: > - Squashed two patches due to dependency. > > drivers/clk/clk-ast2600.c | 4 ++-- > drivers/media/platform/aspeed-video.c | 9 ++++++--- > 2 files changed, 8 insertions(+), 5 deletions(-) > > diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c > index 177368cac6dd..882da16575d4 100644 > --- a/drivers/clk/clk-ast2600.c > +++ b/drivers/clk/clk-ast2600.c > @@ -60,10 +60,10 @@ static void __iomem *scu_g6_base; > static const struct aspeed_gate_data aspeed_g6_gates[] = { > /* clk rst name parent flags */ > [ASPEED_CLK_GATE_MCLK] = { 0, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */ > - [ASPEED_CLK_GATE_ECLK] = { 1, -1, "eclk-gate", "eclk", 0 }, /* Video Engine */ > + [ASPEED_CLK_GATE_ECLK] = { 1, 6, "eclk-gate", "eclk", 0 }, /* Video Engine */ > [ASPEED_CLK_GATE_GCLK] = { 2, 7, "gclk-gate", NULL, 0 }, /* 2D engine */ > /* vclk parent - dclk/d1clk/hclk/mclk */ > - [ASPEED_CLK_GATE_VCLK] = { 3, 6, "vclk-gate", NULL, 0 }, /* Video Capture */ > + [ASPEED_CLK_GATE_VCLK] = { 3, -1, "vclk-gate", NULL, 0 }, /* Video Capture */ > [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", 0 }, /* PCIe/PCI */ > /* From dpll */ > [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, CLK_IS_CRITICAL }, /* DAC */ > diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c > index c46a79eace98..db072ff2df70 100644 > --- a/drivers/media/platform/aspeed-video.c > +++ b/drivers/media/platform/aspeed-video.c > @@ -514,8 +514,8 @@ static void aspeed_video_off(struct aspeed_video *video) > aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff); > > /* Turn off the relevant clocks */ > - clk_disable(video->vclk); > clk_disable(video->eclk); > + clk_disable(video->vclk); > > clear_bit(VIDEO_CLOCKS_ON, &video->flags); > } > @@ -526,8 +526,8 @@ static void aspeed_video_on(struct aspeed_video *video) > return; > > /* Turn on the relevant clocks */ > - clk_enable(video->eclk); > clk_enable(video->vclk); > + clk_enable(video->eclk); > > set_bit(VIDEO_CLOCKS_ON, &video->flags); > } > @@ -1719,8 +1719,11 @@ static int aspeed_video_probe(struct platform_device *pdev) > return rc; > > rc = aspeed_video_setup_video(video); > - if (rc) > + if (rc) { > + clk_unprepare(video->vclk); > + clk_unprepare(video->eclk); > return rc; > + } > > return 0; > } >
Quoting Jae Hyun Yoo (2020-12-21 14:32:25) > Video engine uses eclk and vclk for its clock sources and its reset > control is coupled with eclk so the current clock enabling sequence works > like below. > > Enable eclk > De-assert Video Engine reset > 10ms delay > Enable vclk > > It introduces improper reset on the Video Engine hardware and eventually > the hardware generates unexpected DMA memory transfers that can corrupt > memory region in random and sporadic patterns. This issue is observed > very rarely on some specific AST2500 SoCs but it causes a critical > kernel panic with making a various shape of signature so it's extremely > hard to debug. Moreover, the issue is observed even when the video > engine is not actively used because udevd turns on the video engine > hardware for a short time to make a query in every boot. > > To fix this issue, this commit changes the clock handling logic to make > the reset de-assertion triggered after enabling both eclk and vclk. Also, > it adds clk_unprepare call for a case when probe fails. > > Fixes: d2b4387f3bdf ("media: platform: Add Aspeed Video Engine driver") > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> > Reviewed-by: Joel Stanley <joel@jms.id.au> > Reviewed-by: Eddie James <eajames@linux.ibm.com> > > clk: ast2600: fix reset settings for eclk and vclk > > Video engine reset setting should be coupled with eclk to match it > with the setting for previous Aspeed SoCs which is defined in > clk-aspeed.c since all Aspeed SoCs are sharing a single video engine > driver. Also, reset bit 6 is defined as 'Video Engine' reset in > datasheet so it should be de-asserted when eclk is enabled. This > commit fixes the setting. > > Fixes: d3d04f6c330a ("clk: Add support for AST2600 SoC") > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> > Reviewed-by: Joel Stanley <joel@jms.id.au> > --- Acked-by: Stephen Boyd <sboyd@kernel.org>
diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c index 177368cac6dd..882da16575d4 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/clk-ast2600.c @@ -60,10 +60,10 @@ static void __iomem *scu_g6_base; static const struct aspeed_gate_data aspeed_g6_gates[] = { /* clk rst name parent flags */ [ASPEED_CLK_GATE_MCLK] = { 0, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */ - [ASPEED_CLK_GATE_ECLK] = { 1, -1, "eclk-gate", "eclk", 0 }, /* Video Engine */ + [ASPEED_CLK_GATE_ECLK] = { 1, 6, "eclk-gate", "eclk", 0 }, /* Video Engine */ [ASPEED_CLK_GATE_GCLK] = { 2, 7, "gclk-gate", NULL, 0 }, /* 2D engine */ /* vclk parent - dclk/d1clk/hclk/mclk */ - [ASPEED_CLK_GATE_VCLK] = { 3, 6, "vclk-gate", NULL, 0 }, /* Video Capture */ + [ASPEED_CLK_GATE_VCLK] = { 3, -1, "vclk-gate", NULL, 0 }, /* Video Capture */ [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", 0 }, /* PCIe/PCI */ /* From dpll */ [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, CLK_IS_CRITICAL }, /* DAC */ diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c index c46a79eace98..db072ff2df70 100644 --- a/drivers/media/platform/aspeed-video.c +++ b/drivers/media/platform/aspeed-video.c @@ -514,8 +514,8 @@ static void aspeed_video_off(struct aspeed_video *video) aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff); /* Turn off the relevant clocks */ - clk_disable(video->vclk); clk_disable(video->eclk); + clk_disable(video->vclk); clear_bit(VIDEO_CLOCKS_ON, &video->flags); } @@ -526,8 +526,8 @@ static void aspeed_video_on(struct aspeed_video *video) return; /* Turn on the relevant clocks */ - clk_enable(video->eclk); clk_enable(video->vclk); + clk_enable(video->eclk); set_bit(VIDEO_CLOCKS_ON, &video->flags); } @@ -1719,8 +1719,11 @@ static int aspeed_video_probe(struct platform_device *pdev) return rc; rc = aspeed_video_setup_video(video); - if (rc) + if (rc) { + clk_unprepare(video->vclk); + clk_unprepare(video->eclk); return rc; + } return 0; }