2021-01-11 07:13:56

by KuoHsiang Chou

[permalink] [raw]
Subject: [PATCH] drm/ast: Disable fast reset after DRAM initial

[Bug][AST2500]
When AST2500 acts as stand-alone VGA so that DRAM and DVO initialization
have to be achieved by VGA driver with P2A (PCI to AHB) enabling.
However, HW suggests disable Fast reset mode after DRAM initializaton,
because fast reset mode is mainly designed for ARM ICE debugger.
Once Fast reset is checked as enabling, WDT (Watch Dog Timer) should be
first enabled to avoid system deadlock before disable fast reset mode.

Signed-off-by: KuoHsiang Chou <[email protected]>
---
drivers/gpu/drm/ast/ast_drv.h | 1 +
drivers/gpu/drm/ast/ast_main.c | 4 ++
drivers/gpu/drm/ast/ast_post.c | 72 ++++++++++++++++++++++------------
3 files changed, 51 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index da6dfb677540..8bdd1482370d 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -320,6 +320,7 @@ bool ast_is_vga_enabled(struct drm_device *dev);
void ast_post_gpu(struct drm_device *dev);
u32 ast_mindwm(struct ast_private *ast, u32 r);
void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
+void patch_ahb_ast2500(struct ast_private *ast);
/* ast dp501 */
void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 3775fe26f792..3c072c6589a2 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -96,6 +96,10 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
+ /* Patch AST2500 */
+ if (((dev->pdev->revision & 0xF0) == 0x40) && ((jregd0 & 0xC0) == 0))
+ patch_ahb_ast2500(ast);
+
/* Double check it's actually working */
data = ast_read32(ast, 0xf004);
if (data != 0xFFFFFFFF) {
diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
index 8902c2f84bf9..2d121c5b2233 100644
--- a/drivers/gpu/drm/ast/ast_post.c
+++ b/drivers/gpu/drm/ast/ast_post.c
@@ -2026,6 +2026,33 @@ static bool ast_dram_init_2500(struct ast_private *ast)
return true;
}

