diff options
Diffstat (limited to 'drivers/gpu/drm/ast/ast_mode.c')
-rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 122 |
1 files changed, 101 insertions, 21 deletions
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index b3c670af6ef2..32f04ec6c386 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -342,7 +342,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0; u16 temp, precache = 0; - if ((ast->chip == AST2500 || ast->chip == AST2600) && + if ((IS_AST_GEN6(ast) || IS_AST_GEN7(ast)) && (vbios_mode->enh_table->flags & AST2500PreCatchCRT)) precache = 40; @@ -384,7 +384,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD); // Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels); - if ((ast->chip == AST2600) && (mode->crtc_vdisplay == 1080)) + if (IS_AST_GEN7(ast) && (mode->crtc_vdisplay == 1080)) ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x02); else ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x00); @@ -466,7 +466,7 @@ static void ast_set_dclk_reg(struct ast_device *ast, { const struct ast_vbios_dclk_info *clk_info; - if ((ast->chip == AST2500) || (ast->chip == AST2600)) + if (IS_AST_GEN6(ast) || IS_AST_GEN7(ast)) clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index]; else clk_info = &dclk_table[vbios_mode->enh_table->dclk_index]; @@ -510,17 +510,13 @@ static void ast_set_color_reg(struct ast_device *ast, static void ast_set_crtthd_reg(struct ast_device *ast) { /* Set Threshold */ - if (ast->chip == AST2600) { + if (IS_AST_GEN7(ast)) { ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0); - } else if (ast->chip == AST2300 || ast->chip == AST2400 || - ast->chip == AST2500) { + } else if (IS_AST_GEN6(ast) || IS_AST_GEN5(ast) || IS_AST_GEN4(ast)) { ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60); - } else if (ast->chip == AST2100 || - ast->chip == AST1100 || - ast->chip == AST2200 || - ast->chip == AST2150) { + } else if (IS_AST_GEN3(ast) || IS_AST_GEN2(ast)) { ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f); } else { @@ -1082,9 +1078,10 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode if ((mode->hdisplay == 1152) && (mode->vdisplay == 864)) return MODE_OK; - if ((ast->chip == AST2100) || (ast->chip == AST2200) || - (ast->chip == AST2300) || (ast->chip == AST2400) || - (ast->chip == AST2500) || (ast->chip == AST2600)) { + if ((ast->chip == AST2100) || // GEN2, but not AST1100 (?) + (ast->chip == AST2200) || // GEN3, but not AST2150 (?) + IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || + IS_AST_GEN6(ast) || IS_AST_GEN7(ast)) { if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080)) return MODE_OK; @@ -1585,8 +1582,20 @@ err_drm_connector_update_edid_property: return 0; } +static int ast_dp501_connector_helper_detect_ctx(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, + bool force) +{ + struct ast_device *ast = to_ast_device(connector->dev); + + if (ast_dp501_is_connected(ast)) + return connector_status_connected; + return connector_status_disconnected; +} + static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs = { .get_modes = ast_dp501_connector_helper_get_modes, + .detect_ctx = ast_dp501_connector_helper_detect_ctx, }; static const struct drm_connector_funcs ast_dp501_connector_funcs = { @@ -1611,7 +1620,7 @@ static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - connector->polled = DRM_CONNECTOR_POLL_CONNECT; + connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; return 0; } @@ -1683,8 +1692,20 @@ err_drm_connector_update_edid_property: return 0; } +static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, + bool force) +{ + struct ast_device *ast = to_ast_device(connector->dev); + + if (ast_astdp_is_connected(ast)) + return connector_status_connected; + return connector_status_disconnected; +} + static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = { .get_modes = ast_astdp_connector_helper_get_modes, + .detect_ctx = ast_astdp_connector_helper_detect_ctx, }; static const struct drm_connector_funcs ast_astdp_connector_funcs = { @@ -1709,7 +1730,7 @@ static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - connector->polled = DRM_CONNECTOR_POLL_CONNECT; + connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; return 0; } @@ -1739,6 +1760,60 @@ static int ast_astdp_output_init(struct ast_device *ast) } /* + * BMC virtual Connector + */ + +static const struct drm_encoder_funcs ast_bmc_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector) +{ + return drm_add_modes_noedid(connector, 4096, 4096); +} + +static const struct drm_connector_helper_funcs ast_bmc_connector_helper_funcs = { + .get_modes = ast_bmc_connector_helper_get_modes, +}; + +static const struct drm_connector_funcs ast_bmc_connector_funcs = { + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int ast_bmc_output_init(struct ast_device *ast) +{ + struct drm_device *dev = &ast->base; + struct drm_crtc *crtc = &ast->crtc; + struct drm_encoder *encoder = &ast->output.bmc.encoder; + struct drm_connector *connector = &ast->output.bmc.connector; + int ret; + + ret = drm_encoder_init(dev, encoder, + &ast_bmc_encoder_funcs, + DRM_MODE_ENCODER_VIRTUAL, "ast_bmc"); + if (ret) + return ret; + encoder->possible_crtcs = drm_crtc_mask(crtc); + + ret = drm_connector_init(dev, connector, &ast_bmc_connector_funcs, + DRM_MODE_CONNECTOR_VIRTUAL); + if (ret) + return ret; + + drm_connector_helper_add(connector, &ast_bmc_connector_helper_funcs); + + ret = drm_connector_attach_encoder(connector, encoder); + if (ret) + return ret; + + return 0; +} + +/* * Mode config */ @@ -1800,12 +1875,12 @@ int ast_mode_config_init(struct ast_device *ast) dev->mode_config.min_height = 0; dev->mode_config.preferred_depth = 24; - if (ast->chip == AST2100 || - ast->chip == AST2200 || - ast->chip == AST2300 || - ast->chip == AST2400 || - ast->chip == AST2500 || - ast->chip == AST2600) { + if (ast->chip == AST2100 || // GEN2, but not AST1100 (?) + ast->chip == AST2200 || // GEN3, but not AST2150 (?) + IS_AST_GEN7(ast) || + IS_AST_GEN6(ast) || + IS_AST_GEN5(ast) || + IS_AST_GEN4(ast)) { dev->mode_config.max_width = 1920; dev->mode_config.max_height = 2048; } else { @@ -1845,8 +1920,13 @@ int ast_mode_config_init(struct ast_device *ast) if (ret) return ret; } + ret = ast_bmc_output_init(ast); + if (ret) + return ret; drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); + return 0; } |