From patchwork Mon Oct 8 10:58:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 148354 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp3490263lji; Mon, 8 Oct 2018 03:59:32 -0700 (PDT) X-Google-Smtp-Source: ACcGV62Cyf65Y9pVoe3v25wbJ5VaZ9ZGsEg5WwPK5wbwS94CmrUPssETk4c+XVyao/t6e9yYaK1s X-Received: by 2002:a62:1655:: with SMTP id 82-v6mr24261244pfw.11.1538996372753; Mon, 08 Oct 2018 03:59:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538996372; cv=none; d=google.com; s=arc-20160816; b=EZhDPnKUykMWcFt+iR8YH5BeRYjLGqcUXjNKqDwXpgpP5mGPr2ui6fNl+Ojbez7gap 31K42Ecj2K8QcNu8wDcksHDpV3VNv/A4RNHTuGjpr5WHrDk+A7hwxOMkqV8mbDXU3ix1 0raK70KDa/KwBTZKu0hZrURqsCrWx/PujH1p8B2g55yrN3l3EO0PB1/yM6Z5z0ijU/u+ lYOCeFRjx68EBFG7mqAAQu6JZT5vvZ/k9dnFoPYJT5VE3+LIV0GUp7Rb7583iYAVnQHi 8j6tkyOngJ+MkHNNQ3qcDf9cXpQrRL5NKL3O7w7McL4fIDrc3IXpy8avg12uDc1SO1+P nZSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:delivered-to; bh=U88yxVlattad5e4rejoHyI3n0l7wrr6LtTQVP2fwGVU=; b=z9Z6l/RSS1Qgb/Vomjv7qyPrCM7aX+QCY8ElNZAtckchCI91/QNRzu/Y6I/GqnyOvw 7yqU5rTBQgHDesDXpbF0XaK0NQUXyINYjrTMOK1oQMexqMMgqQaqL3Gfc9IQM2aup7yv GXaiwlzGe2hhYv/gMhBIVfTDVxC8d2AyJipuCrcQ0/brJLnveADy83mBThFQViiD6KoD yk4HvwCby4H7nm0I36X2kSkRFNNLHLz60d898qaYpTe8fMHGK4v3AYdNMxlVg5LD4SQm HEjB0wwne9m/KwCkWFFyjdUWIiOGB/MMUXVJQe/OKKC4iIXAw6P9siL2ZyhZOLVFH6vd v48Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id 8-v6si16518191pgu.519.2018.10.08.03.59.32 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 08 Oct 2018 03:59:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B3DBC6E118; Mon, 8 Oct 2018 10:59:01 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lj1-x244.google.com (mail-lj1-x244.google.com [IPv6:2a00:1450:4864:20::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id E103A6E117 for ; Mon, 8 Oct 2018 10:58:59 +0000 (UTC) Received: by mail-lj1-x244.google.com with SMTP id z21-v6so17443334ljz.0 for ; Mon, 08 Oct 2018 03:58:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WgeYy6QNh0PYq1t6X2xijggZzgWWfBAJfnDwXshLRj0=; b=EkkgZsADld73CcpCFBqL7gkl4dOf/Cnk+3SUAiNdljY3c8GRWehq44MwIthjyopusF zySRReZbhQnAVe479PNK3zvUAABrLLMwmte8jpJ9XDvbAhXey49qi6kmbLAb3N+m0RXS lwZleSd5/9P+jtxou7k+YBDT2ByER551oJOjpOjdfgSWtCOxFwKZiBGv86THVam746rk avCG+PLJboY8bjgwIc1Eubls3X+xVsuQPcTDzGagazYegpKCMBpAnrTY2JZKQsXEnQIV D+dESa7n2U446ZsylNOQA9d9TNaCnkA2ax1EQau23g1GCSJZD/sY6G94ALpP38VwhBlr HgDg== X-Gm-Message-State: ABuFfogz4sxH4HJDnfy4j3LYXU/QjqCh+eQ2N3Ab5m4BGAwF3wxvirzp SU2E0EtybEhxK1HcRPc4u9eJzOd1pdw= X-Received: by 2002:a2e:3918:: with SMTP id g24-v6mr17017lja.113.1538996338090; Mon, 08 Oct 2018 03:58:58 -0700 (PDT) Received: from genomnajs.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id h4-v6sm3372586lfj.69.2018.10.08.03.58.56 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 08 Oct 2018 03:58:57 -0700 (PDT) From: Linus Walleij To: Thierry Reding , dri-devel@lists.freedesktop.org Subject: [PATCH 2/2] drm/panel: Add driver for Samsung S6D16D0 panel Date: Mon, 8 Oct 2018 12:58:52 +0200 Message-Id: <20181008105852.24196-2-linus.walleij@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181008105852.24196-1-linus.walleij@linaro.org> References: <20181008105852.24196-1-linus.walleij@linaro.org> 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: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The Samsung S6D16D0 is a simple comman mode only DSI display that is used on the ST-Ericsson Ux500 reference design TVK1281618 user interface board (UIB). Signed-off-by: Linus Walleij --- drivers/gpu/drm/panel/Kconfig | 7 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-samsung-s6d16d0.c | 235 ++++++++++++++++++ 3 files changed, 243 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6d16d0.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 6020c30a33b3..2aacffee7a86 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -126,6 +126,13 @@ config DRM_PANEL_RAYDIUM_RM68200 Say Y here if you want to enable support for Raydium RM68200 720x1280 DSI video mode panel. +config DRM_PANEL_SAMSUNG_S6D16D0 + tristate "Samsung S6D16D0 DSI video mode panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + config DRM_PANEL_SAMSUNG_S6E3HA2 tristate "Samsung S6E3HA2 DSI video mode panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 5ccaaa9d13af..b52e5c5804ca 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c b/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c new file mode 100644 index 000000000000..da93484ee22f --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * MIPI-DSI Samsung s6d16d0 panel driver. This is a 864x480 + * AMOLED panel with a command-only DSI interface. + */ + +#include +#include +#include + +#include +#include + +struct s6d16d0 { + struct device *dev; + struct drm_panel panel; + struct regulator *supply; + struct gpio_desc *reset_gpio; +}; + +/* + * The timings are not very helpful as the display is used in + * command mode. + */ +static const struct drm_display_mode samsung_s6d16d0_mode = { + .clock = 420160, /* HS 420160kHz, LP 19200kHz */ + .hdisplay = 864, + .hsync_start = 864 + 154, + .hsync_end = 864 + 154 + 16, + .htotal = 864 + 154 + 16 + 32, + .vdisplay = 480, + .vsync_start = 480 + 1, + .vsync_end = 480 + 1 + 1, + .vtotal = 480 + 1 + 1 + 1, + .vrefresh = 60, +}; + +static inline struct s6d16d0 *panel_to_s6d16d0(struct drm_panel *panel) +{ + return container_of(panel, struct s6d16d0, panel); +} + +static int s6d16d0_unprepare(struct drm_panel *panel) +{ + struct s6d16d0 *s6 = panel_to_s6d16d0(panel); + struct mipi_dsi_device *dsi = to_mipi_dsi_device(s6->dev); + int ret; + + /* Exit sleep mode and power on */ + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret) { + dev_err(s6->dev, "failed to turn display off\n"); + return ret; + } + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret) { + dev_err(s6->dev, "failed to enter sleep mode\n"); + return ret; + } + + /* Assert RESET */ + gpiod_set_value_cansleep(s6->reset_gpio, 1); + regulator_disable(s6->supply); + + return 0; +} + +static int s6d16d0_prepare(struct drm_panel *panel) +{ + struct s6d16d0 *s6 = panel_to_s6d16d0(panel); + struct mipi_dsi_device *dsi = to_mipi_dsi_device(s6->dev); + int ret; + + ret = regulator_enable(s6->supply); + if (ret) { + dev_err(s6->dev, "failed to enable supply: %d\n", ret); + return ret; + } + + /* Assert RESET */ + gpiod_set_value_cansleep(s6->reset_gpio, 1); + udelay(10); + /* De-assert RESET */ + gpiod_set_value_cansleep(s6->reset_gpio, 0); + msleep(120); + + /* Enabe tearing mode: send TE (tearing effect) at VBLANK */ + ret = mipi_dsi_dcs_set_tear_on(dsi, + MIPI_DSI_DCS_TEAR_MODE_VBLANK); + if (ret) { + dev_err(s6->dev, "failed to enble vblank TE\n"); + return ret; + } + /* Exit sleep mode and power on */ + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret) { + dev_err(s6->dev, "failed to exit sleep mode\n"); + return ret; + } + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret) { + dev_err(s6->dev, "failed to turn display on\n"); + return ret; + } + + return 0; +} + +static int s6d16d0_enable(struct drm_panel *panel) +{ + return 0; +} + +static int s6d16d0_disable(struct drm_panel *panel) +{ + return 0; +} + +static int s6d16d0_get_modes(struct drm_panel *panel) +{ + struct drm_connector *connector = panel->connector; + struct drm_display_mode *mode; + + strncpy(connector->display_info.name, "Samsung S6D16D0\0", + DRM_DISPLAY_INFO_LEN); + + mode = drm_mode_duplicate(panel->drm, &samsung_s6d16d0_mode); + if (!mode) { + DRM_ERROR("bad mode or failed to add mode\n"); + return -EINVAL; + } + drm_mode_set_name(mode); + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + + mode->width_mm = 84; + mode->height_mm = 48; + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; + + drm_mode_probed_add(connector, mode); + + return 1; /* Number of modes */ +} + +static const struct drm_panel_funcs s6d16d0_drm_funcs = { + .disable = s6d16d0_disable, + .unprepare = s6d16d0_unprepare, + .prepare = s6d16d0_prepare, + .enable = s6d16d0_enable, + .get_modes = s6d16d0_get_modes, +}; + +static int s6d16d0_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct s6d16d0 *s6; + int ret; + + s6 = devm_kzalloc(dev, sizeof(struct s6d16d0), GFP_KERNEL); + if (!s6) + return -ENOMEM; + mipi_dsi_set_drvdata(dsi, s6); + s6->dev = dev; + + dsi->lanes = 2; + dsi->format = MIPI_DSI_FMT_RGB888; + /* + * This display uses command mode so no MIPI_DSI_MODE_VIDEO + * or MIPI_DSI_MODE_VIDEO_SYNC_PULSE + * + * As we only send commands we do not need to be continously + * clocked. + */ + dsi->mode_flags = + MIPI_DSI_CLOCK_NON_CONTINUOUS | + MIPI_DSI_MODE_EOT_PACKET; + + s6->supply = devm_regulator_get(dev, "vdd1"); + if (IS_ERR(s6->supply)) + return PTR_ERR(s6->supply); + + /* This asserts RESET by default */ + s6->reset_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(s6->reset_gpio)) { + ret = PTR_ERR(s6->reset_gpio); + if (ret != -EPROBE_DEFER) + dev_err(dev, "failed to request GPIO: %d\n", ret); + return ret; + } + + drm_panel_init(&s6->panel); + s6->panel.dev = dev; + s6->panel.funcs = &s6d16d0_drm_funcs; + + ret = drm_panel_add(&s6->panel); + if (ret < 0) + return ret; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) + drm_panel_remove(&s6->panel); + + return ret; +} + +static int s6d16d0_remove(struct mipi_dsi_device *dsi) +{ + struct s6d16d0 *s6 = mipi_dsi_get_drvdata(dsi); + + mipi_dsi_detach(dsi); + drm_panel_remove(&s6->panel); + + return 0; +} + +static const struct of_device_id s6d16d0_of_match[] = { + { .compatible = "samsung,s6d16d0" }, + { } +}; +MODULE_DEVICE_TABLE(of, s6d16d0_of_match); + +static struct mipi_dsi_driver s6d16d0_driver = { + .probe = s6d16d0_probe, + .remove = s6d16d0_remove, + .driver = { + .name = "panel-samsung-s6d16d0", + .of_match_table = s6d16d0_of_match, + }, +}; +module_mipi_dsi_driver(s6d16d0_driver); + +MODULE_AUTHOR("Linus Wallei "); +MODULE_DESCRIPTION("MIPI-DSI s6d16d0 Panel Driver"); +MODULE_LICENSE("GPL v2");