Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/armada/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 6 kB image not shown  

Quelle  armada_drv.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2012 Russell King
 */


#include <linux/aperture.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>

#include <drm/clients/drm_client_setup.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_managed.h>
#include <drm/drm_prime.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_of.h>
#include <drm/drm_vblank.h>

#include "armada_crtc.h"
#include "armada_drm.h"
#include "armada_gem.h"
#include "armada_fb.h"
#include "armada_hw.h"
#include <drm/armada_drm.h>
#include "armada_ioctlP.h"

static const struct drm_ioctl_desc armada_ioctls[] = {
 DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl,0),
 DRM_IOCTL_DEF_DRV(ARMADA_GEM_MMAP, armada_gem_mmap_ioctl, 0),
 DRM_IOCTL_DEF_DRV(ARMADA_GEM_PWRITE, armada_gem_pwrite_ioctl, 0),
};

DEFINE_DRM_GEM_FOPS(armada_drm_fops);

static const struct drm_driver armada_drm_driver = {
 .gem_prime_import = armada_gem_prime_import,
 .dumb_create  = armada_gem_dumb_create,
 ARMADA_FBDEV_DRIVER_OPS,
 .major   = 1,
 .minor   = 0,
 .name   = "armada-drm",
 .desc   = "Armada SoC DRM",
 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 .ioctls   = armada_ioctls,
 .num_ioctls = ARRAY_SIZE(armada_ioctls),
 .fops   = &armada_drm_fops,
};

static const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
 .fb_create  = armada_fb_create,
 .atomic_check  = drm_atomic_helper_check,
 .atomic_commit  = drm_atomic_helper_commit,
};

static int armada_drm_bind(struct device *dev)
{
 struct armada_private *priv;
 struct resource *mem = NULL;
 int ret, n;

 for (n = 0; ; n++) {
  struct resource *r = platform_get_resource(to_platform_device(dev),
          IORESOURCE_MEM, n);
  if (!r)
   break;

  /* Resources above 64K are graphics memory */
  if (resource_size(r) > SZ_64K)
   mem = r;
  else
   return -EINVAL;
 }

 if (!mem)
  return -ENXIO;

 if (!devm_request_mem_region(dev, mem->start, resource_size(mem),
         "armada-drm"))
  return -EBUSY;

 priv = devm_drm_dev_alloc(dev, &armada_drm_driver,
      struct armada_private, drm);
 if (IS_ERR(priv)) {
  dev_err(dev, "[" DRM_NAME ":%s] devm_drm_dev_alloc failed: %li\n",
   __func__, PTR_ERR(priv));
  return PTR_ERR(priv);
 }

 /* Remove early framebuffers */
 ret = aperture_remove_all_conflicting_devices(armada_drm_driver.name);
 if (ret) {
  dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n",
   __func__, ret);
  return ret;
 }

 dev_set_drvdata(dev, &priv->drm);

 /* Mode setting support */
 drm_mode_config_init(&priv->drm);
 priv->drm.mode_config.min_width = 320;
 priv->drm.mode_config.min_height = 200;

 /*
 * With vscale enabled, the maximum width is 1920 due to the
 * 1920 by 3 lines RAM
 */

 priv->drm.mode_config.max_width = 1920;
 priv->drm.mode_config.max_height = 2048;

 priv->drm.mode_config.preferred_depth = 24;
 priv->drm.mode_config.funcs = &armada_drm_mode_config_funcs;
 drm_mm_init(&priv->linear, mem->start, resource_size(mem));
 mutex_init(&priv->linear_lock);

 ret = component_bind_all(dev, &priv->drm);
 if (ret)
  goto err_kms;

 ret = drm_vblank_init(&priv->drm, priv->drm.mode_config.num_crtc);
 if (ret)
  goto err_comp;

 drm_mode_config_reset(&priv->drm);

 drm_kms_helper_poll_init(&priv->drm);

 ret = drm_dev_register(&priv->drm, 0);
 if (ret)
  goto err_poll;

#ifdef CONFIG_DEBUG_FS
 armada_drm_debugfs_init(priv->drm.primary);
