1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * ARC PGU DRM driver. 4 * 5 * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com) 6 */ 7 8#include <drm/drm_atomic_helper.h> 9#include <drm/drm_device.h> 10#include <drm/drm_probe_helper.h> 11 12#include "arcpgu.h" 13 14#define XRES_DEF 640 15#define YRES_DEF 480 16 17#define XRES_MAX 8192 18#define YRES_MAX 8192 19 20 21struct arcpgu_drm_connector { 22 struct drm_connector connector; 23}; 24 25static int arcpgu_drm_connector_get_modes(struct drm_connector *connector) 26{ 27 int count; 28 29 count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); 30 drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF); 31 return count; 32} 33 34static void arcpgu_drm_connector_destroy(struct drm_connector *connector) 35{ 36 drm_connector_unregister(connector); 37 drm_connector_cleanup(connector); 38} 39 40static const struct drm_connector_helper_funcs 41arcpgu_drm_connector_helper_funcs = { 42 .get_modes = arcpgu_drm_connector_get_modes, 43}; 44 45static const struct drm_connector_funcs arcpgu_drm_connector_funcs = { 46 .reset = drm_atomic_helper_connector_reset, 47 .fill_modes = drm_helper_probe_single_connector_modes, 48 .destroy = arcpgu_drm_connector_destroy, 49 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 50 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 51}; 52 53static struct drm_encoder_funcs arcpgu_drm_encoder_funcs = { 54 .destroy = drm_encoder_cleanup, 55}; 56 57int arcpgu_drm_sim_init(struct drm_device *drm, struct device_node *np) 58{ 59 struct arcpgu_drm_connector *arcpgu_connector; 60 struct drm_encoder *encoder; 61 struct drm_connector *connector; 62 int ret; 63 64 encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL); 65 if (encoder == NULL) 66 return -ENOMEM; 67 68 encoder->possible_crtcs = 1; 69 encoder->possible_clones = 0; 70 71 ret = drm_encoder_init(drm, encoder, &arcpgu_drm_encoder_funcs, 72 DRM_MODE_ENCODER_VIRTUAL, NULL); 73 if (ret) 74 return ret; 75 76 arcpgu_connector = devm_kzalloc(drm->dev, sizeof(*arcpgu_connector), 77 GFP_KERNEL); 78 if (!arcpgu_connector) { 79 ret = -ENOMEM; 80 goto error_encoder_cleanup; 81 } 82 83 connector = &arcpgu_connector->connector; 84 drm_connector_helper_add(connector, &arcpgu_drm_connector_helper_funcs); 85 86 ret = drm_connector_init(drm, connector, &arcpgu_drm_connector_funcs, 87 DRM_MODE_CONNECTOR_VIRTUAL); 88 if (ret < 0) { 89 dev_err(drm->dev, "failed to initialize drm connector\n"); 90 goto error_encoder_cleanup; 91 } 92 93 ret = drm_connector_attach_encoder(connector, encoder); 94 if (ret < 0) { 95 dev_err(drm->dev, "could not attach connector to encoder\n"); 96 drm_connector_unregister(connector); 97 goto error_connector_cleanup; 98 } 99 100 return 0; 101 102error_connector_cleanup: 103 drm_connector_cleanup(connector); 104 105error_encoder_cleanup: 106 drm_encoder_cleanup(encoder); 107 return ret; 108} 109