Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR MIT
0002 
0003 /*
0004  *  Xen para-virtual DRM device
0005  *
0006  * Copyright (C) 2016-2018 EPAM Systems Inc.
0007  *
0008  * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
0009  */
0010 
0011 #include <linux/device.h>
0012 
0013 #include <drm/drm_print.h>
0014 
0015 #include <xen/interface/io/displif.h>
0016 #include <xen/xenbus.h>
0017 
0018 #include "xen_drm_front.h"
0019 #include "xen_drm_front_cfg.h"
0020 
0021 static int cfg_connector(struct xen_drm_front_info *front_info,
0022              struct xen_drm_front_cfg_connector *connector,
0023              const char *path, int index)
0024 {
0025     char *connector_path;
0026 
0027     connector_path = devm_kasprintf(&front_info->xb_dev->dev,
0028                     GFP_KERNEL, "%s/%d", path, index);
0029     if (!connector_path)
0030         return -ENOMEM;
0031 
0032     if (xenbus_scanf(XBT_NIL, connector_path, XENDISPL_FIELD_RESOLUTION,
0033              "%d" XENDISPL_RESOLUTION_SEPARATOR "%d",
0034              &connector->width, &connector->height) < 0) {
0035         /* either no entry configured or wrong resolution set */
0036         connector->width = 0;
0037         connector->height = 0;
0038         return -EINVAL;
0039     }
0040 
0041     connector->xenstore_path = connector_path;
0042 
0043     DRM_INFO("Connector %s: resolution %dx%d\n",
0044          connector_path, connector->width, connector->height);
0045     return 0;
0046 }
0047 
0048 int xen_drm_front_cfg_card(struct xen_drm_front_info *front_info,
0049                struct xen_drm_front_cfg *cfg)
0050 {
0051     struct xenbus_device *xb_dev = front_info->xb_dev;
0052     int ret, i;
0053 
0054     if (xenbus_read_unsigned(front_info->xb_dev->nodename,
0055                  XENDISPL_FIELD_BE_ALLOC, 0)) {
0056         DRM_INFO("Backend can provide display buffers\n");
0057         cfg->be_alloc = true;
0058     }
0059 
0060     cfg->num_connectors = 0;
0061     for (i = 0; i < ARRAY_SIZE(cfg->connectors); i++) {
0062         ret = cfg_connector(front_info, &cfg->connectors[i],
0063                     xb_dev->nodename, i);
0064         if (ret < 0)
0065             break;
0066         cfg->num_connectors++;
0067     }
0068 
0069     if (!cfg->num_connectors) {
0070         DRM_ERROR("No connector(s) configured at %s\n",
0071               xb_dev->nodename);
0072         return -ENODEV;
0073     }
0074 
0075     return 0;
0076 }
0077