78 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR MIT2 3/*4 * Xen para-virtual DRM device5 *6 * Copyright (C) 2016-2018 EPAM Systems Inc.7 *8 * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>9 */10 11#include <linux/device.h>12 13#include <drm/drm_print.h>14 15#include <xen/interface/io/displif.h>16#include <xen/xenbus.h>17 18#include "xen_drm_front.h"19#include "xen_drm_front_cfg.h"20 21static int cfg_connector(struct xen_drm_front_info *front_info,22 struct xen_drm_front_cfg_connector *connector,23 const char *path, int index)24{25 char *connector_path;26 27 connector_path = devm_kasprintf(&front_info->xb_dev->dev,28 GFP_KERNEL, "%s/%d", path, index);29 if (!connector_path)30 return -ENOMEM;31 32 if (xenbus_scanf(XBT_NIL, connector_path, XENDISPL_FIELD_RESOLUTION,33 "%d" XENDISPL_RESOLUTION_SEPARATOR "%d",34 &connector->width, &connector->height) < 0) {35 /* either no entry configured or wrong resolution set */36 connector->width = 0;37 connector->height = 0;38 return -EINVAL;39 }40 41 connector->xenstore_path = connector_path;42 43 DRM_INFO("Connector %s: resolution %dx%d\n",44 connector_path, connector->width, connector->height);45 return 0;46}47 48int xen_drm_front_cfg_card(struct xen_drm_front_info *front_info,49 struct xen_drm_front_cfg *cfg)50{51 struct xenbus_device *xb_dev = front_info->xb_dev;52 int ret, i;53 54 if (xenbus_read_unsigned(front_info->xb_dev->nodename,55 XENDISPL_FIELD_BE_ALLOC, 0)) {56 DRM_INFO("Backend can provide display buffers\n");57 cfg->be_alloc = true;58 }59 60 cfg->num_connectors = 0;61 for (i = 0; i < ARRAY_SIZE(cfg->connectors); i++) {62 ret = cfg_connector(front_info, &cfg->connectors[i],63 xb_dev->nodename, i);64 if (ret < 0)65 break;66 cfg->num_connectors++;67 }68 69 if (!cfg->num_connectors) {70 DRM_ERROR("No connector(s) configured at %s\n",71 xb_dev->nodename);72 return -ENODEV;73 }74 75 return 0;76}77 78