Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp2634179ybv; Mon, 24 Feb 2020 08:44:58 -0800 (PST) X-Google-Smtp-Source: APXvYqxT6C7FCAt9LUrEAFaZKIOZ+ebz4HXdCzxvdCAHdPugG+YfZnUluxNj7F+I7ZJGg6d4iOEE X-Received: by 2002:aca:3f43:: with SMTP id m64mr12774045oia.165.1582562698299; Mon, 24 Feb 2020 08:44:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1582562698; cv=none; d=google.com; s=arc-20160816; b=Np7fNGwqvdO50J6N8h93HcWOek21SubQpBcOoUU4dPLVgFFQJF4Dv+2mD0H2uIFJFH gYc0N7IXogn6EwPSeludFSB5Wgy2FvMWXS9Shmv1zcUOIcKBAcSQwKHeX/lS9OFjWaqJ ZAdfn/iy+PvZuCKwtueaU/P9Q74Z3XRQd7p1WmvPomd43wm+D+7I90Cl9U5edSwSOnr3 CzHFNqvnNgi3XTs5JFNCigw6bIwAZJa9ONADGc0NdG75vKdskdrtYoTjQLybp389jIvU Vdz3g1O92RcgvX7cVcbQShpEy7GiV9XAfKwzEhjHdze8rQd9gKRvGZoJ+3/gos4Apvpw foRA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=x3iMdgcJvhdPaNdsBIZMg+A92EcAUzwpTpA940qYnKo=; b=OIHGrmx4SCpCC5hVSNRhvVk24bprNPFiHCXGNSW1NwiYD6lKY3/4083fjiBUDdJWd2 eDgv/yflC6Gc5yoQxve5nasbD5ArlsvZy/XP4wF2aPzwqwgMYyoeF+LpZJ6+m735oeiH ZQvoOWe+HwHvLPvazX8yi+dUk+3fFeabv2gi1zK2qkNj9PCW7r41F7c3BKN2cox4H7s/ ipdWg8X/PuzLauRocdXcY8aGW3TvrV7NW84acKTA1bvDKssWACIz9tO7Rap7bK2XFgCv wVhuRl9BDj0PbUTwxYF7G4Zp10aXLbIHgl7b9erLitXpxiL3MEL3p/gm6vZ5MIN1xxGH FbXA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=lruTX+Yq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v6si6317640ota.19.2020.02.24.08.44.45; Mon, 24 Feb 2020 08:44:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=lruTX+Yq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727689AbgBXQna (ORCPT + 99 others); Mon, 24 Feb 2020 11:43:30 -0500 Received: from mail-ua1-f68.google.com ([209.85.222.68]:42064 "EHLO mail-ua1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727426AbgBXQna (ORCPT ); Mon, 24 Feb 2020 11:43:30 -0500 Received: by mail-ua1-f68.google.com with SMTP id p2so3442807uao.9 for ; Mon, 24 Feb 2020 08:43:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=x3iMdgcJvhdPaNdsBIZMg+A92EcAUzwpTpA940qYnKo=; b=lruTX+YqdxxtwSJdiuUeSP9//uqvNR8HQ6aMPj8TaZ2lyJWECp2EhvRoFkT2hrU7Wj hqV4iCJgs9dIgmUp1T75c0QOD/GDNuhNNo2nF+yd2RHGFQyTOwZoYMkIzK3v/yrWvUmN a6p1MAIljW3JVw+c4ZGkDn50r7nbRrQbtQTSEyzfeKMfu988yr+Al3VmOTG2bGlR1/hv d7hTIOTEMejBSj49OcBJenumu5HOUP5cjxT+pJxgNhbrg34QdUdilKSLg/o4xRTrIIow IPEyCyxyuZahW13WboKhz4lMKzJygpMmWT8EdrUaIxwzDW3gfPm0XFppTgRad/L95eYu +kZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=x3iMdgcJvhdPaNdsBIZMg+A92EcAUzwpTpA940qYnKo=; b=NiqFbtpw+spBKhwJVzY0G7lZcRBZvJOuD7BMQSrmxH1YWnE2aMpg9wYIm/pExLJFqm 3yyafc24PA+CBUnwBlUpZUjqJ+wUhYXxHULOzSl1joDXpcjW22rJftChX8uq7oIQPGrN VQ0wzOBUfLxBeIo/xCaHtvkRrzK3impeZKdEBxzt3+/TG+lURaEFNuSiFbc8XFm0WqGL 0y0DwmaZSDB57qm4sZq7HZjz4B06pST1lTmSl+O9mH+1nOY7O5pyJeEqxpVK7fFp1CE2 IgUpQfHZPdwKt/S8LnlJUEPJPwSYxxjdmICykpoPI3ia+dlGevt2SjqC5v7K1snxO53L cfxQ== X-Gm-Message-State: APjAAAWKK2TYwAu0jdDARkR+2EtEl7UJb36qP8FzRMtdJqSc6XNY3dRz pxLWPhVsvH2OqvtglOz4SXEEFj5m5Bp1cXp4qR0= X-Received: by 2002:ab0:66d4:: with SMTP id d20mr24839010uaq.64.1582562607061; Mon, 24 Feb 2020 08:43:27 -0800 (PST) MIME-Version: 1.0 References: <1582271336-3708-1-git-send-email-kevin3.tang@gmail.com> <1582271336-3708-3-git-send-email-kevin3.tang@gmail.com> In-Reply-To: <1582271336-3708-3-git-send-email-kevin3.tang@gmail.com> From: Emil Velikov Date: Mon, 24 Feb 2020 16:43:08 +0000 Message-ID: Subject: Re: [PATCH RFC v3 2/6] drm/sprd: add Unisoc's drm kms master To: Kevin Tang Cc: Dave Airlie , Daniel Vetter , Rob Herring , Mark Rutland , Orson Zhai , ML dri-devel , "Linux-Kernel@Vger. Kernel. Org" , Chunyan Zhang , Baolin Wang Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi all, On Fri, 21 Feb 2020 at 11:15, Kevin Tang wrote: > > From: Kevin Tang > > Adds drm support for the Unisoc's display subsystem. > > This is drm device and gem driver. This driver provides support for the > Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. > > Cc: Orson Zhai > Cc: Baolin Wang > Cc: Chunyan Zhang > Signed-off-by: Kevin Tang > --- > drivers/gpu/drm/Kconfig | 2 + > drivers/gpu/drm/Makefile | 1 + > drivers/gpu/drm/sprd/Kconfig | 14 ++ > drivers/gpu/drm/sprd/Makefile | 7 + > drivers/gpu/drm/sprd/sprd_drm.c | 292 ++++++++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/sprd/sprd_drm.h | 16 +++ > 6 files changed, 332 insertions(+) > create mode 100644 drivers/gpu/drm/sprd/Kconfig > create mode 100644 drivers/gpu/drm/sprd/Makefile > create mode 100644 drivers/gpu/drm/sprd/sprd_drm.c > create mode 100644 drivers/gpu/drm/sprd/sprd_drm.h > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index bfdadc3..cead12c 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -387,6 +387,8 @@ source "drivers/gpu/drm/aspeed/Kconfig" > > source "drivers/gpu/drm/mcde/Kconfig" > > +source "drivers/gpu/drm/sprd/Kconfig" > + > # Keep legacy drivers last > > menuconfig DRM_LEGACY > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 9f1c7c4..85ca211 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -122,3 +122,4 @@ obj-$(CONFIG_DRM_LIMA) += lima/ > obj-$(CONFIG_DRM_PANFROST) += panfrost/ > obj-$(CONFIG_DRM_ASPEED_GFX) += aspeed/ > obj-$(CONFIG_DRM_MCDE) += mcde/ > +obj-$(CONFIG_DRM_SPRD) += sprd/ > diff --git a/drivers/gpu/drm/sprd/Kconfig b/drivers/gpu/drm/sprd/Kconfig > new file mode 100644 > index 0000000..79f286b > --- /dev/null > +++ b/drivers/gpu/drm/sprd/Kconfig > @@ -0,0 +1,14 @@ > +config DRM_SPRD > + tristate "DRM Support for Unisoc SoCs Platform" > + depends on ARCH_SPRD > + depends on DRM && OF > + select DRM_KMS_HELPER > + select DRM_GEM_CMA_HELPER > + select DRM_KMS_CMA_HELPER > + select DRM_MIPI_DSI > + select DRM_PANEL > + select VIDEOMODE_HELPERS > + select BACKLIGHT_CLASS_DEVICE > + help > + Choose this option if you have a Unisoc chipsets. > + If M is selected the module will be called sprd-drm. > \ No newline at end of file > diff --git a/drivers/gpu/drm/sprd/Makefile b/drivers/gpu/drm/sprd/Makefile > new file mode 100644 > index 0000000..63b8751 > --- /dev/null > +++ b/drivers/gpu/drm/sprd/Makefile > @@ -0,0 +1,7 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +ccflags-y += -Iinclude/drm > + > +subdir-ccflags-y += -I$(src) > + > +obj-y := sprd_drm.o > diff --git a/drivers/gpu/drm/sprd/sprd_drm.c b/drivers/gpu/drm/sprd/sprd_drm.c > new file mode 100644 > index 0000000..7cac098 > --- /dev/null > +++ b/drivers/gpu/drm/sprd/sprd_drm.c > @@ -0,0 +1,292 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2019 Unisoc Inc. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "sprd_drm.h" > + > +#define DRIVER_NAME "sprd" > +#define DRIVER_DESC "Spreadtrum SoCs' DRM Driver" > +#define DRIVER_DATE "20191101" > +#define DRIVER_MAJOR 1 > +#define DRIVER_MINOR 0 > + > +static const struct drm_mode_config_helper_funcs sprd_drm_mode_config_helper = { > + .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, > +}; > + > +static const struct drm_mode_config_funcs sprd_drm_mode_config_funcs = { > + .fb_create = drm_gem_fb_create, > + .atomic_check = drm_atomic_helper_check, > + .atomic_commit = drm_atomic_helper_commit, > +}; > + > +static void sprd_drm_mode_config_init(struct drm_device *drm) > +{ > + drm_mode_config_init(drm); > + > + drm->mode_config.min_width = 0; > + drm->mode_config.min_height = 0; > + drm->mode_config.max_width = 8192; > + drm->mode_config.max_height = 8192; > + drm->mode_config.allow_fb_modifiers = true; > + > + drm->mode_config.funcs = &sprd_drm_mode_config_funcs; > + drm->mode_config.helper_private = &sprd_drm_mode_config_helper; > +} > + > +DEFINE_DRM_GEM_CMA_FOPS(sprd_drm_fops); > + > +static struct drm_driver sprd_drm_drv = { > + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, > + .fops = &sprd_drm_fops, > + > + /* GEM Operations */ > + DRM_GEM_CMA_VMAP_DRIVER_OPS, > + > + .name = DRIVER_NAME, > + .desc = DRIVER_DESC, > + .date = DRIVER_DATE, > + .major = DRIVER_MAJOR, > + .minor = DRIVER_MINOR, > +}; > + > +static int sprd_drm_bind(struct device *dev) > +{ > + struct drm_device *drm; > + struct sprd_drm *sprd; > + int err; > + > + drm = drm_dev_alloc(&sprd_drm_drv, dev); > + if (IS_ERR(drm)) > + return PTR_ERR(drm); > + > + dev_set_drvdata(dev, drm); > + > + sprd = devm_kzalloc(drm->dev, sizeof(*sprd), GFP_KERNEL); > + if (!sprd) { > + err = -ENOMEM; > + goto err_free_drm; > + } > + drm->dev_private = sprd; > + > + sprd_drm_mode_config_init(drm); > + > + /* bind and init sub drivers */ > + err = component_bind_all(drm->dev, drm); > + if (err) { > + DRM_ERROR("failed to bind all component.\n"); > + goto err_dc_cleanup; > + } > + > + /* vblank init */ > + err = drm_vblank_init(drm, drm->mode_config.num_crtc); > + if (err) { > + DRM_ERROR("failed to initialize vblank.\n"); > + goto err_unbind_all; > + } > + /* with irq_enabled = true, we can use the vblank feature. */ > + drm->irq_enabled = true; > + > + /* reset all the states of crtc/plane/encoder/connector */ > + drm_mode_config_reset(drm); > + > + /* init kms poll for handling hpd */ > + drm_kms_helper_poll_init(drm); > + > + err = drm_dev_register(drm, 0); > + if (err < 0) > + goto err_kms_helper_poll_fini; > + > + return 0; > + > +err_kms_helper_poll_fini: > + drm_kms_helper_poll_fini(drm); > +err_unbind_all: > + component_unbind_all(drm->dev, drm); > +err_dc_cleanup: > + drm_mode_config_cleanup(drm); > +err_free_drm: > + drm_dev_put(drm); > + return err; > +} > + > +static void sprd_drm_unbind(struct device *dev) > +{ > + drm_put_dev(dev_get_drvdata(dev)); > +} > + > +static const struct component_master_ops drm_component_ops = { > + .bind = sprd_drm_bind, > + .unbind = sprd_drm_unbind, > +}; > + > +static int compare_of(struct device *dev, void *data) > +{ > + struct device_node *np = data; > + > + DRM_DEBUG("compare %s\n", np->full_name); > + > + return dev->of_node == np; > +} > + > +static int sprd_drm_component_probe(struct device *dev, > + const struct component_master_ops *m_ops) > +{ > + struct device_node *ep, *port, *remote; > + struct component_match *match = NULL; > + int i; > + > + if (!dev->of_node) > + return -EINVAL; > + > + /* > + * Bind the crtc's ports first, so that drm_of_find_possible_crtcs() > + * called from encoder's .bind callbacks works as expected > + */ > + for (i = 0; ; i++) { > + port = of_parse_phandle(dev->of_node, "ports", i); > + if (!port) > + break; > + > + if (!of_device_is_available(port->parent)) { > + of_node_put(port); > + continue; > + } > + > + component_match_add(dev, &match, compare_of, port->parent); > + of_node_put(port); > + } > + > + if (i == 0) { > + dev_err(dev, "missing 'ports' property\n"); > + return -ENODEV; > + } > + > + if (!match) { > + dev_err(dev, "no available port\n"); > + return -ENODEV; > + } > + > + /* > + * For bound crtcs, bind the encoders attached to their remote endpoint > + */ > + for (i = 0; ; i++) { > + port = of_parse_phandle(dev->of_node, "ports", i); > + if (!port) > + break; > + > + if (!of_device_is_available(port->parent)) { > + of_node_put(port); > + continue; > + } > + > + for_each_child_of_node(port, ep) { > + remote = of_graph_get_remote_port_parent(ep); > + if (!remote || !of_device_is_available(remote)) { > + of_node_put(remote); > + continue; > + } else if (!of_device_is_available(remote->parent)) { > + dev_warn(dev, "parent device of %s is not available\n", > + remote->full_name); > + of_node_put(remote); > + continue; > + } > + > + component_match_add(dev, &match, compare_of, remote); > + of_node_put(remote); > + } > + of_node_put(port); > + } > + > + return component_master_add_with_match(dev, m_ops, match); This whole function is effectively a copy of drm_of_component_probe(). Reuse that instead. With that + comments from Sam addressed this patch is: Reviewed-by: Emil Velikov -Emil