From patchwork Mon Jan 21 06:03:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lubomir Rintel X-Patchwork-Id: 10773409 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 911B8139A for ; Mon, 21 Jan 2019 09:20:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7EB5D29E26 for ; Mon, 21 Jan 2019 09:20:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7300829E29; Mon, 21 Jan 2019 09:20:38 +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 E627529E26 for ; Mon, 21 Jan 2019 09:20:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 51BF36E73C; Mon, 21 Jan 2019 09:20:24 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from shell.v3.sk (shell.v3.sk [90.176.6.54]) by gabe.freedesktop.org (Postfix) with ESMTPS id B0DCE6E0F4 for ; Mon, 21 Jan 2019 06:03:58 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by zimbra.v3.sk (Postfix) with ESMTP id E8824CAE29; Mon, 21 Jan 2019 07:03:56 +0100 (CET) Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 5IVA6vgqZbOq; Mon, 21 Jan 2019 07:03:53 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by zimbra.v3.sk (Postfix) with ESMTP id 07B01CAE2A; Mon, 21 Jan 2019 07:03:53 +0100 (CET) X-Virus-Scanned: amavisd-new at zimbra.v3.sk Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id xZYBKZF4kRF2; Mon, 21 Jan 2019 07:03:52 +0100 (CET) Received: from belphegor.brq.redhat.com (nat-pool-brq-t.redhat.com [213.175.37.10]) by zimbra.v3.sk (Postfix) with ESMTPSA id D1218CAE29; Mon, 21 Jan 2019 07:03:51 +0100 (CET) From: Lubomir Rintel To: Russell King Subject: [PATCH] drm/armada: add mmp2 support Date: Mon, 21 Jan 2019 07:03:49 +0100 Message-Id: <20190121060349.549797-1-lkundrak@v3.sk> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Mailman-Approved-At: Mon, 21 Jan 2019 09:20:23 +0000 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 Airlie , Lubomir Rintel , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Heavily based on the Armada 510 (Dove) support. Like with 510 support, this also just supports a single source clock -- the "Display 1" clock as generated by the APMU. This one was chosen because the OLPC XO 1.75 laptop uses it for its internal panel. If anyone uses this to drive a MIPI or HDMI encoder, they may want to extend this to choose a different source for the pixel clock -- it should be a reasonably straightforward thing to do. The data sheet is not available, but James Cameron of OLPC kindly provided some details about the LCD_SCLK_DIV register. Link: https://lists.freedesktop.org/archives/dri-devel/2018-December/201021.html Signed-off-by: Lubomir Rintel --- drivers/gpu/drm/armada/Makefile | 1 + drivers/gpu/drm/armada/armada_610.c | 93 ++++++++++++++++++++++++++++ drivers/gpu/drm/armada/armada_crtc.c | 4 ++ drivers/gpu/drm/armada/armada_drm.h | 1 + drivers/gpu/drm/armada/armada_hw.h | 10 +++ 5 files changed, 109 insertions(+) create mode 100644 drivers/gpu/drm/armada/armada_610.c diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile index 9bc3c3213724..5bbf86324cda 100644 --- a/drivers/gpu/drm/armada/Makefile +++ b/drivers/gpu/drm/armada/Makefile @@ -2,6 +2,7 @@ armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \ armada_gem.o armada_overlay.o armada_plane.o armada_trace.o armada-y += armada_510.o +armada-y += armada_610.o armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o obj-$(CONFIG_DRM_ARMADA) := armada.o diff --git a/drivers/gpu/drm/armada/armada_610.c b/drivers/gpu/drm/armada/armada_610.c new file mode 100644 index 000000000000..278b204038ea --- /dev/null +++ b/drivers/gpu/drm/armada/armada_610.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2012 Russell King + * Copyright (C) 2018,2019 Lubomir Rintel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Armada MMP2 variant support + */ +#include +#include +#include +#include "armada_crtc.h" +#include "armada_drm.h" +#include "armada_hw.h" + +static int armada610_crtc_init(struct armada_crtc *dcrtc, struct device *dev) +{ + struct clk *clk; + + clk = devm_clk_get(dev, "disp0"); + if (IS_ERR(clk)) + return PTR_ERR(clk) == -ENOENT ? -EPROBE_DEFER : PTR_ERR(clk); + + dcrtc->extclk[0] = clk; + + return 0; +} + +/* + * This gets called with sclk = NULL to test whether the mode is + * supportable, and again with sclk != NULL to set the clocks up for + * that. The former can return an error, but the latter is expected + * not to. + */ +static int armada610_crtc_compute_clock(struct armada_crtc *dcrtc, + const struct drm_display_mode *mode, uint32_t *sclk) +{ + struct clk *clk = dcrtc->extclk[0]; + uint32_t ret, rate, ref, div; + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + rate = mode->clock * 1000; + ref = clk_get_rate(clk); + div = DIV_ROUND_UP(ref, rate); + + if (div < 2) + return -EINVAL; + + if (dcrtc->clk != clk) { + ret = clk_prepare_enable(clk); + if (ret) + return ret; + dcrtc->clk = clk; + } + + if (sclk) { + *sclk = 0x00001000; /* No idea */ + *sclk |= 1 << 8; /* MIPI clock bypass */ + *sclk |= SCLK_610_DISP0; + *sclk |= div; + } + + return 0; +} + +static void armada610_crtc_disable(struct armada_crtc *dcrtc) +{ + if (!IS_ERR(dcrtc->clk)) { + clk_disable_unprepare(dcrtc->clk); + dcrtc->clk = ERR_PTR(-EINVAL); + } +} + +static void armada610_crtc_enable(struct armada_crtc *dcrtc, + const struct drm_display_mode *mode) +{ + if (IS_ERR(dcrtc->clk)) { + dcrtc->clk = dcrtc->extclk[0]; + WARN_ON(clk_prepare_enable(dcrtc->clk)); + } +} + +const struct armada_variant armada610_ops = { + .init = armada610_crtc_init, + .compute_clock = armada610_crtc_compute_clock, + .disable = armada610_crtc_disable, + .enable = armada610_crtc_enable, +}; diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index da9360688b55..927be8898eb7 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -884,6 +884,10 @@ static const struct of_device_id armada_lcd_of_match[] = { .compatible = "marvell,dove-lcd", .data = &armada510_ops, }, + { + .compatible = "marvell,mmp2-lcd", + .data = &armada610_ops, + }, {} }; MODULE_DEVICE_TABLE(of, armada_lcd_of_match); diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h index f09083ff15d3..7cbcf33d0304 100644 --- a/drivers/gpu/drm/armada/armada_drm.h +++ b/drivers/gpu/drm/armada/armada_drm.h @@ -52,6 +52,7 @@ struct armada_variant { /* Variant ops */ extern const struct armada_variant armada510_ops; +extern const struct armada_variant armada610_ops; struct armada_private { struct drm_device drm; diff --git a/drivers/gpu/drm/armada/armada_hw.h b/drivers/gpu/drm/armada/armada_hw.h index 277580b36758..df2ff77b9c07 100644 --- a/drivers/gpu/drm/armada/armada_hw.h +++ b/drivers/gpu/drm/armada/armada_hw.h @@ -205,6 +205,16 @@ enum { SCLK_510_FRAC_DIV_MASK = 0xfff << 16, SCLK_510_INT_DIV_MASK = 0xffff << 0, + /* Armada 610 */ + SCLK_610_AXI = 0x0 << 30, + SCLK_610_DISP0 = 0x1 << 30, /* LCD Display 1 */ + SCLK_610_DISP1 = 0x2 << 30, /* LCD Display 2 */ + SCLK_610_PLL = 0x3 << 30, /* HDMI PLL clock */ + SCLK_610_PANEL_CLK_DIS = 0x1 << 28, /* 1 = panel clock disabled */ + SCLK_610_FRAC_DIV_MASK = 0xfff << 16, + SCLK_610_MIPI_DIV_MASK = 0xf << 8, /* 0 = off, 1 = bypass, ... */ + SCLK_610_INT_DIV_MASK = 0xff << 0, + /* Armada 16x */ SCLK_16X_AHB = 0x0 << 28, SCLK_16X_PCLK = 0x1 << 28,