From patchwork Sun Feb 10 13:10:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10804755 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2AC501669 for ; Sun, 10 Feb 2019 13:11:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1B3BC29F95 for ; Sun, 10 Feb 2019 13:11:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0FB5629F9D; Sun, 10 Feb 2019 13:11:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8B0E029F95 for ; Sun, 10 Feb 2019 13:11:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A87936E0E5; Sun, 10 Feb 2019 13:11:04 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id B5FD66E0E0 for ; Sun, 10 Feb 2019 13:10:56 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:41944 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84_2) (envelope-from ) id 1gsoso-00071t-RF; Sun, 10 Feb 2019 14:10:54 +0100 From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [PATCH v2 09/12] drm/tinydrm: Drop using tinydrm_device Date: Sun, 10 Feb 2019 14:10:36 +0100 Message-Id: <20190210131039.52664-10-noralf@tronnes.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190210131039.52664-1-noralf@tronnes.org> References: <20190210131039.52664-1-noralf@tronnes.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, david@lechnology.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Use devm_drm_dev_init() and drop using tinydrm_device. v2: devm_drm_dev_register() was dropped so add driver release callbacks. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/tinydrm/hx8357d.c | 40 +++++++++-- drivers/gpu/drm/tinydrm/ili9225.c | 40 +++++++++-- drivers/gpu/drm/tinydrm/ili9341.c | 40 +++++++++-- drivers/gpu/drm/tinydrm/mi0283qt.c | 40 +++++++++-- drivers/gpu/drm/tinydrm/mipi-dbi.c | 67 +++++++++++------- drivers/gpu/drm/tinydrm/st7586.c | 105 ++++++++++++++++------------- drivers/gpu/drm/tinydrm/st7735r.c | 40 +++++++++-- include/drm/tinydrm/mipi-dbi.h | 26 ++++--- 8 files changed, 294 insertions(+), 104 deletions(-) diff --git a/drivers/gpu/drm/tinydrm/hx8357d.c b/drivers/gpu/drm/tinydrm/hx8357d.c index 84dda622df85..e9b9e08fafc7 100644 --- a/drivers/gpu/drm/tinydrm/hx8357d.c +++ b/drivers/gpu/drm/tinydrm/hx8357d.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -189,6 +190,7 @@ DEFINE_DRM_GEM_CMA_FOPS(hx8357d_fops); static struct drm_driver hx8357d_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, .fops = &hx8357d_fops, + .release = mipi_dbi_release, DRM_GEM_CMA_VMAP_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "hx8357d", @@ -213,15 +215,25 @@ MODULE_DEVICE_TABLE(spi, hx8357d_id); static int hx8357d_probe(struct spi_device *spi) { struct device *dev = &spi->dev; + struct drm_device *drm; struct mipi_dbi *mipi; struct gpio_desc *dc; u32 rotation = 0; int ret; - mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL); + mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); if (!mipi) return -ENOMEM; + drm = &mipi->drm; + ret = devm_drm_dev_init(dev, drm, &hx8357d_driver); + if (ret) { + kfree(mipi); + return ret; + } + + drm_mode_config_init(drm); + dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW); if (IS_ERR(dc)) { DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n"); @@ -238,14 +250,31 @@ static int hx8357d_probe(struct spi_device *spi) if (ret) return ret; - ret = mipi_dbi_init(&spi->dev, mipi, &hx8357d_pipe_funcs, - &hx8357d_driver, &yx350hv15_mode, rotation); + ret = mipi_dbi_init(mipi, &hx8357d_pipe_funcs, &yx350hv15_mode, rotation); if (ret) return ret; - spi_set_drvdata(spi, mipi->tinydrm.drm); + drm_mode_config_reset(drm); - return devm_tinydrm_register(&mipi->tinydrm); + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + drm_fbdev_generic_setup(drm, 32); + + return 0; +} + +static int hx8357d_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; } static void hx8357d_shutdown(struct spi_device *spi) @@ -260,6 +289,7 @@ static struct spi_driver hx8357d_spi_driver = { }, .id_table = hx8357d_id, .probe = hx8357d_probe, + .remove = hx8357d_remove, .shutdown = hx8357d_shutdown, }; module_spi_driver(hx8357d_spi_driver); diff --git a/drivers/gpu/drm/tinydrm/ili9225.c b/drivers/gpu/drm/tinydrm/ili9225.c index 3f59cfbd31ba..4d387a07c48b 100644 --- a/drivers/gpu/drm/tinydrm/ili9225.c +++ b/drivers/gpu/drm/tinydrm/ili9225.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -339,6 +340,7 @@ static struct drm_driver ili9225_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, .fops = &ili9225_fops, + .release = mipi_dbi_release, DRM_GEM_CMA_VMAP_DRIVER_OPS, .name = "ili9225", .desc = "Ilitek ILI9225", @@ -362,15 +364,25 @@ MODULE_DEVICE_TABLE(spi, ili9225_id); static int ili9225_probe(struct spi_device *spi) { struct device *dev = &spi->dev; + struct drm_device *drm; struct mipi_dbi *mipi; struct gpio_desc *rs; u32 rotation = 0; int ret; - mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL); + mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); if (!mipi) return -ENOMEM; + drm = &mipi->drm; + ret = devm_drm_dev_init(dev, drm, &ili9225_driver); + if (ret) { + kfree(mipi); + return ret; + } + + drm_mode_config_init(drm); + mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(mipi->reset)) { DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n"); @@ -392,14 +404,31 @@ static int ili9225_probe(struct spi_device *spi) /* override the command function set in mipi_dbi_spi_init() */ mipi->command = ili9225_dbi_command; - ret = mipi_dbi_init(&spi->dev, mipi, &ili9225_pipe_funcs, - &ili9225_driver, &ili9225_mode, rotation); + ret = mipi_dbi_init(mipi, &ili9225_pipe_funcs, &ili9225_mode, rotation); if (ret) return ret; - spi_set_drvdata(spi, mipi->tinydrm.drm); + drm_mode_config_reset(drm); - return devm_tinydrm_register(&mipi->tinydrm); + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + drm_fbdev_generic_setup(drm, 32); + + return 0; +} + +static int ili9225_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; } static void ili9225_shutdown(struct spi_device *spi) @@ -415,6 +444,7 @@ static struct spi_driver ili9225_spi_driver = { }, .id_table = ili9225_id, .probe = ili9225_probe, + .remove = ili9225_remove, .shutdown = ili9225_shutdown, }; module_spi_driver(ili9225_spi_driver); diff --git a/drivers/gpu/drm/tinydrm/ili9341.c b/drivers/gpu/drm/tinydrm/ili9341.c index 3b7565a6311e..850ce9ed6dd2 100644 --- a/drivers/gpu/drm/tinydrm/ili9341.c +++ b/drivers/gpu/drm/tinydrm/ili9341.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -145,6 +146,7 @@ DEFINE_DRM_GEM_CMA_FOPS(ili9341_fops); static struct drm_driver ili9341_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, .fops = &ili9341_fops, + .release = mipi_dbi_release, DRM_GEM_CMA_VMAP_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "ili9341", @@ -169,15 +171,25 @@ MODULE_DEVICE_TABLE(spi, ili9341_id); static int ili9341_probe(struct spi_device *spi) { struct device *dev = &spi->dev; + struct drm_device *drm; struct mipi_dbi *mipi; struct gpio_desc *dc; u32 rotation = 0; int ret; - mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL); + mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); if (!mipi) return -ENOMEM; + drm = &mipi->drm; + ret = devm_drm_dev_init(dev, drm, &ili9341_driver); + if (ret) { + kfree(mipi); + return ret; + } + + drm_mode_config_init(drm); + mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(mipi->reset)) { DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n"); @@ -200,14 +212,31 @@ static int ili9341_probe(struct spi_device *spi) if (ret) return ret; - ret = mipi_dbi_init(&spi->dev, mipi, &ili9341_pipe_funcs, - &ili9341_driver, &yx240qv29_mode, rotation); + ret = mipi_dbi_init(mipi, &ili9341_pipe_funcs, &yx240qv29_mode, rotation); if (ret) return ret; - spi_set_drvdata(spi, mipi->tinydrm.drm); + drm_mode_config_reset(drm); - return devm_tinydrm_register(&mipi->tinydrm); + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + drm_fbdev_generic_setup(drm, 32); + + return 0; +} + +static int ili9341_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; } static void ili9341_shutdown(struct spi_device *spi) @@ -222,6 +251,7 @@ static struct spi_driver ili9341_spi_driver = { }, .id_table = ili9341_id, .probe = ili9341_probe, + .remove = ili9341_remove, .shutdown = ili9341_shutdown, }; module_spi_driver(ili9341_spi_driver); diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c index da326fd1450d..7aee05586e92 100644 --- a/drivers/gpu/drm/tinydrm/mi0283qt.c +++ b/drivers/gpu/drm/tinydrm/mi0283qt.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -154,6 +155,7 @@ static struct drm_driver mi0283qt_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, .fops = &mi0283qt_fops, + .release = mipi_dbi_release, DRM_GEM_CMA_VMAP_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "mi0283qt", @@ -178,15 +180,25 @@ MODULE_DEVICE_TABLE(spi, mi0283qt_id); static int mi0283qt_probe(struct spi_device *spi) { struct device *dev = &spi->dev; + struct drm_device *drm; struct mipi_dbi *mipi; struct gpio_desc *dc; u32 rotation = 0; int ret; - mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL); + mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); if (!mipi) return -ENOMEM; + drm = &mipi->drm; + ret = devm_drm_dev_init(dev, drm, &mi0283qt_driver); + if (ret) { + kfree(mipi); + return ret; + } + + drm_mode_config_init(drm); + mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(mipi->reset)) { DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n"); @@ -213,14 +225,31 @@ static int mi0283qt_probe(struct spi_device *spi) if (ret) return ret; - ret = mipi_dbi_init(&spi->dev, mipi, &mi0283qt_pipe_funcs, - &mi0283qt_driver, &mi0283qt_mode, rotation); + ret = mipi_dbi_init(mipi, &mi0283qt_pipe_funcs, &mi0283qt_mode, rotation); if (ret) return ret; - spi_set_drvdata(spi, mipi->tinydrm.drm); + drm_mode_config_reset(drm); - return devm_tinydrm_register(&mipi->tinydrm); + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + drm_fbdev_generic_setup(drm, 32); + + return 0; +} + +static int mi0283qt_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; } static void mi0283qt_shutdown(struct spi_device *spi) @@ -253,6 +282,7 @@ static struct spi_driver mi0283qt_spi_driver = { }, .id_table = mi0283qt_id, .probe = mi0283qt_probe, + .remove = mi0283qt_remove, .shutdown = mi0283qt_shutdown, }; module_spi_driver(mi0283qt_spi_driver); diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c index 045b840812c3..ecfee357436d 100644 --- a/drivers/gpu/drm/tinydrm/mipi-dbi.c +++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c @@ -316,7 +316,7 @@ EXPORT_SYMBOL(mipi_dbi_enable_flush); static void mipi_dbi_blank(struct mipi_dbi *mipi) { - struct drm_device *drm = mipi->tinydrm.drm; + struct drm_device *drm = &mipi->drm; u16 height = drm->mode_config.min_height; u16 width = drm->mode_config.min_width; size_t len = width * height * 2; @@ -357,6 +357,12 @@ void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe) } EXPORT_SYMBOL(mipi_dbi_pipe_disable); +static const struct drm_mode_config_funcs mipi_dbi_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + static const uint32_t mipi_dbi_formats[] = { DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888, @@ -364,31 +370,27 @@ static const uint32_t mipi_dbi_formats[] = { /** * mipi_dbi_init - MIPI DBI initialization - * @dev: Parent device * @mipi: &mipi_dbi structure to initialize - * @pipe_funcs: Display pipe functions - * @driver: DRM driver + * @funcs: Display pipe functions * @mode: Display mode * @rotation: Initial rotation in degrees Counter Clock Wise * - * This function initializes a &mipi_dbi structure and it's underlying - * @tinydrm_device. It also sets up the display pipeline. + * This function sets up a &drm_simple_display_pipe with a &drm_connector that + * has one fixed &drm_display_mode which is rotated according to @rotation. + * This mode is used to set the mode config min/max width/height properties. + * Additionally &mipi_dbi.tx_buf is allocated. * * Supported formats: Native RGB565 and emulated XRGB8888. * - * Objects created by this function will be automatically freed on driver - * detach (devres). - * * Returns: * Zero on success, negative error code on failure. */ -int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi, - const struct drm_simple_display_pipe_funcs *pipe_funcs, - struct drm_driver *driver, +int mipi_dbi_init(struct mipi_dbi *mipi, + const struct drm_simple_display_pipe_funcs *funcs, const struct drm_display_mode *mode, unsigned int rotation) { size_t bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16); - struct tinydrm_device *tdev = &mipi->tinydrm; + struct drm_device *drm = &mipi->drm; int ret; if (!mipi->command) @@ -396,16 +398,12 @@ int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi, mutex_init(&mipi->cmdlock); - mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL); + mipi->tx_buf = devm_kmalloc(drm->dev, bufsize, GFP_KERNEL); if (!mipi->tx_buf) return -ENOMEM; - ret = devm_tinydrm_init(dev, tdev, driver); - if (ret) - return ret; - /* TODO: Maybe add DRM_MODE_CONNECTOR_SPI */ - ret = tinydrm_display_pipe_init(tdev->drm, &tdev->pipe, pipe_funcs, + ret = tinydrm_display_pipe_init(drm, &mipi->pipe, funcs, DRM_MODE_CONNECTOR_VIRTUAL, mipi_dbi_formats, ARRAY_SIZE(mipi_dbi_formats), mode, @@ -413,20 +411,39 @@ int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi, if (ret) return ret; - drm_plane_enable_fb_damage_clips(&tdev->pipe.plane); + drm_plane_enable_fb_damage_clips(&mipi->pipe.plane); - tdev->drm->mode_config.preferred_depth = 16; + drm->mode_config.funcs = &mipi_dbi_mode_config_funcs; + drm->mode_config.preferred_depth = 16; mipi->rotation = rotation; - drm_mode_config_reset(tdev->drm); - DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n", - tdev->drm->mode_config.preferred_depth, rotation); + drm->mode_config.preferred_depth, rotation); return 0; } EXPORT_SYMBOL(mipi_dbi_init); +/** + * mipi_dbi_release - DRM driver release helper + * @drm: DRM device + * + * This function finalizes and frees &mipi_dbi. + * + * Drivers can use this as their &drm_driver->release callback. + */ +void mipi_dbi_release(struct drm_device *drm) +{ + struct mipi_dbi *dbi = drm_to_mipi_dbi(drm); + + DRM_DEBUG_DRIVER("\n"); + + drm_mode_config_cleanup(drm); + drm_dev_fini(drm); + kfree(dbi); +} +EXPORT_SYMBOL(mipi_dbi_release); + /** * mipi_dbi_hw_reset - Hardware reset of controller * @mipi: MIPI DBI structure @@ -479,7 +496,7 @@ EXPORT_SYMBOL(mipi_dbi_display_is_on); static int mipi_dbi_poweron_reset_conditional(struct mipi_dbi *mipi, bool cond) { - struct device *dev = mipi->tinydrm.drm->dev; + struct device *dev = mipi->drm.dev; int ret; if (mipi->regulator) { diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c index 6097585913f2..6e92de809b63 100644 --- a/drivers/gpu/drm/tinydrm/st7586.c +++ b/drivers/gpu/drm/tinydrm/st7586.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -262,46 +263,6 @@ static const u32 st7586_formats[] = { DRM_FORMAT_XRGB8888, }; -static int st7586_init(struct device *dev, struct mipi_dbi *mipi, - const struct drm_simple_display_pipe_funcs *pipe_funcs, - struct drm_driver *driver, const struct drm_display_mode *mode, - unsigned int rotation) -{ - size_t bufsize = (mode->vdisplay + 2) / 3 * mode->hdisplay; - struct tinydrm_device *tdev = &mipi->tinydrm; - int ret; - - mutex_init(&mipi->cmdlock); - - mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL); - if (!mipi->tx_buf) - return -ENOMEM; - - ret = devm_tinydrm_init(dev, tdev, driver); - if (ret) - return ret; - - ret = tinydrm_display_pipe_init(tdev->drm, &tdev->pipe, pipe_funcs, - DRM_MODE_CONNECTOR_VIRTUAL, - st7586_formats, - ARRAY_SIZE(st7586_formats), - mode, rotation); - if (ret) - return ret; - - drm_plane_enable_fb_damage_clips(&tdev->pipe.plane); - - tdev->drm->mode_config.preferred_depth = 32; - mipi->rotation = rotation; - - drm_mode_config_reset(tdev->drm); - - DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n", - tdev->drm->mode_config.preferred_depth, rotation); - - return 0; -} - static const struct drm_simple_display_pipe_funcs st7586_pipe_funcs = { .enable = st7586_pipe_enable, .disable = st7586_pipe_disable, @@ -309,6 +270,12 @@ static const struct drm_simple_display_pipe_funcs st7586_pipe_funcs = { .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb, }; +static const struct drm_mode_config_funcs st7586_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + static const struct drm_display_mode st7586_mode = { DRM_SIMPLE_MODE(178, 128, 37, 27), }; @@ -319,6 +286,7 @@ static struct drm_driver st7586_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, .fops = &st7586_fops, + .release = mipi_dbi_release, DRM_GEM_CMA_VMAP_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "st7586", @@ -343,15 +311,35 @@ MODULE_DEVICE_TABLE(spi, st7586_id); static int st7586_probe(struct spi_device *spi) { struct device *dev = &spi->dev; + struct drm_device *drm; struct mipi_dbi *mipi; struct gpio_desc *a0; u32 rotation = 0; + size_t bufsize; int ret; - mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL); + mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); if (!mipi) return -ENOMEM; + drm = &mipi->drm; + ret = devm_drm_dev_init(dev, drm, &st7586_driver); + if (ret) { + kfree(mipi); + return ret; + } + + drm_mode_config_init(drm); + drm->mode_config.preferred_depth = 32; + drm->mode_config.funcs = &st7586_mode_config_funcs; + + mutex_init(&mipi->cmdlock); + + bufsize = (st7586_mode.vdisplay + 2) / 3 * st7586_mode.hdisplay; + mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL); + if (!mipi->tx_buf) + return -ENOMEM; + mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(mipi->reset)) { DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n"); @@ -365,6 +353,7 @@ static int st7586_probe(struct spi_device *spi) } device_property_read_u32(dev, "rotation", &rotation); + mipi->rotation = rotation; ret = mipi_dbi_spi_init(spi, mipi, a0); if (ret) @@ -382,14 +371,39 @@ static int st7586_probe(struct spi_device *spi) */ mipi->swap_bytes = true; - ret = st7586_init(&spi->dev, mipi, &st7586_pipe_funcs, &st7586_driver, - &st7586_mode, rotation); + ret = tinydrm_display_pipe_init(drm, &mipi->pipe, &st7586_pipe_funcs, + DRM_MODE_CONNECTOR_VIRTUAL, + st7586_formats, ARRAY_SIZE(st7586_formats), + &st7586_mode, rotation); if (ret) return ret; - spi_set_drvdata(spi, mipi->tinydrm.drm); + drm_plane_enable_fb_damage_clips(&mipi->pipe.plane); - return devm_tinydrm_register(&mipi->tinydrm); + drm_mode_config_reset(drm); + + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n", + drm->mode_config.preferred_depth, rotation); + + drm_fbdev_generic_setup(drm, 32); + + return 0; +} + +static int st7586_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; } static void st7586_shutdown(struct spi_device *spi) @@ -405,6 +419,7 @@ static struct spi_driver st7586_spi_driver = { }, .id_table = st7586_id, .probe = st7586_probe, + .remove = st7586_remove, .shutdown = st7586_shutdown, }; module_spi_driver(st7586_spi_driver); diff --git a/drivers/gpu/drm/tinydrm/st7735r.c b/drivers/gpu/drm/tinydrm/st7735r.c index bfa7e2221540..0f8a346026ac 100644 --- a/drivers/gpu/drm/tinydrm/st7735r.c +++ b/drivers/gpu/drm/tinydrm/st7735r.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -120,6 +121,7 @@ static struct drm_driver st7735r_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, .fops = &st7735r_fops, + .release = mipi_dbi_release, DRM_GEM_CMA_VMAP_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "st7735r", @@ -144,15 +146,25 @@ MODULE_DEVICE_TABLE(spi, st7735r_id); static int st7735r_probe(struct spi_device *spi) { struct device *dev = &spi->dev; + struct drm_device *drm; struct mipi_dbi *mipi; struct gpio_desc *dc; u32 rotation = 0; int ret; - mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL); + mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); if (!mipi) return -ENOMEM; + drm = &mipi->drm; + ret = devm_drm_dev_init(dev, drm, &st7735r_driver); + if (ret) { + kfree(mipi); + return ret; + } + + drm_mode_config_init(drm); + mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(mipi->reset)) { DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n"); @@ -178,14 +190,31 @@ static int st7735r_probe(struct spi_device *spi) /* Cannot read from Adafruit 1.8" display via SPI */ mipi->read_commands = NULL; - ret = mipi_dbi_init(&spi->dev, mipi, &jd_t18003_t01_pipe_funcs, - &st7735r_driver, &jd_t18003_t01_mode, rotation); + ret = mipi_dbi_init(mipi, &jd_t18003_t01_pipe_funcs, &jd_t18003_t01_mode, rotation); if (ret) return ret; - spi_set_drvdata(spi, mipi->tinydrm.drm); + drm_mode_config_reset(drm); - return devm_tinydrm_register(&mipi->tinydrm); + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + drm_fbdev_generic_setup(drm, 32); + + return 0; +} + +static int st7735r_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; } static void st7735r_shutdown(struct spi_device *spi) @@ -201,6 +230,7 @@ static struct spi_driver st7735r_spi_driver = { }, .id_table = st7735r_id, .probe = st7735r_probe, + .remove = st7735r_remove, .shutdown = st7735r_shutdown, }; module_spi_driver(st7735r_spi_driver); diff --git a/include/drm/tinydrm/mipi-dbi.h b/include/drm/tinydrm/mipi-dbi.h index ad7e6bedab5f..301b2c34cd08 100644 --- a/include/drm/tinydrm/mipi-dbi.h +++ b/include/drm/tinydrm/mipi-dbi.h @@ -12,7 +12,9 @@ #ifndef __LINUX_MIPI_DBI_H #define __LINUX_MIPI_DBI_H -#include +#include +#include +#include struct drm_rect; struct spi_device; @@ -21,7 +23,6 @@ struct regulator; /** * struct mipi_dbi - MIPI DBI controller - * @tinydrm: tinydrm base * @spi: SPI device * @enabled: Pipeline is enabled * @cmdlock: Command lock @@ -39,7 +40,16 @@ struct regulator; * @regulator: power regulator (optional) */ struct mipi_dbi { - struct tinydrm_device tinydrm; + /** + * @drm: DRM device + */ + struct drm_device drm; + + /** + * @pipe: Display pipe structure + */ + struct drm_simple_display_pipe pipe; + struct spi_device *spi; bool enabled; struct mutex cmdlock; @@ -58,17 +68,15 @@ struct mipi_dbi { static inline struct mipi_dbi *drm_to_mipi_dbi(struct drm_device *drm) { - struct tinydrm_device *tdev = drm->dev_private; - - return container_of(tdev, struct mipi_dbi, tinydrm); + return container_of(drm, struct mipi_dbi, drm); } int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi, struct gpio_desc *dc); -int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi, - const struct drm_simple_display_pipe_funcs *pipe_funcs, - struct drm_driver *driver, +int mipi_dbi_init(struct mipi_dbi *mipi, + const struct drm_simple_display_pipe_funcs *funcs, const struct drm_display_mode *mode, unsigned int rotation); +void mipi_dbi_release(struct drm_device *drm); void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state); void mipi_dbi_enable_flush(struct mipi_dbi *mipi,