diff options
Diffstat (limited to 'drivers/gpu/drm/ast')
-rw-r--r-- | drivers/gpu/drm/ast/Kconfig | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_dp.c | 141 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_dp501.c | 111 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.h | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 67 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_post.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_reg.h | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_sil164.c | 55 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_vga.c | 55 |
11 files changed, 279 insertions, 293 deletions
diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig index 563fa7a3b546..da0663542e8a 100644 --- a/drivers/gpu/drm/ast/Kconfig +++ b/drivers/gpu/drm/ast/Kconfig @@ -2,6 +2,7 @@ config DRM_AST tristate "AST server chips" depends on DRM && PCI && MMU + select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER select I2C diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index 00b364f9a71e..0e282b7b167c 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -149,28 +149,22 @@ int ast_dp_launch(struct ast_device *ast) return 0; } -static bool ast_dp_power_is_on(struct ast_device *ast) +static bool ast_dp_get_phy_sleep(struct ast_device *ast) { - u8 vgacre3; + u8 vgacre3 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xe3); - vgacre3 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xe3); - - return !(vgacre3 & AST_DP_PHY_SLEEP); + return (vgacre3 & AST_IO_VGACRE3_DP_PHY_SLEEP); } -static void ast_dp_power_on_off(struct drm_device *dev, bool on) +static void ast_dp_set_phy_sleep(struct ast_device *ast, bool sleep) { - struct ast_device *ast = to_ast_device(dev); - // Read and Turn off DP PHY sleep - u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, AST_DP_VIDEO_ENABLE); - - // Turn on DP PHY sleep - if (!on) - bE3 |= AST_DP_PHY_SLEEP; + u8 vgacre3 = 0x00; - // DP Power on/off - ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3); + if (sleep) + vgacre3 |= AST_IO_VGACRE3_DP_PHY_SLEEP; + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe3, (u8)~AST_IO_VGACRE3_DP_PHY_SLEEP, + vgacre3); msleep(50); } @@ -192,23 +186,39 @@ static void ast_dp_link_training(struct ast_device *ast) drm_err(dev, "Link training failed\n"); } -static void ast_dp_set_on_off(struct drm_device *dev, bool on) +static bool __ast_dp_wait_enable(struct ast_device *ast, bool enabled) { - struct ast_device *ast = to_ast_device(dev); - u8 video_on_off = on; - u32 i = 0; - - // Video On/Off - ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); - - video_on_off <<= 4; - while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, - ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) { - // wait 1 ms - mdelay(1); - if (++i > 200) - break; + u8 vgacrdf_test = 0x00; + u8 vgacrdf; + unsigned int i; + + if (enabled) + vgacrdf_test |= AST_IO_VGACRDF_DP_VIDEO_ENABLE; + + for (i = 0; i < 200; ++i) { + if (i) + mdelay(1); + vgacrdf = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xdf, + AST_IO_VGACRDF_DP_VIDEO_ENABLE); + if (vgacrdf == vgacrdf_test) + return true; } + + return false; +} + +static void ast_dp_set_enable(struct ast_device *ast, bool enabled) +{ + struct drm_device *dev = &ast->base; + u8 vgacre3 = 0x00; + + if (enabled) + vgacre3 |= AST_IO_VGACRE3_DP_VIDEO_ENABLE; + + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe3, (u8)~AST_IO_VGACRE3_DP_VIDEO_ENABLE, + vgacre3); + + drm_WARN_ON(dev, !__ast_dp_wait_enable(ast, enabled)); } static void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode) @@ -317,26 +327,25 @@ static void ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder *encoder static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) { - struct drm_device *dev = encoder->dev; - struct ast_device *ast = to_ast_device(dev); + struct ast_device *ast = to_ast_device(encoder->dev); struct ast_connector *ast_connector = &ast->output.astdp.connector; if (ast_connector->physical_status == connector_status_connected) { - ast_dp_power_on_off(dev, AST_DP_POWER_ON); + ast_dp_set_phy_sleep(ast, false); ast_dp_link_training(ast); ast_wait_for_vretrace(ast); - ast_dp_set_on_off(dev, 1); + ast_dp_set_enable(ast, true); } } static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { - struct drm_device *dev = encoder->dev; + struct ast_device *ast = to_ast_device(encoder->dev); - ast_dp_set_on_off(dev, 0); - ast_dp_power_on_off(dev, AST_DP_POWER_OFF); + ast_dp_set_enable(ast, false); + ast_dp_set_phy_sleep(ast, true); } static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = { @@ -383,22 +392,21 @@ static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector bool force) { struct ast_connector *ast_connector = to_ast_connector(connector); - struct drm_device *dev = connector->dev; struct ast_device *ast = to_ast_device(connector->dev); enum drm_connector_status status = connector_status_disconnected; - bool power_is_on; + bool phy_sleep; mutex_lock(&ast->modeset_lock); - power_is_on = ast_dp_power_is_on(ast); - if (!power_is_on) - ast_dp_power_on_off(dev, true); + phy_sleep = ast_dp_get_phy_sleep(ast); + if (phy_sleep) + ast_dp_set_phy_sleep(ast, false); if (ast_astdp_is_connected(ast)) status = connector_status_connected; - if (!power_is_on && status == connector_status_disconnected) - ast_dp_power_on_off(dev, false); + if (phy_sleep && status == connector_status_disconnected) + ast_dp_set_phy_sleep(ast, true); mutex_unlock(&ast->modeset_lock); @@ -414,6 +422,10 @@ static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs .detect_ctx = ast_astdp_connector_helper_detect_ctx, }; +/* + * Output + */ + static const struct drm_connector_funcs ast_astdp_connector_funcs = { .reset = drm_atomic_helper_connector_reset, .fill_modes = drm_helper_probe_single_connector_modes, @@ -422,34 +434,18 @@ static const struct drm_connector_funcs ast_astdp_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector *connector) -{ - int ret; - - ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); - if (ret) - return ret; - - drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs); - - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - - return 0; -} - int ast_astdp_output_init(struct ast_device *ast) { struct drm_device *dev = &ast->base; struct drm_crtc *crtc = &ast->crtc; - struct drm_encoder *encoder = &ast->output.astdp.encoder; - struct ast_connector *ast_connector = &ast->output.astdp.connector; - struct drm_connector *connector = &ast_connector->base; + struct drm_encoder *encoder; + struct ast_connector *ast_connector; + struct drm_connector *connector; int ret; + /* encoder */ + + encoder = &ast->output.astdp.encoder; ret = drm_encoder_init(dev, encoder, &ast_astdp_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret) @@ -458,9 +454,20 @@ int ast_astdp_output_init(struct ast_device *ast) encoder->possible_crtcs = drm_crtc_mask(crtc); - ret = ast_astdp_connector_init(dev, connector); + /* connector */ + + ast_connector = &ast->output.astdp.connector; + connector = &ast_connector->base; + ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs, + DRM_MODE_CONNECTOR_DisplayPort); if (ret) return ret; + drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs); + + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + ast_connector->physical_status = connector->status; ret = drm_connector_attach_encoder(connector, encoder); diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index e4c636f45082..9e19d8c17730 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -21,9 +21,9 @@ static void ast_release_firmware(void *data) ast->dp501_fw = NULL; } -static int ast_load_dp501_microcode(struct drm_device *dev) +static int ast_load_dp501_microcode(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; int ret; ret = request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev); @@ -109,10 +109,10 @@ static bool wait_fw_ready(struct ast_device *ast) } #endif -static bool ast_write_cmd(struct drm_device *dev, u8 data) +static bool ast_write_cmd(struct ast_device *ast, u8 data) { - struct ast_device *ast = to_ast_device(dev); int retry = 0; + if (wait_nack(ast)) { send_nack(ast); ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); @@ -131,10 +131,8 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data) return false; } -static bool ast_write_data(struct drm_device *dev, u8 data) +static bool ast_write_data(struct ast_device *ast, u8 data) { - struct ast_device *ast = to_ast_device(dev); - if (wait_nack(ast)) { send_nack(ast); ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); @@ -175,10 +173,10 @@ static void clear_cmd(struct ast_device *ast) } #endif -static void ast_set_dp501_video_output(struct drm_device *dev, u8 mode) +static void ast_set_dp501_video_output(struct ast_device *ast, u8 mode) { - ast_write_cmd(dev, 0x40); - ast_write_data(dev, mode); + ast_write_cmd(ast, 0x40); + ast_write_data(ast, mode); msleep(10); } @@ -188,9 +186,8 @@ static u32 get_fw_base(struct ast_device *ast) return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff; } -bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) +bool ast_backup_fw(struct ast_device *ast, u8 *addr, u32 size) { - struct ast_device *ast = to_ast_device(dev); u32 i, data; u32 boot_address; @@ -207,9 +204,8 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) return false; } -static bool ast_launch_m68k(struct drm_device *dev) +static bool ast_launch_m68k(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u32 i, data, len = 0; u32 boot_address; u8 *fw_addr = NULL; @@ -226,7 +222,7 @@ static bool ast_launch_m68k(struct drm_device *dev) len = 32*1024; } else { if (!ast->dp501_fw && - ast_load_dp501_microcode(dev) < 0) + ast_load_dp501_microcode(ast) < 0) return false; fw_addr = (u8 *)ast->dp501_fw->data; @@ -348,9 +344,8 @@ static int ast_dp512_read_edid_block(void *data, u8 *buf, unsigned int block, si return true; } -static bool ast_init_dvo(struct drm_device *dev) +static bool ast_init_dvo(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u8 jreg; u32 data; ast_write32(ast, 0xf004, 0x1e6e0000); @@ -421,9 +416,8 @@ static bool ast_init_dvo(struct drm_device *dev) } -static void ast_init_analog(struct drm_device *dev) +static void ast_init_analog(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u32 data; /* @@ -448,28 +442,28 @@ static void ast_init_analog(struct drm_device *dev) ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x00); } -void ast_init_3rdtx(struct drm_device *dev) +void ast_init_3rdtx(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); - u8 jreg; + u8 vgacrd1; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) { - jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); - switch (jreg & 0x0e) { - case 0x04: - ast_init_dvo(dev); + vgacrd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, + AST_IO_VGACRD1_TX_TYPE_MASK); + switch (vgacrd1) { + case AST_IO_VGACRD1_TX_SIL164_VBIOS: + ast_init_dvo(ast); break; - case 0x08: - ast_launch_m68k(dev); + case AST_IO_VGACRD1_TX_DP501_VBIOS: + ast_launch_m68k(ast); break; - case 0x0c: - ast_init_dvo(dev); + case AST_IO_VGACRD1_TX_FW_EMBEDDED_FW: + ast_init_dvo(ast); break; default: - if (ast->tx_chip_types & BIT(AST_TX_SIL164)) - ast_init_dvo(dev); + if (ast->tx_chip == AST_TX_SIL164) + ast_init_dvo(ast); else - ast_init_analog(dev); + ast_init_analog(ast); } } } @@ -485,17 +479,17 @@ static const struct drm_encoder_funcs ast_dp501_encoder_funcs = { static void ast_dp501_encoder_helper_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) { - struct drm_device *dev = encoder->dev; + struct ast_device *ast = to_ast_device(encoder->dev); - ast_set_dp501_video_output(dev, 1); + ast_set_dp501_video_output(ast, 1); } static void ast_dp501_encoder_helper_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { - struct drm_device *dev = encoder->dev; + struct ast_device *ast = to_ast_device(encoder->dev); - ast_set_dp501_video_output(dev, 0); + ast_set_dp501_video_output(ast, 0); } static const struct drm_encoder_helper_funcs ast_dp501_encoder_helper_funcs = { @@ -567,34 +561,22 @@ static const struct drm_connector_funcs ast_dp501_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector *connector) -{ - int ret; - - ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); - if (ret) - return ret; - - drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs); - - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - - return 0; -} +/* + * Output + */ int ast_dp501_output_init(struct ast_device *ast) { struct drm_device *dev = &ast->base; struct drm_crtc *crtc = &ast->crtc; - struct drm_encoder *encoder = &ast->output.dp501.encoder; - struct ast_connector *ast_connector = &ast->output.dp501.connector; - struct drm_connector *connector = &ast_connector->base; + struct drm_encoder *encoder; + struct ast_connector *ast_connector; + struct drm_connector *connector; int ret; + /* encoder */ + + encoder = &ast->output.dp501.encoder; ret = drm_encoder_init(dev, encoder, &ast_dp501_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret) @@ -603,9 +585,20 @@ int ast_dp501_output_init(struct ast_device *ast) encoder->possible_crtcs = drm_crtc_mask(crtc); - ret = ast_dp501_connector_init(dev, connector); + /* connector */ + + ast_connector = &ast->output.dp501.connector; + connector = &ast_connector->base; + ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs, + DRM_MODE_CONNECTOR_DisplayPort); if (ret) return ret; + drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs); + + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + ast_connector->physical_status = connector->status; ret = drm_connector_attach_encoder(connector, encoder); diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 3a908bb015fe..4afe4be072ef 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -26,12 +26,13 @@ * Authors: Dave Airlie <airlied@redhat.com> */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/of.h> #include <linux/pci.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_shmem.h> #include <drm/drm_gem_shmem_helper.h> @@ -64,7 +65,8 @@ static const struct drm_driver ast_driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, - DRM_GEM_SHMEM_DRIVER_OPS + DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; /* @@ -279,7 +281,7 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct drm_device *drm; bool need_post = false; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &ast_driver); + ret = aperture_remove_conflicting_pci_devices(pdev, ast_driver.name); if (ret) return ret; @@ -360,7 +362,7 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - drm_fbdev_shmem_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; } @@ -396,7 +398,7 @@ static int ast_drm_thaw(struct drm_device *dev) ast_enable_vga(ast->ioregs); ast_open_key(ast->ioregs); ast_enable_mmio(dev->dev, ast->ioregs); - ast_post_gpu(dev); + ast_post_gpu(ast); return drm_mode_config_helper_resume(dev); } diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 91fe07cf7b07..21ce3769bf0d 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -91,11 +91,6 @@ enum ast_tx_chip { AST_TX_ASTDP, }; -#define AST_TX_NONE_BIT BIT(AST_TX_NONE) -#define AST_TX_SIL164_BIT BIT(AST_TX_SIL164) -#define AST_TX_DP501_BIT BIT(AST_TX_DP501) -#define AST_TX_ASTDP_BIT BIT(AST_TX_ASTDP) - enum ast_config_mode { ast_use_p2a, ast_use_dt, @@ -187,10 +182,12 @@ struct ast_device { struct mutex modeset_lock; /* Protects access to modeset I/O registers in ioregs */ + enum ast_tx_chip tx_chip; + struct ast_plane primary_plane; struct ast_plane cursor_plane; struct drm_crtc crtc; - struct { + union { struct { struct drm_encoder encoder; struct ast_connector connector; @@ -211,7 +208,6 @@ struct ast_device { bool support_wide_screen; - unsigned long tx_chip_types; /* bitfield of enum ast_chip_type */ u8 *dp501_fw_addr; const struct firmware *dp501_fw; /* dp501 fw */ }; @@ -407,9 +403,6 @@ int ast_mode_config_init(struct ast_device *ast); #define AST_DP501_LINKRATE 0xf014 #define AST_DP501_EDID_DATA 0xf020 -#define AST_DP_POWER_ON true -#define AST_DP_POWER_OFF false - /* * ASTDP resoultion table: * EX: ASTDP_A_B_C: @@ -453,7 +446,7 @@ int ast_mode_config_init(struct ast_device *ast); int ast_mm_init(struct ast_device *ast); /* ast post */ -void ast_post_gpu(struct drm_device *dev); +void ast_post_gpu(struct ast_device *ast); u32 ast_mindwm(struct ast_device *ast, u32 r); void ast_moutdwm(struct ast_device *ast, u32 r, u32 v); void ast_patch_ahb_2500(void __iomem *regs); @@ -462,8 +455,8 @@ int ast_vga_output_init(struct ast_device *ast); int ast_sil164_output_init(struct ast_device *ast); /* ast dp501 */ -bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); -void ast_init_3rdtx(struct drm_device *dev); +bool ast_backup_fw(struct ast_device *ast, u8 *addr, u32 size); +void ast_init_3rdtx(struct ast_device *ast); int ast_dp501_output_init(struct ast_device *ast); /* aspeed DP */ diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index d836f2a4f9f3..bc37c65305d4 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -68,11 +68,33 @@ static void ast_detect_widescreen(struct ast_device *ast) static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) { + static const char * const info_str[] = { + "analog VGA", + "Sil164 TMDS transmitter", + "DP501 DisplayPort transmitter", + "ASPEED DisplayPort transmitter", + }; + struct drm_device *dev = &ast->base; - u8 jreg; + u8 jreg, vgacrd1; + + /* + * Several of the listed TX chips are not explicitly supported + * by the ast driver. If these exist in real-world devices, they + * are most likely reported as VGA or SIL164 outputs. We warn here + * to get bug reports for these devices. If none come in for some + * time, we can begin to fail device probing on these values. + */ + vgacrd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, AST_IO_VGACRD1_TX_TYPE_MASK); + drm_WARN(dev, vgacrd1 == AST_IO_VGACRD1_TX_ITE66121_VBIOS, + "ITE IT66121 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); + drm_WARN(dev, vgacrd1 == AST_IO_VGACRD1_TX_CH7003_VBIOS, + "Chrontel CH7003 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); + drm_WARN(dev, vgacrd1 == AST_IO_VGACRD1_TX_ANX9807_VBIOS, + "Analogix ANX9807 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); /* Check 3rd Tx option (digital output afaik) */ - ast->tx_chip_types |= AST_TX_NONE_BIT; + ast->tx_chip = AST_TX_NONE; /* * VGACRA3 Enhanced Color Mode Register, check if DVO is already @@ -85,7 +107,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) if (!need_post) { jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xff); if (jreg & 0x80) - ast->tx_chip_types = AST_TX_SIL164_BIT; + ast->tx_chip = AST_TX_SIL164; } if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast)) { @@ -94,49 +116,42 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) * the SOC scratch register #1 bits 11:8 (interestingly marked * as "reserved" in the spec) */ - jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, + AST_IO_VGACRD1_TX_TYPE_MASK); switch (jreg) { - case 0x04: - ast->tx_chip_types = AST_TX_SIL164_BIT; + case AST_IO_VGACRD1_TX_SIL164_VBIOS: + ast->tx_chip = AST_TX_SIL164; break; - case 0x08: + case AST_IO_VGACRD1_TX_DP501_VBIOS: ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL); if (ast->dp501_fw_addr) { /* backup firmware */ - if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) { + if (ast_backup_fw(ast, ast->dp501_fw_addr, 32*1024)) { drmm_kfree(dev, ast->dp501_fw_addr); ast->dp501_fw_addr = NULL; } } fallthrough; - case 0x0c: - ast->tx_chip_types = AST_TX_DP501_BIT; + case AST_IO_VGACRD1_TX_FW_EMBEDDED_FW: + ast->tx_chip = AST_TX_DP501; } } else if (IS_AST_GEN7(ast)) { - if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, TX_TYPE_MASK) == - ASTDP_DPMCU_TX) { + if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, AST_IO_VGACRD1_TX_TYPE_MASK) == + AST_IO_VGACRD1_TX_ASTDP) { int ret = ast_dp_launch(ast); if (!ret) - ast->tx_chip_types = AST_TX_ASTDP_BIT; + ast->tx_chip = AST_TX_ASTDP; } } - /* Print stuff for diagnostic purposes */ - if (ast->tx_chip_types & AST_TX_NONE_BIT) - drm_info(dev, "Using analog VGA\n"); - if (ast->tx_chip_types & AST_TX_SIL164_BIT) - drm_info(dev, "Using Sil164 TMDS transmitter\n"); - if (ast->tx_chip_types & AST_TX_DP501_BIT) - drm_info(dev, "Using DP501 DisplayPort transmitter\n"); - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) - drm_info(dev, "Using ASPEED DisplayPort transmitter\n"); + drm_info(dev, "Using %s\n", info_str[ast->tx_chip]); } -static int ast_get_dram_info(struct drm_device *dev) +static int ast_get_dram_info(struct ast_device *ast) { + struct drm_device *dev = &ast->base; struct device_node *np = dev->dev->of_node; - struct ast_device *ast = to_ast_device(dev); uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap; uint32_t denum, num, div, ref_pll, dsel; @@ -278,7 +293,7 @@ struct drm_device *ast_device_create(struct pci_dev *pdev, ast_detect_widescreen(ast); ast_detect_tx_chip(ast, need_post); - ret = ast_get_dram_info(dev); + ret = ast_get_dram_info(ast); if (ret) return ERR_PTR(ret); @@ -286,7 +301,7 @@ struct drm_device *ast_device_create(struct pci_dev *pdev, ast->mclk, ast->dram_type, ast->dram_bus_width); if (need_post) - ast_post_gpu(dev); + ast_post_gpu(ast); ret = ast_mm_init(ast); if (ret) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index ed496fb32bf3..9d5321c81e68 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1287,9 +1287,9 @@ static const struct drm_crtc_funcs ast_crtc_funcs = { .atomic_destroy_state = ast_crtc_atomic_destroy_state, }; -static int ast_crtc_init(struct drm_device *dev) +static int ast_crtc_init(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; struct drm_crtc *crtc = &ast->crtc; int ret; @@ -1396,28 +1396,26 @@ int ast_mode_config_init(struct ast_device *ast) if (ret) return ret; - ast_crtc_init(dev); + ret = ast_crtc_init(ast); + if (ret) + return ret; - if (ast->tx_chip_types & AST_TX_NONE_BIT) { + switch (ast->tx_chip) { + case AST_TX_NONE: ret = ast_vga_output_init(ast); - if (ret) - return ret; - } - if (ast->tx_chip_types & AST_TX_SIL164_BIT) { + break; + case AST_TX_SIL164: ret = ast_sil164_output_init(ast); - if (ret) - return ret; - } - if (ast->tx_chip_types & AST_TX_DP501_BIT) { + break; + case AST_TX_DP501: ret = ast_dp501_output_init(ast); - if (ret) - return ret; - } - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { + break; + case AST_TX_ASTDP: ret = ast_astdp_output_init(ast); - if (ret) - return ret; + break; } + if (ret) + return ret; drm_mode_config_reset(dev); diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 65755798ab94..364030f97571 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -34,16 +34,14 @@ #include "ast_dram_tables.h" #include "ast_drv.h" -static void ast_post_chip_2300(struct drm_device *dev); -static void ast_post_chip_2500(struct drm_device *dev); +static void ast_post_chip_2300(struct ast_device *ast); +static void ast_post_chip_2500(struct ast_device *ast); static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff }; static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff }; -static void -ast_set_def_ext_reg(struct drm_device *dev) +static void ast_set_def_ext_reg(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u8 i, index, reg; const u8 *ext_reg_info; @@ -252,9 +250,8 @@ cbr_start: -static void ast_init_dram_reg(struct drm_device *dev) +static void ast_init_dram_reg(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u8 j; u32 data, temp, i; const struct ast_dramstruct *dram_reg_info; @@ -343,26 +340,24 @@ static void ast_init_dram_reg(struct drm_device *dev) } while ((j & 0x40) == 0); } -void ast_post_gpu(struct drm_device *dev) +void ast_post_gpu(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); - - ast_set_def_ext_reg(dev); + ast_set_def_ext_reg(ast); if (IS_AST_GEN7(ast)) { - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) + if (ast->tx_chip == AST_TX_ASTDP) ast_dp_launch(ast); } else if (ast->config_mode == ast_use_p2a) { if (IS_AST_GEN6(ast)) - ast_post_chip_2500(dev); + ast_post_chip_2500(ast); else if (IS_AST_GEN5(ast) || IS_AST_GEN4(ast)) - ast_post_chip_2300(dev); + ast_post_chip_2300(ast); else - ast_init_dram_reg(dev); + ast_init_dram_reg(ast); - ast_init_3rdtx(dev); + ast_init_3rdtx(ast); } else { - if (ast->tx_chip_types & AST_TX_SIL164_BIT) + if (ast->tx_chip == AST_TX_SIL164) ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); /* Enable DVO */ } } @@ -1569,9 +1564,8 @@ ddr2_init_start: } -static void ast_post_chip_2300(struct drm_device *dev) +static void ast_post_chip_2300(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); struct ast2300_dram_param param; u32 temp; u8 reg; @@ -2038,9 +2032,9 @@ void ast_patch_ahb_2500(void __iomem *regs) __ast_moutdwm(regs, 0x1e6e207c, 0x08000000); /* clear fast reset */ } -void ast_post_chip_2500(struct drm_device *dev) +void ast_post_chip_2500(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; u32 temp; u8 reg; diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h index 040961cc1a19..2aadf07d135a 100644 --- a/drivers/gpu/drm/ast/ast_reg.h +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -37,28 +37,29 @@ #define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ #define AST_IO_VGACRCB_HWC_ENABLED BIT(1) -#define AST_IO_VGACRD1_MCU_FW_EXECUTING BIT(5) +#define AST_IO_VGACRD1_MCU_FW_EXECUTING BIT(5) +/* Display Transmitter Type */ +#define AST_IO_VGACRD1_TX_TYPE_MASK GENMASK(3, 1) +#define AST_IO_VGACRD1_NO_TX 0x00 +#define AST_IO_VGACRD1_TX_ITE66121_VBIOS 0x02 +#define AST_IO_VGACRD1_TX_SIL164_VBIOS 0x04 +#define AST_IO_VGACRD1_TX_CH7003_VBIOS 0x06 +#define AST_IO_VGACRD1_TX_DP501_VBIOS 0x08 +#define AST_IO_VGACRD1_TX_ANX9807_VBIOS 0x0a +#define AST_IO_VGACRD1_TX_FW_EMBEDDED_FW 0x0c /* special case of DP501 */ +#define AST_IO_VGACRD1_TX_ASTDP 0x0e + #define AST_IO_VGACRD7_EDID_VALID_FLAG BIT(0) #define AST_IO_VGACRDC_LINK_SUCCESS BIT(0) #define AST_IO_VGACRDF_HPD BIT(0) +#define AST_IO_VGACRDF_DP_VIDEO_ENABLE BIT(4) /* mirrors AST_IO_VGACRE3_DP_VIDEO_ENABLE */ +#define AST_IO_VGACRE3_DP_VIDEO_ENABLE BIT(0) +#define AST_IO_VGACRE3_DP_PHY_SLEEP BIT(4) #define AST_IO_VGACRE5_EDID_READ_DONE BIT(0) #define AST_IO_VGAIR1_R (0x5A) #define AST_IO_VGAIR1_VREFRESH BIT(3) -/* - * Display Transmitter Type - */ - -#define TX_TYPE_MASK GENMASK(3, 1) -#define NO_TX (0 << 1) -#define ITE66121_VBIOS_TX (1 << 1) -#define SI164_VBIOS_TX (2 << 1) -#define CH7003_VBIOS_TX (3 << 1) -#define DP501_VBIOS_TX (4 << 1) -#define ANX9807_VBIOS_TX (5 << 1) -#define TX_FW_EMBEDDED_FW_TX (6 << 1) -#define ASTDP_DPMCU_TX (7 << 1) #define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) //#define AST_VRAM_INIT_BY_BMC BIT(7) @@ -68,18 +69,6 @@ * AST DisplayPort */ -/* Define for Soc scratched reg used on ASTDP */ -#define AST_DP_PHY_SLEEP BIT(4) -#define AST_DP_VIDEO_ENABLE BIT(0) - -/* - * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE - * Precondition: A. ~AST_DP_PHY_SLEEP && - * B. DP_HPD && - * C. DP_LINK_SUCCESS - */ -#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4) - /* * ASTDP setmode registers: * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp) diff --git a/drivers/gpu/drm/ast/ast_sil164.c b/drivers/gpu/drm/ast/ast_sil164.c index c231389936bd..be01254dd48a 100644 --- a/drivers/gpu/drm/ast/ast_sil164.c +++ b/drivers/gpu/drm/ast/ast_sil164.c @@ -73,52 +73,49 @@ static const struct drm_connector_funcs ast_sil164_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static int ast_sil164_connector_init(struct drm_device *dev, struct drm_connector *connector) +/* + * Output + */ + +int ast_sil164_output_init(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; + struct drm_crtc *crtc = &ast->crtc; struct i2c_adapter *ddc; + struct drm_encoder *encoder; + struct ast_connector *ast_connector; + struct drm_connector *connector; int ret; + /* DDC */ + ddc = ast_ddc_create(ast); - if (IS_ERR(ddc)) { - ret = PTR_ERR(ddc); - drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret); + if (IS_ERR(ddc)) + return PTR_ERR(ddc); + + /* encoder */ + + encoder = &ast->output.sil164.encoder; + ret = drm_encoder_init(dev, encoder, &ast_sil164_encoder_funcs, + DRM_MODE_ENCODER_TMDS, NULL); + if (ret) return ret; - } + encoder->possible_crtcs = drm_crtc_mask(crtc); + + /* connector */ + ast_connector = &ast->output.sil164.connector; + connector = &ast_connector->base; ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs, DRM_MODE_CONNECTOR_DVII, ddc); if (ret) return ret; - drm_connector_helper_add(connector, &ast_sil164_connector_helper_funcs); connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - return 0; -} - -int ast_sil164_output_init(struct ast_device *ast) -{ - struct drm_device *dev = &ast->base; - struct drm_crtc *crtc = &ast->crtc; - struct drm_encoder *encoder = &ast->output.sil164.encoder; - struct ast_connector *ast_connector = &ast->output.sil164.connector; - struct drm_connector *connector = &ast_connector->base; - int ret; - - ret = drm_encoder_init(dev, encoder, &ast_sil164_encoder_funcs, - DRM_MODE_ENCODER_TMDS, NULL); - if (ret) - return ret; - encoder->possible_crtcs = drm_crtc_mask(crtc); - - ret = ast_sil164_connector_init(dev, connector); - if (ret) - return ret; ast_connector->physical_status = connector->status; ret = drm_connector_attach_encoder(connector, encoder); diff --git a/drivers/gpu/drm/ast/ast_vga.c b/drivers/gpu/drm/ast/ast_vga.c index dd389a0a8f4a..abe0fff8485c 100644 --- a/drivers/gpu/drm/ast/ast_vga.c +++ b/drivers/gpu/drm/ast/ast_vga.c @@ -73,52 +73,49 @@ static const struct drm_connector_funcs ast_vga_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static int ast_vga_connector_init(struct drm_device *dev, struct drm_connector *connector) +/* + * Output + */ + +int ast_vga_output_init(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; + struct drm_crtc *crtc = &ast->crtc; struct i2c_adapter *ddc; + struct drm_encoder *encoder; + struct ast_connector *ast_connector; + struct drm_connector *connector; int ret; + /* DDC */ + ddc = ast_ddc_create(ast); - if (IS_ERR(ddc)) { - ret = PTR_ERR(ddc); - drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret); + if (IS_ERR(ddc)) + return PTR_ERR(ddc); + + /* encoder */ + + encoder = &ast->output.vga.encoder; + ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs, + DRM_MODE_ENCODER_DAC, NULL); + if (ret) return ret; - } + encoder->possible_crtcs = drm_crtc_mask(crtc); + + /* connector */ + ast_connector = &ast->output.vga.connector; + connector = &ast_connector->base; ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA, ddc); if (ret) return ret; - drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs); connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - return 0; -} - -int ast_vga_output_init(struct ast_device *ast) -{ - struct drm_device *dev = &ast->base; - struct drm_crtc *crtc = &ast->crtc; - struct drm_encoder *encoder = &ast->output.vga.encoder; - struct ast_connector *ast_connector = &ast->output.vga.connector; - struct drm_connector *connector = &ast_connector->base; - int ret; - - ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs, - DRM_MODE_ENCODER_DAC, NULL); - if (ret) - return ret; - encoder->possible_crtcs = drm_crtc_mask(crtc); - - ret = ast_vga_connector_init(dev, connector); - if (ret) - return ret; ast_connector->physical_status = connector->status; ret = drm_connector_attach_encoder(connector, encoder); |