From patchwork Sun Jan 20 11:43:15 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: 10772369 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 866D16C2 for ; Sun, 20 Jan 2019 11:43:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 74F0E287DC for ; Sun, 20 Jan 2019 11:43:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 68F92288C5; Sun, 20 Jan 2019 11:43:51 +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 4A8E1287DC for ; Sun, 20 Jan 2019 11:43:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5B4C16E5F5; Sun, 20 Jan 2019 11:43:40 +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 3A7A36E5F2 for ; Sun, 20 Jan 2019 11:43:32 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:41476 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 1glBVi-0000O0-EB; Sun, 20 Jan 2019 12:43:30 +0100 From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [PATCH 08/11] drm/tinydrm: Use devm_drm_dev_*() Date: Sun, 20 Jan 2019 12:43:15 +0100 Message-Id: <20190120114318.49199-9-noralf@tronnes.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190120114318.49199-1-noralf@tronnes.org> References: <20190120114318.49199-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: 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(), devm_drm_dev_register_with_fbdev() and drop using tinydrm_device. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/tinydrm/hx8357d.c | 25 +++++-- drivers/gpu/drm/tinydrm/ili9225.c | 25 +++++-- drivers/gpu/drm/tinydrm/ili9341.c | 25 +++++-- drivers/gpu/drm/tinydrm/mi0283qt.c | 25 +++++-- drivers/gpu/drm/tinydrm/mipi-dbi.c | 69 +++++++++++--------- drivers/gpu/drm/tinydrm/st7586.c | 101 ++++++++++++++--------------- drivers/gpu/drm/tinydrm/st7735r.c | 25 +++++-- include/drm/tinydrm/mipi-dbi.h | 26 +++++--- 8 files changed, 206 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/tinydrm/hx8357d.c b/drivers/gpu/drm/tinydrm/hx8357d.c index 84dda622df85..4648bd6d6282 100644 --- a/drivers/gpu/drm/tinydrm/hx8357d.c +++ b/drivers/gpu/drm/tinydrm/hx8357d.c @@ -189,6 +189,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 +214,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->base; + 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 +249,18 @@ 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); + spi_set_drvdata(spi, drm); + + DRM_DEBUG_DRIVER("SPI speed: %uMHz, rotation = %u\n", + spi->max_speed_hz / 1000000, rotation); + + return devm_drm_dev_register_with_fbdev(drm, 0); } static void hx8357d_shutdown(struct spi_device *spi) diff --git a/drivers/gpu/drm/tinydrm/ili9225.c b/drivers/gpu/drm/tinydrm/ili9225.c index 3f59cfbd31ba..20a44a43a64a 100644 --- a/drivers/gpu/drm/tinydrm/ili9225.c +++ b/drivers/gpu/drm/tinydrm/ili9225.c @@ -339,6 +339,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 +363,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->base; + 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 +403,18 @@ 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); + spi_set_drvdata(spi, drm); + + DRM_DEBUG_DRIVER("SPI speed: %uMHz, rotation = %u\n", + spi->max_speed_hz / 1000000, rotation); + + return devm_drm_dev_register_with_fbdev(drm, 0); } static void ili9225_shutdown(struct spi_device *spi) diff --git a/drivers/gpu/drm/tinydrm/ili9341.c b/drivers/gpu/drm/tinydrm/ili9341.c index 3b7565a6311e..5ab3267b224a 100644 --- a/drivers/gpu/drm/tinydrm/ili9341.c +++ b/drivers/gpu/drm/tinydrm/ili9341.c @@ -145,6 +145,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 +170,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->base; + 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 +211,18 @@ 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); + spi_set_drvdata(spi, drm); + + DRM_DEBUG_DRIVER("SPI speed: %uMHz, rotation = %u\n", + spi->max_speed_hz / 1000000, rotation); + + return devm_drm_dev_register_with_fbdev(drm, 0); } static void ili9341_shutdown(struct spi_device *spi) diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c index da326fd1450d..bb0ce4514e60 100644 --- a/drivers/gpu/drm/tinydrm/mi0283qt.c +++ b/drivers/gpu/drm/tinydrm/mi0283qt.c @@ -154,6 +154,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 +179,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->base; + 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 +224,18 @@ 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); + spi_set_drvdata(spi, drm); + + DRM_DEBUG_DRIVER("SPI speed: %uMHz, rotation = %u\n", + spi->max_speed_hz / 1000000, rotation); + + return devm_drm_dev_register_with_fbdev(drm, 0); } static void mi0283qt_shutdown(struct spi_device *spi) diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c index 3c66a844fe56..861e04815104 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->base; 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,33 +370,28 @@ 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->base; struct drm_connector *connector; - struct drm_device *drm; int ret; static const uint64_t modifiers[] = { DRM_FORMAT_MOD_LINEAR, @@ -402,41 +403,51 @@ 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; - - drm = tdev->drm; - connector = drm_simple_connector_create(drm, DRM_MODE_CONNECTOR_VIRTUAL, mode, rotation); if (IS_ERR(connector)) return PTR_ERR(connector); - ret = drm_simple_display_pipe_init(drm, &tdev->pipe, pipe_funcs, + ret = drm_simple_display_pipe_init(drm, &mipi->pipe, funcs, mipi_dbi_formats, ARRAY_SIZE(mipi_dbi_formats), modifiers, connector); if (ret) return ret; - drm_plane_enable_fb_damage_clips(&tdev->pipe.plane); + drm_plane_enable_fb_damage_clips(&mipi->pipe.plane); + drm->mode_config.funcs = &mipi_dbi_mode_config_funcs; drm_simple_connector_set_mode_config(connector); 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); - 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 @@ -489,7 +500,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->base.dev; int ret; if (mipi->regulator) { diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c index 99be557cc973..cae003318b42 100644 --- a/drivers/gpu/drm/tinydrm/st7586.c +++ b/drivers/gpu/drm/tinydrm/st7586.c @@ -262,53 +262,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; - struct drm_connector *connector; - struct drm_device *drm; - 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; - - drm = tdev->drm; - - connector = drm_simple_connector_create(drm, DRM_MODE_CONNECTOR_VIRTUAL, mode, rotation); - if (IS_ERR(connector)) - return PTR_ERR(connector); - - ret = drm_simple_display_pipe_init(drm, &tdev->pipe, pipe_funcs, - st7586_formats, ARRAY_SIZE(st7586_formats), - NULL, connector); - if (ret) - return ret; - - drm_plane_enable_fb_damage_clips(&tdev->pipe.plane); - - drm_simple_connector_set_mode_config(connector); - 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, @@ -316,6 +269,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), }; @@ -326,6 +285,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", @@ -349,16 +309,37 @@ MODULE_DEVICE_TABLE(spi, st7586_id); static int st7586_probe(struct spi_device *spi) { + struct drm_connector *connector; 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->base; + 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"); @@ -372,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) @@ -389,14 +371,29 @@ 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); + connector = drm_simple_connector_create(drm, DRM_MODE_CONNECTOR_VIRTUAL, + &st7586_mode, rotation); + if (IS_ERR(connector)) + return PTR_ERR(connector); + + ret = drm_simple_display_pipe_init(drm, &mipi->pipe, &st7586_pipe_funcs, + st7586_formats, ARRAY_SIZE(st7586_formats), + NULL, connector); 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_simple_connector_set_mode_config(connector); + + drm_mode_config_reset(drm); + + spi_set_drvdata(spi, drm); + + DRM_DEBUG_DRIVER("SPI speed: %uMHz, rotation = %u\n", + spi->max_speed_hz / 1000000, rotation); + + return devm_drm_dev_register_with_fbdev(drm, 0); } static void st7586_shutdown(struct spi_device *spi) diff --git a/drivers/gpu/drm/tinydrm/st7735r.c b/drivers/gpu/drm/tinydrm/st7735r.c index bfa7e2221540..dcd07248884c 100644 --- a/drivers/gpu/drm/tinydrm/st7735r.c +++ b/drivers/gpu/drm/tinydrm/st7735r.c @@ -120,6 +120,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 +145,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->base; + 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 +189,18 @@ 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); + spi_set_drvdata(spi, drm); + + DRM_DEBUG_DRIVER("SPI speed: %uMHz, rotation = %u\n", + spi->max_speed_hz / 1000000, rotation); + + return devm_drm_dev_register_with_fbdev(drm, 0); } static void st7735r_shutdown(struct spi_device *spi) diff --git a/include/drm/tinydrm/mipi-dbi.h b/include/drm/tinydrm/mipi-dbi.h index ad7e6bedab5f..a678391e4cb1 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; + /** + * @base: DRM device + */ + struct drm_device base; + + /** + * @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, base); } 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,