#endif

 drm_client_setup(&priv->drm, NULL);

 return 0;

 err_poll:
 drm_kms_helper_poll_fini(&priv->drm);
 err_comp:
 component_unbind_all(dev, &priv->drm);
 err_kms:
 drm_mode_config_cleanup(&priv->drm);
 drm_mm_takedown(&priv->linear);
 dev_set_drvdata(dev, NULL);
 return ret;
}

static void armada_drm_unbind(struct device *dev)
{
 struct drm_device *drm = dev_get_drvdata(dev);
 struct armada_private *priv = drm_to_armada_dev(drm);

 drm_kms_helper_poll_fini(&priv->drm);

 drm_dev_unregister(&priv->drm);

 drm_atomic_helper_shutdown(&priv->drm);

 component_unbind_all(dev, &priv->drm);

 drm_mode_config_cleanup(&priv->drm);
 drm_mm_takedown(&priv->linear);
 dev_set_drvdata(dev, NULL);
}

static void armada_add_endpoints(struct device *dev,
 struct component_match **match, struct device_node *dev_node)
{
 struct device_node *ep, *remote;

 for_each_endpoint_of_node(dev_node, ep) {
  remote = of_graph_get_remote_port_parent(ep);
  if (remote && of_device_is_available(remote))
   drm_of_component_match_add(dev, match, component_compare_of,
         remote);
  of_node_put(remote);
 }
}

static const struct component_master_ops armada_master_ops = {
 .bind = armada_drm_bind,
 .unbind = armada_drm_unbind,
};

static int armada_drm_probe(struct platform_device *pdev)
{
 struct component_match *match = NULL;
 struct device *dev = &pdev->dev;
 int ret;

 ret = drm_of_component_probe(dev, component_compare_dev_name, &armada_master_ops);
 if (ret != -EINVAL)
  return ret;

 if (dev->platform_data) {
  char **devices = dev->platform_data;
  struct device *d;
  int i;

  for (i = 0; devices[i]; i++)
   component_match_add(dev, &match, component_compare_dev_name,
         devices[i]);

  if (i == 0) {
   dev_err(dev, "missing 'ports' property\n");
   return -ENODEV;
  }

  for (i = 0; devices[i]; i++) {
   d = bus_find_device_by_name(&platform_bus_type, NULL,
          devices[i]);
   if (d && d->of_node)
    armada_add_endpoints(dev, &match, d->of_node);
   put_device(d);
  }
 }

 return component_master_add_with_match(&pdev->dev, &armada_master_ops,
            match);
}

static void armada_drm_remove(struct platform_device *pdev)
{
 component_master_del(&pdev->dev, &armada_master_ops);
}

static void armada_drm_shutdown(struct platform_device *pdev)
{
 drm_atomic_helper_shutdown(platform_get_drvdata(pdev));
}

static const struct platform_device_id armada_drm_platform_ids[] = {
 {
  .name  = "armada-drm",
 }, {
  .name  = "armada-510-drm",
 },
 { },
};
MODULE_DEVICE_TABLE(platform, armada_drm_platform_ids);

static struct platform_driver armada_drm_platform_driver = {
 .probe = armada_drm_probe,
 .remove = armada_drm_remove,
 .shutdown = armada_drm_shutdown,
 .driver = {
  .name = "armada-drm",
 },
 .id_table = armada_drm_platform_ids,
};

static int __init armada_drm_init(void)
{
 int ret;

 if (drm_firmware_drivers_only())
  return -ENODEV;

 ret = platform_driver_register(&armada_lcd_platform_driver);
 if (ret)
  return ret;
 ret = platform_driver_register(&armada_drm_platform_driver);
 if (ret)
  platform_driver_unregister(&armada_lcd_platform_driver);
 return ret;
}
module_init(armada_drm_init);

static void __exit armada_drm_exit(void)
{
 platform_driver_unregister(&armada_drm_platform_driver);
 platform_driver_unregister(&armada_lcd_platform_driver);
}
module_exit(armada_drm_exit);

MODULE_AUTHOR("Russell King ");
MODULE_DESCRIPTION("Armada DRM Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:armada-drm");

Messung V0.5
C=96 H=95 G=95

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.