<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Maxime Ripard <maxime@cerno.tech> 于2021年3月24日周三 下午6:53写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi<br>
<br>
On Mon, Feb 22, 2021 at 09:28:18PM +0800, Kevin Tang wrote:<br>
> Adds drm support for the Unisoc's display subsystem.<br>
> <br>
> This is drm kms driver, this driver provides support for the<br>
> application framework in Android, Yocto and more.<br>
> <br>
> Application framework can access Unisoc's display internel<br>
<br>
                                                    ^ internal<br>
<br>
> peripherals through libdrm or libkms, it's test ok by modetest<br>
> (DRM/KMS test tool) and Android HWComposer.<br>
> <br>
> Cc: Orson Zhai <<a href="mailto:orsonzhai@gmail.com" target="_blank">orsonzhai@gmail.com</a>><br>
> Cc: Chunyan Zhang <<a href="mailto:zhang.lyra@gmail.com" target="_blank">zhang.lyra@gmail.com</a>><br>
> Signed-off-by: Kevin Tang <<a href="mailto:kevin.tang@unisoc.com" target="_blank">kevin.tang@unisoc.com</a>><br>
> <br>
> v4:<br>
>   - Move the devm_drm_dev_alloc to master_ops->bind function.<br>
>   - The managed drmm_mode_config_init() it is no longer necessary for drivers to explicitly call drm_mode_config_cleanup, so delete it.<br>
> ---<br>
>  drivers/gpu/drm/Kconfig         |   2 +<br>
>  drivers/gpu/drm/Makefile        |   1 +<br>
>  drivers/gpu/drm/sprd/Kconfig    |  12 ++<br>
>  drivers/gpu/drm/sprd/Makefile   |   5 +<br>
>  drivers/gpu/drm/sprd/sprd_drm.c | 217 ++++++++++++++++++++++++++++++++<br>
>  drivers/gpu/drm/sprd/sprd_drm.h |  16 +++<br>
>  6 files changed, 253 insertions(+)<br>
>  create mode 100644 drivers/gpu/drm/sprd/Kconfig<br>
>  create mode 100644 drivers/gpu/drm/sprd/Makefile<br>
>  create mode 100644 drivers/gpu/drm/sprd/sprd_drm.c<br>
>  create mode 100644 drivers/gpu/drm/sprd/sprd_drm.h<br>
> <br>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig<br>
> index 8bf103de1..9d6ce2867 100644<br>
> --- a/drivers/gpu/drm/Kconfig<br>
> +++ b/drivers/gpu/drm/Kconfig<br>
> @@ -382,6 +382,8 @@ source "drivers/gpu/drm/tidss/Kconfig"<br>
>  <br>
>  source "drivers/gpu/drm/xlnx/Kconfig"<br>
>  <br>
> +source "drivers/gpu/drm/sprd/Kconfig"<br>
> +<br>
>  # Keep legacy drivers last<br>
>  <br>
>  menuconfig DRM_LEGACY<br>
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile<br>
> index 02c229392..42d211d9c 100644<br>
> --- a/drivers/gpu/drm/Makefile<br>
> +++ b/drivers/gpu/drm/Makefile<br>
> @@ -126,3 +126,4 @@ obj-$(CONFIG_DRM_ASPEED_GFX) += aspeed/<br>
>  obj-$(CONFIG_DRM_MCDE) += mcde/<br>
>  obj-$(CONFIG_DRM_TIDSS) += tidss/<br>
>  obj-y                        += xlnx/<br>
> +obj-$(CONFIG_DRM_SPRD) += sprd/<br>
> diff --git a/drivers/gpu/drm/sprd/Kconfig b/drivers/gpu/drm/sprd/Kconfig<br>
> new file mode 100644<br>
> index 000000000..6e80cc9f3<br>
> --- /dev/null<br>
> +++ b/drivers/gpu/drm/sprd/Kconfig<br>
> @@ -0,0 +1,12 @@<br>
> +config DRM_SPRD<br>
> +     tristate "DRM Support for Unisoc SoCs Platform"<br>
> +     depends on ARCH_SPRD || COMPILE_TEST<br>
> +     depends on DRM && OF<br>
> +     select DRM_KMS_HELPER<br>
> +     select DRM_GEM_CMA_HELPER<br>
> +     select DRM_KMS_CMA_HELPER<br>
> +     select DRM_MIPI_DSI<br>
<br>
I guess this should rather be moved to your DSI introduction patch?<br></blockquote><div>Thks, it's will be fixed on patch v5. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> +     help<br>
> +       Choose this option if you have a Unisoc chipset.<br>
> +       If M is selected the module will be called sprd_drm.<br>
> +<br>
> diff --git a/drivers/gpu/drm/sprd/Makefile b/drivers/gpu/drm/sprd/Makefile<br>
> new file mode 100644<br>
> index 000000000..86d95d93a<br>
> --- /dev/null<br>
> +++ b/drivers/gpu/drm/sprd/Makefile<br>
> @@ -0,0 +1,5 @@<br>
> +# SPDX-License-Identifier: GPL-2.0<br>
> +<br>
> +subdir-ccflags-y += -I$(srctree)/$(src)<br>
<br>
Is it really needed? I'm not seeing any header that aren't in the<br>
include path already.<br></blockquote><div>

