brintos

brintos / linux-shallow public Read only

0
0
Text · 3.4 KiB · dd389a0 Raw
130 lines · c
1// SPDX-License-Identifier: MIT2 3#include <drm/drm_atomic_state_helper.h>4#include <drm/drm_edid.h>5#include <drm/drm_modeset_helper_vtables.h>6#include <drm/drm_print.h>7#include <drm/drm_probe_helper.h>8 9#include "ast_ddc.h"10#include "ast_drv.h"11 12/*13 * Encoder14 */15 16static const struct drm_encoder_funcs ast_vga_encoder_funcs = {17	.destroy = drm_encoder_cleanup,18};19 20/*21 * Connector22 */23 24static int ast_vga_connector_helper_get_modes(struct drm_connector *connector)25{26	struct ast_connector *ast_connector = to_ast_connector(connector);27	int count;28 29	if (ast_connector->physical_status == connector_status_connected) {30		count = drm_connector_helper_get_modes(connector);31	} else {32		drm_edid_connector_update(connector, NULL);33 34		/*35		 * There's no EDID data without a connected monitor. Set BMC-36		 * compatible modes in this case. The XGA default resolution37		 * should work well for all BMCs.38		 */39		count = drm_add_modes_noedid(connector, 4096, 4096);40		if (count)41			drm_set_preferred_mode(connector, 1024, 768);42	}43 44	return count;45}46 47static int ast_vga_connector_helper_detect_ctx(struct drm_connector *connector,48					       struct drm_modeset_acquire_ctx *ctx,49					       bool force)50{51	struct ast_connector *ast_connector = to_ast_connector(connector);52	enum drm_connector_status status;53 54	status = drm_connector_helper_detect_from_ddc(connector, ctx, force);55 56	if (status != ast_connector->physical_status)57		++connector->epoch_counter;58	ast_connector->physical_status = status;59 60	return connector_status_connected;61}62 63static const struct drm_connector_helper_funcs ast_vga_connector_helper_funcs = {64	.get_modes = ast_vga_connector_helper_get_modes,65	.detect_ctx = ast_vga_connector_helper_detect_ctx,66};67 68static const struct drm_connector_funcs ast_vga_connector_funcs = {69	.reset = drm_atomic_helper_connector_reset,70	.fill_modes = drm_helper_probe_single_connector_modes,71	.destroy = drm_connector_cleanup,72	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,73	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,74};75 76static int ast_vga_connector_init(struct drm_device *dev, struct drm_connector *connector)77{78	struct ast_device *ast = to_ast_device(dev);79	struct i2c_adapter *ddc;80	int ret;81 82	ddc = ast_ddc_create(ast);83	if (IS_ERR(ddc)) {84		ret = PTR_ERR(ddc);85		drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret);86		return ret;87	}88 89	ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs,90					  DRM_MODE_CONNECTOR_VGA, ddc);91	if (ret)92		return ret;93 94	drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs);95 96	connector->interlace_allowed = 0;97	connector->doublescan_allowed = 0;98 99	connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;100 101	return 0;102}103 104int ast_vga_output_init(struct ast_device *ast)105{106	struct drm_device *dev = &ast->base;107	struct drm_crtc *crtc = &ast->crtc;108	struct drm_encoder *encoder = &ast->output.vga.encoder;109	struct ast_connector *ast_connector = &ast->output.vga.connector;110	struct drm_connector *connector = &ast_connector->base;111	int ret;112 113	ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs,114			       DRM_MODE_ENCODER_DAC, NULL);115	if (ret)116		return ret;117	encoder->possible_crtcs = drm_crtc_mask(crtc);118 119	ret = ast_vga_connector_init(dev, connector);120	if (ret)121		return ret;122	ast_connector->physical_status = connector->status;123 124	ret = drm_connector_attach_encoder(connector, encoder);125	if (ret)126		return ret;127 128	return 0;129}130