From patchwork Tue Oct 4 16:23:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 9362065 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 57280607D6 for ; Tue, 4 Oct 2016 16:23:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 497A528B65 for ; Tue, 4 Oct 2016 16:23:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3DE6728B69; Tue, 4 Oct 2016 16:23:47 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID 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 D0D6A28B65 for ; Tue, 4 Oct 2016 16:23:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 659A26E6DA; Tue, 4 Oct 2016 16:23:41 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from galahad.ideasonboard.com (galahad.ideasonboard.com [185.26.127.97]) by gabe.freedesktop.org (Postfix) with ESMTPS id 27E6E6E6DA for ; Tue, 4 Oct 2016 16:23:39 +0000 (UTC) Received: from avalon.ideasonboard.com (unknown [90.63.244.31]) by galahad.ideasonboard.com (Postfix) with ESMTPSA id 4C1CA207B1; Tue, 4 Oct 2016 18:22:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1475598175; bh=J6/SGy1zSRTAmAnSWM0RRupmY4dgPmWgpoZhOx9bEhY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EaCOaZffZDW6DYNSvH4NGPEIadOo1OaGAEtW4IY3RWHB5kR66cQ7l/L6edwFz084U sW3pQ6AFsvEHuT6aGs9woz3zRNJVxctAsmwWr7Tdccod/TUKusPErSyi07XptTE+GT 7eqR/ojFbykBo5j0DFWHJEIPIOZ6P4u4ttnnDX8o= From: Laurent Pinchart To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/2] drm: rcar-du: Add support for LVDS mode selection Date: Tue, 4 Oct 2016 19:23:30 +0300 Message-Id: <1475598210-26857-3-git-send-email-laurent.pinchart+renesas@ideasonboard.com> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1475598210-26857-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com> References: <1475598210-26857-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com> Cc: devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Tomi Valkeinen , linux-media@vger.kernel.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 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" X-Virus-Scanned: ClamAV using ClamSMTP Retrieve the LVDS mode from the panel node and configure the LVDS encoder accordingly. LVDS mode selection is static as LVDS panels can't be hot-plugged on any of the device supported by the driver. Support for dynamic mode selection can be implemented in the future if needed without any impact on the DT bindings. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c | 29 +++++++++++++++++++++++++++++ drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c | 11 +++++++++-- drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h | 13 +++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c index 64e9f0b86e58..71a70b06f16b 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c @@ -24,6 +24,7 @@ #include "rcar_du_encoder.h" #include "rcar_du_kms.h" #include "rcar_du_lvdscon.h" +#include "rcar_du_lvdsenc.h" struct rcar_du_lvds_connector { struct rcar_du_connector connector; @@ -33,6 +34,8 @@ struct rcar_du_lvds_connector { unsigned int height_mm; /* Panel height in mm */ struct videomode mode; } panel; + + unsigned int mode; }; #define to_rcar_lvds_connector(c) \ @@ -100,6 +103,32 @@ int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, of_property_read_u32(np, "width-mm", &lvdscon->panel.width_mm); of_property_read_u32(np, "height-mm", &lvdscon->panel.height_mm); + if (of_device_is_compatible(np, "panel-lvds")) { + enum rcar_lvds_mode mode = 0; + const char *mapping = NULL; + + of_property_read_string(np, "data-mapping", &mapping); + if (!mapping) { + dev_dbg(rcdu->dev, + "required property %s not found in %s node\n", + "data-mapping", np->full_name); + return -EINVAL; + } + + if (!strcmp(mapping, "jeida-18") || + !strcmp(mapping, "jeida-24")) + mode = RCAR_LVDS_MODE_JEIDA; + else if (!strcmp(mapping, "vesa-24")) + mode = RCAR_LVDS_MODE_VESA; + else + return -EINVAL; + + if (of_find_property(np, "data-mirror", NULL)) + mode |= RCAR_LVDS_MODE_MIRROR; + + rcar_du_lvdsenc_set_mode(renc->lvds, mode); + } + connector = &lvdscon->connector.connector; connector->display_info.width_mm = lvdscon->panel.width_mm; connector->display_info.height_mm = lvdscon->panel.height_mm; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c index b74105a80a6e..c8c22850947a 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c @@ -31,6 +31,7 @@ struct rcar_du_lvdsenc { bool enabled; enum rcar_lvds_input input; + enum rcar_lvds_mode mode; }; static void rcar_lvds_write(struct rcar_du_lvdsenc *lvds, u32 reg, u32 data) @@ -61,7 +62,7 @@ static void rcar_du_lvdsenc_start_gen2(struct rcar_du_lvdsenc *lvds, /* Select the input, hardcode mode 0, enable LVDS operation and turn * bias circuitry on. */ - lvdcr0 = LVDCR0_BEN | LVDCR0_LVEN; + lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_BEN | LVDCR0_LVEN; if (rcrtc->index == 2) lvdcr0 |= LVDCR0_DUSEL; rcar_lvds_write(lvds, LVDCR0, lvdcr0); @@ -107,7 +108,7 @@ static void rcar_du_lvdsenc_start_gen3(struct rcar_du_lvdsenc *lvds, /* Turn the PLL on, set it to LVDS normal mode, wait for the startup * delay and turn the output on. */ - lvdcr0 = LVDCR0_PLLON; + lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_PLLON; rcar_lvds_write(lvds, LVDCR0, lvdcr0); lvdcr0 |= LVDCR0_PWD; @@ -210,6 +211,12 @@ void rcar_du_lvdsenc_atomic_check(struct rcar_du_lvdsenc *lvds, mode->clock = clamp(mode->clock, 25175, 148500); } +void rcar_du_lvdsenc_set_mode(struct rcar_du_lvdsenc *lvds, + enum rcar_lvds_mode mode) +{ + lvds->mode = mode; +} + static int rcar_du_lvdsenc_get_resources(struct rcar_du_lvdsenc *lvds, struct platform_device *pdev) { diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h index dfdba746edf4..7218ac89333e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h @@ -26,8 +26,17 @@ enum rcar_lvds_input { RCAR_LVDS_INPUT_DU2, }; +/* Keep in sync with the LVDCR0.LVMD hardware register values. */ +enum rcar_lvds_mode { + RCAR_LVDS_MODE_JEIDA = 0, + RCAR_LVDS_MODE_MIRROR = 1, + RCAR_LVDS_MODE_VESA = 4, +}; + #if IS_ENABLED(CONFIG_DRM_RCAR_LVDS) int rcar_du_lvdsenc_init(struct rcar_du_device *rcdu); +void rcar_du_lvdsenc_set_mode(struct rcar_du_lvdsenc *lvds, + enum rcar_lvds_mode mode); int rcar_du_lvdsenc_enable(struct rcar_du_lvdsenc *lvds, struct drm_crtc *crtc, bool enable); void rcar_du_lvdsenc_atomic_check(struct rcar_du_lvdsenc *lvds, @@ -37,6 +46,10 @@ static inline int rcar_du_lvdsenc_init(struct rcar_du_device *rcdu) { return 0; } +static inline void rcar_du_lvdsenc_set_mode(struct rcar_du_lvdsenc *lvds, + enum rcar_lvds_mode mode) +{ +} static inline int rcar_du_lvdsenc_enable(struct rcar_du_lvdsenc *lvds, struct drm_crtc *crtc, bool enable) {