Thks, it's will be fixed on patch v5. 

 </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> +obj-y := sprd_drm.o<br>
> diff --git a/drivers/gpu/drm/sprd/sprd_drm.c b/drivers/gpu/drm/sprd/sprd_drm.c<br>
> new file mode 100644<br>
> index 000000000..a1d3ed655<br>
> --- /dev/null<br>
> +++ b/drivers/gpu/drm/sprd/sprd_drm.c<br>
> @@ -0,0 +1,217 @@<br>
> +// SPDX-License-Identifier: GPL-2.0<br>
> +/*<br>
> + * Copyright (C) 2020 Unisoc Inc.<br>
> + */<br>
> +<br>
> +#include <linux/component.h><br>
> +#include <linux/dma-mapping.h><br>
> +#include <linux/module.h><br>
> +#include <linux/mutex.h><br>
> +#include <linux/of_graph.h><br>
> +#include <linux/of_platform.h><br>
> +<br>
> +#include <drm/drm_atomic_helper.h><br>
> +#include <drm/drm_crtc_helper.h><br>
> +#include <drm/drm_drv.h><br>
> +#include <drm/drm_gem_cma_helper.h><br>
> +#include <drm/drm_gem_framebuffer_helper.h><br>
> +#include <drm/drm_of.h><br>
> +#include <drm/drm_probe_helper.h><br>
> +#include <drm/drm_vblank.h><br>
> +<br>
> +#include "sprd_drm.h"<br>
> +<br>
> +#define DRIVER_NAME  "sprd"<br>
> +#define DRIVER_DESC  "Spreadtrum SoCs' DRM Driver"<br>
> +#define DRIVER_DATE  "20200201"<br>
> +#define DRIVER_MAJOR 1<br>
> +#define DRIVER_MINOR 0<br>
> +<br>
> +static const struct drm_mode_config_helper_funcs sprd_drm_mode_config_helper = {<br>
> +     .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,<br>
> +};<br>
> +<br>
> +static const struct drm_mode_config_funcs sprd_drm_mode_config_funcs = {<br>
> +     .fb_create = drm_gem_fb_create,<br>
> +     .atomic_check = drm_atomic_helper_check,<br>
> +     .atomic_commit = drm_atomic_helper_commit,<br>
> +};<br>
> +<br>
> +static void sprd_drm_mode_config_init(struct drm_device *drm)<br>
> +{<br>
> +     drm->mode_config.min_width = 0;<br>
> +     drm->mode_config.min_height = 0;<br>
> +     drm->mode_config.max_width = 8192;<br>
> +     drm->mode_config.max_height = 8192;<br>
> +     drm->mode_config.allow_fb_modifiers = true;<br>
> +<br>
> +     drm->mode_config.funcs = &sprd_drm_mode_config_funcs;<br>
> +     drm->mode_config.helper_private = &sprd_drm_mode_config_helper;<br>
> +}<br>
> +<br>
> +DEFINE_DRM_GEM_CMA_FOPS(sprd_drm_fops);<br>
> +<br>
> +static struct drm_driver sprd_drm_drv = {<br>
> +     .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,<br>
> +     .fops                   = &sprd_drm_fops,<br>
> +<br>
> +     /* GEM Operations */<br>
> +     DRM_GEM_CMA_DRIVER_OPS,<br>
> +<br>
> +     .name                   = DRIVER_NAME,<br>
> +     .desc                   = DRIVER_DESC,<br>
> +     .date                   = DRIVER_DATE,<br>
> +     .major                  = DRIVER_MAJOR,<br>
> +     .minor                  = DRIVER_MINOR,<br>
> +};<br>
> +<br>
> +static int sprd_drm_bind(struct device *dev)<br>
> +{<br>
> +     struct platform_device *pdev = to_platform_device(dev);<br>
> +     struct drm_device *drm;<br>
> +     struct sprd_drm *sprd;<br>
> +     int ret;<br>
> +<br>
> +     sprd = devm_drm_dev_alloc(dev, &sprd_drm_drv, struct sprd_drm, drm);<br>
> +     if (IS_ERR(sprd))<br>
> +             return PTR_ERR(sprd);<br>
> +<br>
> +     drm = &sprd->drm;<br>
> +     platform_set_drvdata(pdev, drm);<br>
> +<br>
> +     ret = drmm_mode_config_init(drm);<br>
> +     if (ret)<br>
> +             return ret;<br>
> +<br>
> +     sprd_drm_mode_config_init(drm);<br>
> +<br>
> +     /* bind and init sub drivers */<br>
> +     ret = component_bind_all(drm->dev, drm);<br>
> +     if (ret) {<br>
> +             drm_err(drm, "failed to bind all component.\n");<br>
> +             return ret;<br>
> +     }<br>
> +<br>
> +     /* vblank init */<br>
> +     ret = drm_vblank_init(drm, drm->mode_config.num_crtc);<br>
> +     if (ret) {<br>
> +             drm_err(drm, "failed to initialize vblank.\n");<br>
> +             goto err_unbind_all;<br>
> +     }<br>
> +     /* with irq_enabled = true, we can use the vblank feature. */<br>
> +     drm->irq_enabled = true;<br>
> +<br>
> +     /* reset all the states of crtc/plane/encoder/connector */<br>
> +     drm_mode_config_reset(drm);<br>
> +<br>
> +     /* init kms poll for handling hpd */<br>
> +     drm_kms_helper_poll_init(drm);<br>
> +<br>
> +     ret = drm_dev_register(drm, 0);<br>
> +     if (ret < 0)<br>
> +             goto err_kms_helper_poll_fini;<br>
> +<br>
> +     return 0;<br>
> +<br>
> +err_kms_helper_poll_fini:<br>
> +     drm_kms_helper_poll_fini(drm);<br>
> +err_unbind_all:<br>
> +     component_unbind_all(drm->dev, drm);<br>
> +     return ret;<br>
> +}<br>
> +<br>
> +static void sprd_drm_unbind(struct device *dev)<br>
> +{<br>
> +     struct drm_device *drm = dev_get_drvdata(dev);<br>
> +<br>
> +     drm_dev_unregister(drm);<br>
> +<br>
> +     drm_kms_helper_poll_fini(drm);<br>
> +<br>
> +     component_unbind_all(drm->dev, drm);<br>
> +}<br>
> +<br>
> +static const struct component_master_ops drm_component_ops = {<br>
> +     .bind = sprd_drm_bind,<br>
> +     .unbind = sprd_drm_unbind,<br>
> +};<br>
> +<br>
> +static int compare_of(struct device *dev, void *data)<br>
> +{<br>
> +     return dev->of_node == data;<br>
> +}<br>
> +<br>
> +static int sprd_drm_probe(struct platform_device *pdev)<br>
> +{<br>
> +     struct device *dev = &pdev->dev;<br>
> +     int ret;<br>
> +<br>
> +     ret = dma_set_mask_and_coherent(dev, ~0UL);<br>
> +     if (ret) {<br>
> +             dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);<br>
> +             return ret;<br>
> +     }<br>
<br>
It's not really clear to me what it's here for. Could you explain with a<br>
comment here?<br></blockquote><div>

Thks, it's will be fixed on patch v5. 

 

 </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Thanks<br>
Maxime<br>
</blockquote></div></div>