[PATCH 2/9] drm/ast: POST chip at probe time if VGA not enabled
We need to do it on machines without a BIOS such as POWER8. Also for detection to work without triggering PCIe errors, we need to enable VGA early on, inside ast_detect_chip(). While touching those files, replace a few hard coded register numbers with the corresponding symbolic constant. Signed-off-by: Benjamin Herrenschmidt --- drivers/gpu/drm/ast/ast_drv.h | 3 +++ drivers/gpu/drm/ast/ast_main.c | 47 -- drivers/gpu/drm/ast/ast_post.c | 23 + 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index a203a6f..78fc683 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -384,6 +384,9 @@ int ast_bo_push_sysram(struct ast_bo *bo); int ast_mmap(struct file *filp, struct vm_area_struct *vma); /* ast post */ +void ast_enable_vga(struct drm_device *dev); +void ast_enable_mmio(struct drm_device *dev); +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); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index c2ff793..556d065 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -63,7 +63,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast, } -static int ast_detect_chip(struct drm_device *dev) +static int ast_detect_chip(struct drm_device *dev, bool *need_post) { struct ast_private *ast = dev->dev_private; uint32_t data, jreg; @@ -109,6 +109,21 @@ static int ast_detect_chip(struct drm_device *dev) } } + /* +* If VGA isn't enabled, we need to enable now or subsequent +* access to the scratch registers will fail. We also inform +* our caller that it needs to POST the chip +* (Assumption: VGA not enabled -> need to POST) +*/ + if (!ast_is_vga_enabled(dev)) { + ast_enable_vga(dev); + ast_enable_mmio(dev); + DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); + *need_post = true; + } else + *need_post = false; + + /* Check if we support wide screen */ switch (ast->chip) { case AST1180: ast->support_wide_screen = true; @@ -124,6 +139,7 @@ static int ast_detect_chip(struct drm_device *dev) ast->support_wide_screen = true; else { ast->support_wide_screen = false; + /* Read SCU7c (silicon revision register) */ ast_write32(ast, 0xf004, 0x1e6e); ast_write32(ast, 0xf000, 0x1); data = ast_read32(ast, 0x1207c); @@ -136,11 +152,23 @@ static int ast_detect_chip(struct drm_device *dev) break; } + /* Check 3rd Tx option (digital output afaik) */ ast->tx_chip_type = AST_TX_NONE; + + /* +* VGACRA3 Enhanced Color Mode Register, check if DVO is already +* enabled, in that case, assume we have a SIL164 TMDS transmitter +*/ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); if (jreg & 0x80) ast->tx_chip_type = AST_TX_SIL164; + if ((ast->chip == AST2300) || (ast->chip == AST2400)) { + /* +* On AST2300 and 2400, look the configuration set by the SoC in +* the SOC scratch register #1 bits 11:8 (interestingly marked +* as "reserved" in the spec +*/ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); switch (jreg) { case 0x04: @@ -161,6 +189,17 @@ static int ast_detect_chip(struct drm_device *dev) } } + /* Print stuff for diagnostic purposes */ + switch(ast->tx_chip_type) { + case AST_TX_SIL164: + DRM_INFO("Using Sil164 TMDS transmitter\n"); + break; + case AST_TX_DP501: + DRM_INFO("Using DP501 DisplayPort transmitter\n"); + break; + default: + DRM_INFO("Analog VGA only\n"); + } return 0; } @@ -345,6 +384,7 @@ static u32 ast_get_vram_info(struct drm_device *dev) int ast_driver_load(struct drm_device *dev, unsigned long flags) { struct ast_private *ast; + bool need_post; int ret = 0; ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); @@ -379,7 +419,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) } } - ast_detect_chip(dev); + ast_detect_chip(dev, _post); if (ast->chip != AST1180) { ast_get_dram_info(dev); @@ -387,6 +427,9 @@ int ast_driver_load(struct drm_device *dev,
[PATCH 2/9] drm/ast: POST chip at probe time if VGA not enabled
We need to do it on machines without a BIOS such as POWER8. Also for detection to work without triggering PCIe errors, we need to enable VGA early on, inside ast_detect_chip(). While touching those files, replace a few hard coded register numbers with the corresponding symbolic constant. Signed-off-by: Benjamin Herrenschmidt --- drivers/gpu/drm/ast/ast_drv.h | 3 +++ drivers/gpu/drm/ast/ast_main.c | 47 -- drivers/gpu/drm/ast/ast_post.c | 23 + 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index a203a6f..78fc683 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -384,6 +384,9 @@ int ast_bo_push_sysram(struct ast_bo *bo); int ast_mmap(struct file *filp, struct vm_area_struct *vma); /* ast post */ +void ast_enable_vga(struct drm_device *dev); +void ast_enable_mmio(struct drm_device *dev); +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); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index c2ff793..556d065 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -63,7 +63,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast, } -static int ast_detect_chip(struct drm_device *dev) +static int ast_detect_chip(struct drm_device *dev, bool *need_post) { struct ast_private *ast = dev->dev_private; uint32_t data, jreg; @@ -109,6 +109,21 @@ static int ast_detect_chip(struct drm_device *dev) } } + /* +* If VGA isn't enabled, we need to enable now or subsequent +* access to the scratch registers will fail. We also inform +* our caller that it needs to POST the chip +* (Assumption: VGA not enabled -> need to POST) +*/ + if (!ast_is_vga_enabled(dev)) { + ast_enable_vga(dev); + ast_enable_mmio(dev); + DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); + *need_post = true; + } else + *need_post = false; + + /* Check if we support wide screen */ switch (ast->chip) { case AST1180: ast->support_wide_screen = true; @@ -124,6 +139,7 @@ static int ast_detect_chip(struct drm_device *dev) ast->support_wide_screen = true; else { ast->support_wide_screen = false; + /* Read SCU7c (silicon revision register) */ ast_write32(ast, 0xf004, 0x1e6e); ast_write32(ast, 0xf000, 0x1); data = ast_read32(ast, 0x1207c); @@ -136,11 +152,23 @@ static int ast_detect_chip(struct drm_device *dev) break; } + /* Check 3rd Tx option (digital output afaik) */ ast->tx_chip_type = AST_TX_NONE; + + /* +* VGACRA3 Enhanced Color Mode Register, check if DVO is already +* enabled, in that case, assume we have a SIL164 TMDS transmitter +*/ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); if (jreg & 0x80) ast->tx_chip_type = AST_TX_SIL164; + if ((ast->chip == AST2300) || (ast->chip == AST2400)) { + /* +* On AST2300 and 2400, look the configuration set by the SoC in +* the SOC scratch register #1 bits 11:8 (interestingly marked +* as "reserved" in the spec +*/ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); switch (jreg) { case 0x04: @@ -161,6 +189,17 @@ static int ast_detect_chip(struct drm_device *dev) } } + /* Print stuff for diagnostic purposes */ + switch(ast->tx_chip_type) { + case AST_TX_SIL164: + DRM_INFO("Using Sil164 TMDS transmitter\n"); + break; + case AST_TX_DP501: + DRM_INFO("Using DP501 DisplayPort transmitter\n"); + break; + default: + DRM_INFO("Analog VGA only\n"); + } return 0; } @@ -345,6 +384,7 @@ static u32 ast_get_vram_info(struct drm_device *dev) int ast_driver_load(struct drm_device *dev, unsigned long flags) { struct ast_private *ast; + bool need_post; int ret = 0; ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); @@ -379,7 +419,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) } } - ast_detect_chip(dev); + ast_detect_chip(dev, _post); if (ast->chip != AST1180) { ast_get_dram_info(dev); @@ -387,6 +427,9 @@ int ast_driver_load(struct drm_device *dev,