+void patch_ahb_ast2500(struct ast_private *ast)
+{
+ u32 data;
+
+patch_ahb_lock:
+ /* Clear bus lock condition */
+ ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
+ ast_moutdwm(ast, 0x1e600084, 0x00010000);
+ ast_moutdwm(ast, 0x1e600088, 0x00000000);
+ ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
+ data = ast_mindwm(ast, 0x1e6e2070);
+ if (data & 0x08000000) { /* check fast reset */
+
+ ast_moutdwm(ast, 0x1E785004, 0x00000010);
+ ast_moutdwm(ast, 0x1E785008, 0x00004755);
+ ast_moutdwm(ast, 0x1E78500c, 0x00000033);
+ udelay(1000);
+ }
+ ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
+ do {
+ data = ast_mindwm(ast, 0x1e6e2000);
+ if (data == 0xffffffff)
+ goto patch_ahb_lock;
+ } while (data != 1);
+ ast_moutdwm(ast, 0x1e6e207c, 0x08000000); /* clear fast reset */
+}
+
void ast_post_chip_2500(struct drm_device *dev)
{
struct ast_private *ast = to_ast_private(dev);
@@ -2033,39 +2060,32 @@ void ast_post_chip_2500(struct drm_device *dev)
u8 reg;

reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
- if ((reg & 0x80) == 0) {/* vga only */
+ if ((reg & 0xC0) == 0) {/* vga only */
/* Clear bus lock condition */
- ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
- ast_moutdwm(ast, 0x1e600084, 0x00010000);
- ast_moutdwm(ast, 0x1e600088, 0x00000000);
- ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
- ast_write32(ast, 0xf004, 0x1e6e0000);
- ast_write32(ast, 0xf000, 0x1);
- ast_write32(ast, 0x12000, 0x1688a8a8);
- while (ast_read32(ast, 0x12000) != 0x1)
- ;
-
- ast_write32(ast, 0x10000, 0xfc600309);
- while (ast_read32(ast, 0x10000) != 0x1)
- ;
+ patch_ahb_ast2500(ast);
+
+ /* Disable watchdog */
+ ast_moutdwm(ast, 0x1E78502C, 0x00000000);
+ ast_moutdwm(ast, 0x1E78504C, 0x00000000);
+ /* Reset USB port */
+ ast_moutdwm(ast, 0x1E6E2090, 0x20000000); /* add at V1.2 */
+ ast_moutdwm(ast, 0x1E6E2094, 0x00004000); /* add at V1.2 */
+ if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) { /* add at V1.2 */
+ ast_moutdwm(ast, 0x1E6E207C, 0x00800000); /* add at V1.2 */
+ mdelay(100); /* add at V1.2 */
+ ast_moutdwm(ast, 0x1E6E2070, 0x00800000); /* add at V1.2 */
+ } /* add at V1.2 */
+ /* Modify eSPI reset pin */
+ temp = ast_mindwm(ast, 0x1E6E2070); /* add at V1.3 */
+ if (temp & 0x02000000) { /* add at V1.3 */
+ ast_moutdwm(ast, 0x1E6E207C, 0x00004000); /* add at V1.3 */
+ }

/* Slow down CPU/AHB CLK in VGA only mode */
temp = ast_read32(ast, 0x12008);
temp |= 0x73;
ast_write32(ast, 0x12008, temp);

- /* Reset USB port to patch USB unknown device issue */
- ast_moutdwm(ast, 0x1e6e2090, 0x20000000);
- temp = ast_mindwm(ast, 0x1e6e2094);
- temp |= 0x00004000;
- ast_moutdwm(ast, 0x1e6e2094, temp);
- temp = ast_mindwm(ast, 0x1e6e2070);
- if (temp & 0x00800000) {
- ast_moutdwm(ast, 0x1e6e207c, 0x00800000);
- mdelay(100);
- ast_moutdwm(ast, 0x1e6e2070, 0x00800000);
- }
-
if (!ast_dram_init_2500(ast))
drm_err(dev, "DRAM init failed !\n");

--
2.18.4


2021-01-11 07:47:20

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH] drm/ast: Disable fast reset after DRAM initial

Hi

Am 11.01.21 um 07:43 schrieb KuoHsiang Chou:
> [Bug][AST2500]
> When AST2500 acts as stand-alone VGA so that DRAM and DVO initialization
> have to be achieved by VGA driver with P2A (PCI to AHB) enabling.
> However, HW suggests disable Fast reset mode after DRAM initializaton,
> because fast reset mode is mainly designed for ARM ICE debugger.
> Once Fast reset is checked as enabling, WDT (Watch Dog Timer) should be
> first enabled to avoid system deadlock before disable fast reset mode.
>
> Signed-off-by: KuoHsiang Chou <[email protected]>
> ---
> drivers/gpu/drm/ast/ast_drv.h | 1 +
> drivers/gpu/drm/ast/ast_main.c | 4 ++
> drivers/gpu/drm/ast/ast_post.c | 72 ++++++++++++++++++++++------------
> 3 files changed, 51 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
> index da6dfb677540..8bdd1482370d 100644
> --- a/drivers/gpu/drm/ast/ast_drv.h
> +++ b/drivers/gpu/drm/ast/ast_drv.h
> @@ -320,6 +320,7 @@ bool ast_is_vga_enabled(struct drm_device *dev);
> void ast_post_gpu(struct drm_device *dev);
> u32 ast_mindwm(struct ast_private *ast, u32 r);
> void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
> +void patch_ahb_ast2500(struct ast_private *ast);

The function name should be named ast_patch_ahb_2500() because it's not
static.

> /* ast dp501 */
> void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
> bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
> diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
> index 3775fe26f792..3c072c6589a2 100644
> --- a/drivers/gpu/drm/ast/ast_main.c
> +++ b/drivers/gpu/drm/ast/ast_main.c
> @@ -96,6 +96,10 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
> jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
> jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
> if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
> + /* Patch AST2500 */
> + if (((dev->pdev->revision & 0xF0) == 0x40) && ((jregd0 & 0xC0) == 0))

The field dev->pdev is considered deprecated. Instead, you can get the
CP device from dev->dev like this

struct pci_dev *pdev = to_pci_dev(dev->dev);

It's the same instance, but dev->pdev will removed soon.

> + patch_ahb_ast2500(ast);
> +
> /* Double check it's actually working */
> data = ast_read32(ast, 0xf004);
> if (data != 0xFFFFFFFF) {
> diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
> index 8902c2f84bf9..2d121c5b2233 100644
> --- a/drivers/gpu/drm/ast/ast_post.c
> +++ b/drivers/gpu/drm/ast/ast_post.c
> @@ -2026,6 +2026,33 @@ static bool ast_dram_init_2500(struct ast_private *ast)
> return true;
> }
>
> +void patch_ahb_ast2500(struct ast_private *ast)
> +{
> + u32 data;
> +
> +patch_ahb_lock:
> + /* Clear bus lock condition */
> + ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
> + ast_moutdwm(ast, 0x1e600084, 0x00010000);
> + ast_moutdwm(ast, 0x1e600088, 0x00000000);
> + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> + data = ast_mindwm(ast, 0x1e6e2070);
> + if (data & 0x08000000) { /* check fast reset */
> +
> + ast_moutdwm(ast, 0x1E785004, 0x00000010);
> + ast_moutdwm(ast, 0x1E785008, 0x00004755);
> + ast_moutdwm(ast, 0x1E78500c, 0x00000033);
> + udelay(1000);
> + }
> + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> + do {
> + data = ast_mindwm(ast, 0x1e6e2000);
> + if (data == 0xffffffff)
> + goto patch_ahb_lock;
> + } while (data != 1);
> + ast_moutdwm(ast, 0x1e6e207c, 0x08000000); /* clear fast reset */
> +}
> +
> void ast_post_chip_2500(struct drm_device *dev)
> {
> struct ast_private *ast = to_ast_private(dev);
> @@ -2033,39 +2060,32 @@ void ast_post_chip_2500(struct drm_device *dev)
> u8 reg;
>
> reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
> - if ((reg & 0x80) == 0) {/* vga only */
> + if ((reg & 0xC0) == 0) {/* vga only */
> /* Clear bus lock condition */
> - ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
> - ast_moutdwm(ast, 0x1e600084, 0x00010000);
> - ast_moutdwm(ast, 0x1e600088, 0x00000000);
> - ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> - ast_write32(ast, 0xf004, 0x1e6e0000);
> - ast_write32(ast, 0xf000, 0x1);
> - ast_write32(ast, 0x12000, 0x1688a8a8);
> - while (ast_read32(ast, 0x12000) != 0x1)
> - ;
> -
> - ast_write32(ast, 0x10000, 0xfc600309);
> - while (ast_read32(ast, 0x10000) != 0x1)
> - ;
> + patch_ahb_ast2500(ast);
> +
> + /* Disable watchdog */
> + ast_moutdwm(ast, 0x1E78502C, 0x00000000);
> + ast_moutdwm(ast, 0x1E78504C, 0x00000000);
> + /* Reset USB port */
> + ast_moutdwm(ast, 0x1E6E2090, 0x20000000); /* add at V1.2 */
> + ast_moutdwm(ast, 0x1E6E2094, 0x00004000); /* add at V1.2 */
> + if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) { /* add at V1.2 */
> + ast_moutdwm(ast, 0x1E6E207C, 0x00800000); /* add at V1.2 */
> + mdelay(100); /* add at V1.2 */
> + ast_moutdwm(ast, 0x1E6E2070, 0x00800000); /* add at V1.2 */
> + } /* add at V1.2 */
> + /* Modify eSPI reset pin */
> + temp = ast_mindwm(ast, 0x1E6E2070); /* add at V1.3 */
> + if (temp & 0x02000000) { /* add at V1.3 */
> + ast_moutdwm(ast, 0x1E6E207C, 0x00004000); /* add at V1.3 */
> + }

Do these v1.2 and v1.3 code paths not need a version check in the code?

Best regards
Thomas

>
> /* Slow down CPU/AHB CLK in VGA only mode */
> temp = ast_read32(ast, 0x12008);
> temp |= 0x73;
> ast_write32(ast, 0x12008, temp);
>
> - /* Reset USB port to patch USB unknown device issue */
> - ast_moutdwm(ast, 0x1e6e2090, 0x20000000);
> - temp = ast_mindwm(ast, 0x1e6e2094);
> - temp |= 0x00004000;
> - ast_moutdwm(ast, 0x1e6e2094, temp);
> - temp = ast_mindwm(ast, 0x1e6e2070);
> - if (temp & 0x00800000) {
> - ast_moutdwm(ast, 0x1e6e207c, 0x00800000);
> - mdelay(100);
> - ast_moutdwm(ast, 0x1e6e2070, 0x00800000);
> - }
> -
> if (!ast_dram_init_2500(ast))
> drm_err(dev, "DRAM init failed !\n");
>
> --
> 2.18.4
>
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


Attachments:
OpenPGP_signature (855.00 B)
OpenPGP digital signature

2021-01-12 11:43:01

by KuoHsiang Chou

[permalink] [raw]
Subject: [PATCH v2] drm/ast: Disable fast reset after DRAM initial

[Bug][AST2500]

V1:
When AST2500 acts as stand-alone VGA so that DRAM and DVO initialization
have to be achieved by VGA driver with P2A (PCI to AHB) enabling.
However, HW suggests disable Fast reset mode after DRAM initializaton,
because fast reset mode is mainly designed for ARM ICE debugger.
Once Fast reset is checked as enabling, WDT (Watch Dog Timer) should be
first enabled to avoid system deadlock before disable fast reset mode.

V2:
Use to_pci_dev() to get revision of PCI configuration.

Signed-off-by: KuoHsiang Chou <[email protected]>
---
drivers/gpu/drm/ast/ast_drv.h | 1 +
drivers/gpu/drm/ast/ast_main.c | 5 +++
drivers/gpu/drm/ast/ast_post.c | 71 +++++++++++++++++++++-------------
3 files changed, 51 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index da6dfb677540..a2cf5fef2399 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -320,6 +320,7 @@ bool ast_is_vga_enabled(struct drm_device *dev);
void ast_post_gpu(struct drm_device *dev);
u32 ast_mindwm(struct ast_private *ast, u32 r);
void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
+void ast_patch_ahb_2500(struct ast_private *ast);
/* ast dp501 */
void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 3775fe26f792..0e4dfcc25623 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -69,6 +69,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
{
struct device_node *np = dev->pdev->dev.of_node;
struct ast_private *ast = to_ast_private(dev);
+ struct pci_dev *pdev = to_pci_dev(dev->dev);
uint32_t data, jregd0, jregd1;

/* Defaults */
@@ -96,6 +97,10 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
+ /* Patch AST2500 */
+ if (((pdev->revision & 0xF0) == 0x40) && ((jregd0 & 0xC0) == 0))
+ ast_patch_ahb_2500(ast);
+
/* Double check it's actually working */
data = ast_read32(ast, 0xf004);
if (data != 0xFFFFFFFF) {
diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
index 8902c2f84bf9..1f0007daa005 100644
--- a/drivers/gpu/drm/ast/ast_post.c
+++ b/drivers/gpu/drm/ast/ast_post.c
@@ -2026,6 +2026,33 @@ static bool ast_dram_init_2500(struct ast_private *ast)
return true;
}

+void ast_patch_ahb_2500(struct ast_private *ast)
+{
+ u32 data;
+
+patch_ahb_lock:
+ /* Clear bus lock condition */
+ ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
+ ast_moutdwm(ast, 0x1e600084, 0x00010000);
+ ast_moutdwm(ast, 0x1e600088, 0x00000000);
+ ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
+ data = ast_mindwm(ast, 0x1e6e2070);
+ if (data & 0x08000000) { /* check fast reset */
+
+ ast_moutdwm(ast, 0x1E785004, 0x00000010);
+ ast_moutdwm(ast, 0x1E785008, 0x00004755);
+ ast_moutdwm(ast, 0x1E78500c, 0x00000033);
+ udelay(1000);
+ }
+ ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
+ do {
+ data = ast_mindwm(ast, 0x1e6e2000);
+ if (data == 0xffffffff)
+ goto patch_ahb_lock;
+ } while (data != 1);
+ ast_moutdwm(ast, 0x1e6e207c, 0x08000000); /* clear fast reset */
+}
+
void ast_post_chip_2500(struct drm_device *dev)
{
struct ast_private *ast = to_ast_private(dev);
@@ -2033,39 +2060,31 @@ void ast_post_chip_2500(struct drm_device *dev)
u8 reg;

reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
- if ((reg & 0x80) == 0) {/* vga only */
+ if ((reg & 0xC0) == 0) {/* vga only */
/* Clear bus lock condition */
- ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
- ast_moutdwm(ast, 0x1e600084, 0x00010000);
- ast_moutdwm(ast, 0x1e600088, 0x00000000);
- ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
- ast_write32(ast, 0xf004, 0x1e6e0000);
- ast_write32(ast, 0xf000, 0x1);
- ast_write32(ast, 0x12000, 0x1688a8a8);
- while (ast_read32(ast, 0x12000) != 0x1)
- ;
-
- ast_write32(ast, 0x10000, 0xfc600309);
- while (ast_read32(ast, 0x10000) != 0x1)
- ;
+ ast_patch_ahb_2500(ast);
+
+ /* Disable watchdog */
+ ast_moutdwm(ast, 0x1E78502C, 0x00000000);
+ ast_moutdwm(ast, 0x1E78504C, 0x00000000);
+ /* Reset USB port */
+ ast_moutdwm(ast, 0x1E6E2090, 0x20000000);
+ ast_moutdwm(ast, 0x1E6E2094, 0x00004000);
+ if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) {
+ ast_moutdwm(ast, 0x1E6E207C, 0x00800000);
+ mdelay(100);
+ ast_moutdwm(ast, 0x1E6E2070, 0x00800000);
+ }
+ /* Modify eSPI reset pin */
+ temp = ast_mindwm(ast, 0x1E6E2070);
+ if (temp & 0x02000000)
+ ast_moutdwm(ast, 0x1E6E207C, 0x00004000);

/* Slow down CPU/AHB CLK in VGA only mode */
temp = ast_read32(ast, 0x12008);
temp |= 0x73;
ast_write32(ast, 0x12008, temp);

- /* Reset USB port to patch USB unknown device issue */
- ast_moutdwm(ast, 0x1e6e2090, 0x20000000);
- temp = ast_mindwm(ast, 0x1e6e2094);
- temp |= 0x00004000;
- ast_moutdwm(ast, 0x1e6e2094, temp);
- temp = ast_mindwm(ast, 0x1e6e2070);
- if (temp & 0x00800000) {
- ast_moutdwm(ast, 0x1e6e207c, 0x00800000);
- mdelay(100);
- ast_moutdwm(ast, 0x1e6e2070, 0x00800000);
- }
-
if (!ast_dram_init_2500(ast))
drm_err(dev, "DRAM init failed !\n");

--
2.18.4

2021-01-18 09:27:25

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH v2] drm/ast: Disable fast reset after DRAM initial

Hi

Am 12.01.21 um 08:58 schrieb KuoHsiang Chou:
> [Bug][AST2500]
>
> V1:
> When AST2500 acts as stand-alone VGA so that DRAM and DVO initialization
> have to be achieved by VGA driver with P2A (PCI to AHB) enabling.
> However, HW suggests disable Fast reset mode after DRAM initializaton,
> because fast reset mode is mainly designed for ARM ICE debugger.
> Once Fast reset is checked as enabling, WDT (Watch Dog Timer) should be
> first enabled to avoid system deadlock before disable fast reset mode.
>
> V2:
> Use to_pci_dev() to get revision of PCI configuration.
>
> Signed-off-by: KuoHsiang Chou <[email protected]>
> ---
> drivers/gpu/drm/ast/ast_drv.h | 1 +
> drivers/gpu/drm/ast/ast_main.c | 5 +++
> drivers/gpu/drm/ast/ast_post.c | 71 +++++++++++++++++++++-------------
> 3 files changed, 51 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
> index da6dfb677540..a2cf5fef2399 100644
> --- a/drivers/gpu/drm/ast/ast_drv.h
> +++ b/drivers/gpu/drm/ast/ast_drv.h
> @@ -320,6 +320,7 @@ bool ast_is_vga_enabled(struct drm_device *dev);
> void ast_post_gpu(struct drm_device *dev);
> u32 ast_mindwm(struct ast_private *ast, u32 r);
> void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
> +void ast_patch_ahb_2500(struct ast_private *ast);
> /* ast dp501 */
> void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
> bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
> diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
> index 3775fe26f792..0e4dfcc25623 100644
> --- a/drivers/gpu/drm/ast/ast_main.c
> +++ b/drivers/gpu/drm/ast/ast_main.c
> @@ -69,6 +69,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
> {
> struct device_node *np = dev->pdev->dev.of_node;
> struct ast_private *ast = to_ast_private(dev);
> + struct pci_dev *pdev = to_pci_dev(dev->dev);
> uint32_t data, jregd0, jregd1;
>
> /* Defaults */
> @@ -96,6 +97,10 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
> jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
> jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
> if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
> + /* Patch AST2500 */
> + if (((pdev->revision & 0xF0) == 0x40) && ((jregd0 & 0xC0) == 0))
> + ast_patch_ahb_2500(ast);
> +
> /* Double check it's actually working */
> data = ast_read32(ast, 0xf004);
> if (data != 0xFFFFFFFF) {
> diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
> index 8902c2f84bf9..1f0007daa005 100644
> --- a/drivers/gpu/drm/ast/ast_post.c
> +++ b/drivers/gpu/drm/ast/ast_post.c
> @@ -2026,6 +2026,33 @@ static bool ast_dram_init_2500(struct ast_private *ast)
> return true;
> }
>
> +void ast_patch_ahb_2500(struct ast_private *ast)
> +{
> + u32 data;
> +
> +patch_ahb_lock:
> + /* Clear bus lock condition */
> + ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
> + ast_moutdwm(ast, 0x1e600084, 0x00010000);
> + ast_moutdwm(ast, 0x1e600088, 0x00000000);
> + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> + data = ast_mindwm(ast, 0x1e6e2070);
> + if (data & 0x08000000) { /* check fast reset */
> +
> + ast_moutdwm(ast, 0x1E785004, 0x00000010);
> + ast_moutdwm(ast, 0x1E785008, 0x00004755);
> + ast_moutdwm(ast, 0x1E78500c, 0x00000033);
> + udelay(1000);
> + }
> + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> + do {
> + data = ast_mindwm(ast, 0x1e6e2000);
> + if (data == 0xffffffff)
> + goto patch_ahb_lock;
> + } while (data != 1);
> + ast_moutdwm(ast, 0x1e6e207c, 0x08000000); /* clear fast reset */
> +}
> +
> void ast_post_chip_2500(struct drm_device *dev)
> {
> struct ast_private *ast = to_ast_private(dev);
> @@ -2033,39 +2060,31 @@ void ast_post_chip_2500(struct drm_device *dev)
> u8 reg;
>
> reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
> - if ((reg & 0x80) == 0) {/* vga only */
> + if ((reg & 0xC0) == 0) {/* vga only */
> /* Clear bus lock condition */
> - ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
> - ast_moutdwm(ast, 0x1e600084, 0x00010000);
> - ast_moutdwm(ast, 0x1e600088, 0x00000000);
> - ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> - ast_write32(ast, 0xf004, 0x1e6e0000);
> - ast_write32(ast, 0xf000, 0x1);
> - ast_write32(ast, 0x12000, 0x1688a8a8);
> - while (ast_read32(ast, 0x12000) != 0x1)
> - ;
> -
> - ast_write32(ast, 0x10000, 0xfc600309);
> - while (ast_read32(ast, 0x10000) != 0x1)
> - ;
> + ast_patch_ahb_2500(ast);
> +
> + /* Disable watchdog */
> + ast_moutdwm(ast, 0x1E78502C, 0x00000000);
> + ast_moutdwm(ast, 0x1E78504C, 0x00000000);
> + /* Reset USB port */
> + ast_moutdwm(ast, 0x1E6E2090, 0x20000000);
> + ast_moutdwm(ast, 0x1E6E2094, 0x00004000);
> + if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) {
> + ast_moutdwm(ast, 0x1E6E207C, 0x00800000);
> + mdelay(100);
> + ast_moutdwm(ast, 0x1E6E2070, 0x00800000);
> + }
> + /* Modify eSPI reset pin */
> + temp = ast_mindwm(ast, 0x1E6E2070);
> + if (temp & 0x02000000)
> + ast_moutdwm(ast, 0x1E6E207C, 0x00004000);

Instead of answering my question, you simply deleted the comments. It
doesn't work like that.

Best regards
Thomas

>
> /* Slow down CPU/AHB CLK in VGA only mode */
> temp = ast_read32(ast, 0x12008);
> temp |= 0x73;
> ast_write32(ast, 0x12008, temp);
>
> - /* Reset USB port to patch USB unknown device issue */
> - ast_moutdwm(ast, 0x1e6e2090, 0x20000000);
> - temp = ast_mindwm(ast, 0x1e6e2094);
> - temp |= 0x00004000;
> - ast_moutdwm(ast, 0x1e6e2094, temp);
> - temp = ast_mindwm(ast, 0x1e6e2070);
> - if (temp & 0x00800000) {
> - ast_moutdwm(ast, 0x1e6e207c, 0x00800000);
> - mdelay(100);
> - ast_moutdwm(ast, 0x1e6e2070, 0x00800000);
> - }
> -
> if (!ast_dram_init_2500(ast))
> drm_err(dev, "DRAM init failed !\n");
>
> --
> 2.18.4
>
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


Attachments:
OpenPGP_signature (855.00 B)
OpenPGP digital signature

2021-01-19 05:47:11

by KuoHsiang Chou

[permalink] [raw]
Subject: RE: [PATCH v2] drm/ast: Disable fast reset after DRAM initial

-----Original Message-----
From: Thomas Zimmermann [mailto:[email protected]]
Sent: Monday, January 18, 2021 5:06 PM
To: Kuo-Hsiang Chou <[email protected]>; [email protected]; [email protected]

Subject: Re: [PATCH v2] drm/ast: Disable fast reset after DRAM initial

Hi, Thomas,

Hi

Am 12.01.21 um 08:58 schrieb KuoHsiang Chou:
> [Bug][AST2500]
>
> V1:
> When AST2500 acts as stand-alone VGA so that DRAM and DVO
> initialization have to be achieved by VGA driver with P2A (PCI to AHB) enabling.
> However, HW suggests disable Fast reset mode after DRAM initializaton,
> because fast reset mode is mainly designed for ARM ICE debugger.
> Once Fast reset is checked as enabling, WDT (Watch Dog Timer) should
> be first enabled to avoid system deadlock before disable fast reset mode.
>
> V2:
> Use to_pci_dev() to get revision of PCI configuration.
>
> Signed-off-by: KuoHsiang Chou <[email protected]>
> ---
> drivers/gpu/drm/ast/ast_drv.h | 1 +
> drivers/gpu/drm/ast/ast_main.c | 5 +++
> drivers/gpu/drm/ast/ast_post.c | 71 +++++++++++++++++++++-------------
> 3 files changed, 51 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/ast/ast_drv.h
> b/drivers/gpu/drm/ast/ast_drv.h index da6dfb677540..a2cf5fef2399
> 100644
> --- a/drivers/gpu/drm/ast/ast_drv.h
> +++ b/drivers/gpu/drm/ast/ast_drv.h
> @@ -320,6 +320,7 @@ bool ast_is_vga_enabled(struct drm_device *dev);
> void ast_post_gpu(struct drm_device *dev);
> u32 ast_mindwm(struct ast_private *ast, u32 r);
> void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
> +void ast_patch_ahb_2500(struct ast_private *ast);
> /* ast dp501 */
> void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
> bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); diff
> --git a/drivers/gpu/drm/ast/ast_main.c
> b/drivers/gpu/drm/ast/ast_main.c index 3775fe26f792..0e4dfcc25623
> 100644
> --- a/drivers/gpu/drm/ast/ast_main.c
> +++ b/drivers/gpu/drm/ast/ast_main.c
> @@ -69,6 +69,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
> {
> struct device_node *np = dev->pdev->dev.of_node;
> struct ast_private *ast = to_ast_private(dev);
> + struct pci_dev *pdev = to_pci_dev(dev->dev);
> uint32_t data, jregd0, jregd1;
>
> /* Defaults */
> @@ -96,6 +97,10 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
> jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
> jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
> if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
> + /* Patch AST2500 */
> + if (((pdev->revision & 0xF0) == 0x40) && ((jregd0 & 0xC0) == 0))
> + ast_patch_ahb_2500(ast);
> +
> /* Double check it's actually working */
> data = ast_read32(ast, 0xf004);
> if (data != 0xFFFFFFFF) {
> diff --git a/drivers/gpu/drm/ast/ast_post.c
> b/drivers/gpu/drm/ast/ast_post.c index 8902c2f84bf9..1f0007daa005
> 100644
> --- a/drivers/gpu/drm/ast/ast_post.c
> +++ b/drivers/gpu/drm/ast/ast_post.c
> @@ -2026,6 +2026,33 @@ static bool ast_dram_init_2500(struct ast_private *ast)
> return true;
> }
>
> +void ast_patch_ahb_2500(struct ast_private *ast) {
> + u32 data;
> +
> +patch_ahb_lock:
> + /* Clear bus lock condition */
> + ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
> + ast_moutdwm(ast, 0x1e600084, 0x00010000);
> + ast_moutdwm(ast, 0x1e600088, 0x00000000);
> + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> + data = ast_mindwm(ast, 0x1e6e2070);
> + if (data & 0x08000000) { /* check fast reset */
> +
> + ast_moutdwm(ast, 0x1E785004, 0x00000010);
> + ast_moutdwm(ast, 0x1E785008, 0x00004755);
> + ast_moutdwm(ast, 0x1E78500c, 0x00000033);
> + udelay(1000);
> + }
> + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> + do {
> + data = ast_mindwm(ast, 0x1e6e2000);
> + if (data == 0xffffffff)
> + goto patch_ahb_lock;
> + } while (data != 1);
> + ast_moutdwm(ast, 0x1e6e207c, 0x08000000); /* clear fast reset */
> +}
> +
> void ast_post_chip_2500(struct drm_device *dev)
> {
> struct ast_private *ast = to_ast_private(dev); @@ -2033,39 +2060,31
> @@ void ast_post_chip_2500(struct drm_device *dev)
> u8 reg;
>
> reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
> - if ((reg & 0x80) == 0) {/* vga only */
> + if ((reg & 0xC0) == 0) {/* vga only */
> /* Clear bus lock condition */
> - ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
> - ast_moutdwm(ast, 0x1e600084, 0x00010000);
> - ast_moutdwm(ast, 0x1e600088, 0x00000000);
> - ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
> - ast_write32(ast, 0xf004, 0x1e6e0000);
> - ast_write32(ast, 0xf000, 0x1);
> - ast_write32(ast, 0x12000, 0x1688a8a8);
> - while (ast_read32(ast, 0x12000) != 0x1)
> - ;
> -
> - ast_write32(ast, 0x10000, 0xfc600309);
> - while (ast_read32(ast, 0x10000) != 0x1)
> - ;
> + ast_patch_ahb_2500(ast);
> +
> + /* Disable watchdog */
> + ast_moutdwm(ast, 0x1E78502C, 0x00000000);
> + ast_moutdwm(ast, 0x1E78504C, 0x00000000);
> + /* Reset USB port */
> + ast_moutdwm(ast, 0x1E6E2090, 0x20000000);
> + ast_moutdwm(ast, 0x1E6E2094, 0x00004000);
> + if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) {
> + ast_moutdwm(ast, 0x1E6E207C, 0x00800000);
> + mdelay(100);
> + ast_moutdwm(ast, 0x1E6E2070, 0x00800000);
> + }
> + /* Modify eSPI reset pin */
> + temp = ast_mindwm(ast, 0x1E6E2070);
> + if (temp & 0x02000000)
> + ast_moutdwm(ast, 0x1E6E207C, 0x00004000);

Instead of answering my question, you simply deleted the comments. It doesn't work like that.

My bad!
About to /* add at V1.2 */ and /* add at V1.3 */, the comments should be some marks of recommendations came from HW designer.
Therefore, I thought this kind of comments could be deleted directly.
Sorry for my poor English, so that the biggest error is that I misunderstood your question likes a sentence of "why not ....".
Should I recover the comments? Thanks!

Best Regards,
Kuo-Hsiang Chou


Best regards
Thomas

>
> /* Slow down CPU/AHB CLK in VGA only mode */
> temp = ast_read32(ast, 0x12008);
> temp |= 0x73;
> ast_write32(ast, 0x12008, temp);
>
> - /* Reset USB port to patch USB unknown device issue */
> - ast_moutdwm(ast, 0x1e6e2090, 0x20000000);
> - temp = ast_mindwm(ast, 0x1e6e2094);
> - temp |= 0x00004000;
> - ast_moutdwm(ast, 0x1e6e2094, temp);
> - temp = ast_mindwm(ast, 0x1e6e2070);
> - if (temp & 0x00800000) {
> - ast_moutdwm(ast, 0x1e6e207c, 0x00800000);
> - mdelay(100);
> - ast_moutdwm(ast, 0x1e6e2070, 0x00800000);
> - }
> -
> if (!ast_dram_init_2500(ast))
> drm_err(dev, "DRAM init failed !\n");
>
> --
> 2.18.4
>
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer