From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6A10C2BB86 for ; Tue, 14 Apr 2020 10:57:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A2443206D5 for ; Tue, 14 Apr 2020 10:57:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2438769AbgDNK52 (ORCPT ); Tue, 14 Apr 2020 06:57:28 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:54315 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2438355AbgDNKcK (ORCPT ); Tue, 14 Apr 2020 06:32:10 -0400 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jOIrN-0007BX-EI; Tue, 14 Apr 2020 12:32:05 +0200 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jOIrM-000189-Ta; Tue, 14 Apr 2020 12:32:04 +0200 From: Michael Tretter To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Cc: Rohit Visavalia , Michal Simek , Rob Herring , Dhaval Shah , kernel@pengutronix.de, Michael Tretter Subject: [PATCH v2 3/6] soc: xilinx: vcu: implement clock provider for output clocks Date: Tue, 14 Apr 2020 12:31:59 +0200 Message-Id: <20200414103202.4288-4-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200414103202.4288-1-m.tretter@pengutronix.de> References: <20200414103202.4288-1-m.tretter@pengutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: devicetree@vger.kernel.org Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The VCU System-Level Control uses an internal PLL to drive the core and MCU clock for the allegro encoder and decoder based on an external PL clock. In order be able to ensure that the clocks are enabled and to get their rate from other drivers, the module must implement a clock provider and register the clocks at the common clock framework. Other drivers are then able to access the clock via devicetree bindings. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: - unregister registered clocks when removing the driver --- drivers/soc/xilinx/Kconfig | 2 +- drivers/soc/xilinx/xlnx_vcu.c | 76 ++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/drivers/soc/xilinx/Kconfig b/drivers/soc/xilinx/Kconfig index 223f1f9d0922..331f124902e8 100644 --- a/drivers/soc/xilinx/Kconfig +++ b/drivers/soc/xilinx/Kconfig @@ -3,7 +3,7 @@ menu "Xilinx SoC drivers" config XILINX_VCU tristate "Xilinx VCU logicoreIP Init" - depends on HAS_IOMEM + depends on HAS_IOMEM && COMMON_CLK help Provides the driver to enable and disable the isolation between the processing system and programmable logic part by using the logicoreIP diff --git a/drivers/soc/xilinx/xlnx_vcu.c b/drivers/soc/xilinx/xlnx_vcu.c index dcd8e7824b06..f07a1361a2a8 100644 --- a/drivers/soc/xilinx/xlnx_vcu.c +++ b/drivers/soc/xilinx/xlnx_vcu.c @@ -7,6 +7,7 @@ * Contacts Dhaval Shah */ #include +#include #include #include #include @@ -14,6 +15,8 @@ #include #include +#include + /* Address map for different registers implemented in the VCU LogiCORE IP. */ #define VCU_ECODER_ENABLE 0x00 #define VCU_DECODER_ENABLE 0x04 @@ -108,7 +111,9 @@ struct xvcu_device { struct clk *aclk; void __iomem *logicore_reg_ba; void __iomem *vcu_slcr_ba; + struct clk_onecell_data clk_data; u32 coreclk; + u32 mcuclk; }; /** @@ -375,10 +380,10 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) } xvcu->coreclk = pll_clk / divisor_core; - mcuclk = pll_clk / divisor_mcu; + xvcu->mcuclk = pll_clk / divisor_mcu; dev_dbg(xvcu->dev, "Actual Ref clock freq is %uHz\n", refclk); dev_dbg(xvcu->dev, "Actual Core clock freq is %uHz\n", xvcu->coreclk); - dev_dbg(xvcu->dev, "Actual Mcu clock freq is %uHz\n", mcuclk); + dev_dbg(xvcu->dev, "Actual Mcu clock freq is %uHz\n", xvcu->mcuclk); vcu_pll_ctrl &= ~(VCU_PLL_CTRL_FBDIV_MASK << VCU_PLL_CTRL_FBDIV_SHIFT); vcu_pll_ctrl |= (found->fbdiv & VCU_PLL_CTRL_FBDIV_MASK) << @@ -485,6 +490,63 @@ static int xvcu_set_pll(struct xvcu_device *xvcu) return -ETIMEDOUT; } +static int xvcu_register_clock_provider(struct xvcu_device *xvcu) +{ + struct device *dev = xvcu->dev; + const char *parent_name = __clk_get_name(xvcu->pll_ref); + struct clk_onecell_data *data = &xvcu->clk_data; + struct clk **clks; + size_t num_clks = CLK_XVCU_MAX; + + clks = devm_kcalloc(dev, num_clks, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + data->clk_num = num_clks; + data->clks = clks; + + clks[CLK_XVCU_ENC_CORE] = + clk_register_fixed_rate(dev, "venc_core_clk", + parent_name, 0, xvcu->coreclk); + clks[CLK_XVCU_ENC_MCU] = + clk_register_fixed_rate(dev, "venc_mcu_clk", + parent_name, 0, xvcu->mcuclk); + clks[CLK_XVCU_DEC_CORE] = + clk_register_fixed_rate(dev, "vdec_core_clk", + parent_name, 0, xvcu->coreclk); + clks[CLK_XVCU_DEC_MCU] = + clk_register_fixed_rate(dev, "vdec_mcu_clk", + parent_name, 0, xvcu->mcuclk); + + return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); +} + +static void xvcu_unregister_clock_provider(struct xvcu_device *xvcu) +{ + struct device *dev = xvcu->dev; + struct clk_onecell_data *data = &xvcu->clk_data; + struct clk **clks = data->clks; + + of_clk_del_provider(dev->of_node); + + clk_unregister_fixed_rate(clks[CLK_XVCU_DEC_MCU]); + clk_unregister_fixed_rate(clks[CLK_XVCU_DEC_CORE]); + clk_unregister_fixed_rate(clks[CLK_XVCU_ENC_MCU]); + clk_unregister_fixed_rate(clks[CLK_XVCU_ENC_CORE]); +} + +static void xvcu_reset(struct xvcu_device *xvcu) +{ + if (!xvcu->reset_gpio) + return; + + gpiod_set_value(xvcu->reset_gpio, 0); + /* min 2 clock cycle of vcu pll_ref, slowest freq is 33.33KHz */ + usleep_range(60, 120); + gpiod_set_value(xvcu->reset_gpio, 1); + usleep_range(60, 120); +} + /** * xvcu_probe - Probe existence of the logicoreIP * and initialize PLL @@ -569,10 +631,18 @@ static int xvcu_probe(struct platform_device *pdev) goto error_pll_ref; } + ret = xvcu_register_clock_provider(xvcu); + if (ret) { + dev_err(&pdev->dev, "failed to register clock provider\n"); + goto error_clk_provider; + } + dev_set_drvdata(&pdev->dev, xvcu); return 0; +error_clk_provider: + xvcu_unregister_clock_provider(xvcu); error_pll_ref: clk_disable_unprepare(xvcu->pll_ref); error_aclk: @@ -596,6 +666,8 @@ static int xvcu_remove(struct platform_device *pdev) if (!xvcu) return -ENODEV; + xvcu_unregister_clock_provider(xvcu); + /* Add the the Gasket isolation and put the VCU in reset. */ xvcu_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0); -- 2.20.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD957C2BA19 for ; Tue, 14 Apr 2020 10:32:58 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5E73C20644 for ; Tue, 14 Apr 2020 10:32:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="rki6QdyU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5E73C20644 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=k4+qhzEsvSFyUWJg/Rw8a2VQqqWqaDKlaWXN2w8XvOM=; b=rki6QdyU2hskJu yi4Yd4fAyc3tHS+EalzaPFry1B2AGREPbZ48hDJAz712IXAYj1gfDNhnO0a4kUc+6gaca7jaVs5bP oG8SOulXBVO66U6YVH28BR6gj+iKMDfpc0Q79zsNB4kSWJSvUHVefLK2VLqlpdCM4TJdPi6o3lKd5 72+bm2SgvCTjdL6TXdI5LoaFr5JpEPEl8M+x8bNpK7KrHIOct1ElSk6H6SDcTNgvHQS3o3aPccXRO upPXIWB4dd4JvBnE07mGGWiLsnCWCIejGoRXixFCTqmimJAFFDIs+CoLRg2cL//9iaW3K8fJEP+Lp z460mUuGbvvCFYXgzE0g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jOIs9-0001Wj-8R; Tue, 14 Apr 2020 10:32:53 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jOIrP-0000s2-F9 for linux-arm-kernel@lists.infradead.org; Tue, 14 Apr 2020 10:32:10 +0000 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28] helo=dude02.lab.pengutronix.de) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jOIrN-0007BX-EI; Tue, 14 Apr 2020 12:32:05 +0200 Received: from mtr by dude02.lab.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1jOIrM-000189-Ta; Tue, 14 Apr 2020 12:32:04 +0200 From: Michael Tretter To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Subject: [PATCH v2 3/6] soc: xilinx: vcu: implement clock provider for output clocks Date: Tue, 14 Apr 2020 12:31:59 +0200 Message-Id: <20200414103202.4288-4-m.tretter@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200414103202.4288-1-m.tretter@pengutronix.de> References: <20200414103202.4288-1-m.tretter@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mtr@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200414_033207_579933_7FD45EDE X-CRM114-Status: GOOD ( 16.15 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dhaval Shah , Michael Tretter , Michal Simek , Rob Herring , kernel@pengutronix.de, Rohit Visavalia Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org The VCU System-Level Control uses an internal PLL to drive the core and MCU clock for the allegro encoder and decoder based on an external PL clock. In order be able to ensure that the clocks are enabled and to get their rate from other drivers, the module must implement a clock provider and register the clocks at the common clock framework. Other drivers are then able to access the clock via devicetree bindings. Signed-off-by: Michael Tretter --- Changelog: v1 -> v2: - unregister registered clocks when removing the driver --- drivers/soc/xilinx/Kconfig | 2 +- drivers/soc/xilinx/xlnx_vcu.c | 76 ++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/drivers/soc/xilinx/Kconfig b/drivers/soc/xilinx/Kconfig index 223f1f9d0922..331f124902e8 100644 --- a/drivers/soc/xilinx/Kconfig +++ b/drivers/soc/xilinx/Kconfig @@ -3,7 +3,7 @@ menu "Xilinx SoC drivers" config XILINX_VCU tristate "Xilinx VCU logicoreIP Init" - depends on HAS_IOMEM + depends on HAS_IOMEM && COMMON_CLK help Provides the driver to enable and disable the isolation between the processing system and programmable logic part by using the logicoreIP diff --git a/drivers/soc/xilinx/xlnx_vcu.c b/drivers/soc/xilinx/xlnx_vcu.c index dcd8e7824b06..f07a1361a2a8 100644 --- a/drivers/soc/xilinx/xlnx_vcu.c +++ b/drivers/soc/xilinx/xlnx_vcu.c @@ -7,6 +7,7 @@ * Contacts Dhaval Shah */ #include +#include #include #include #include @@ -14,6 +15,8 @@ #include #include +#include + /* Address map for different registers implemented in the VCU LogiCORE IP. */ #define VCU_ECODER_ENABLE 0x00 #define VCU_DECODER_ENABLE 0x04 @@ -108,7 +111,9 @@ struct xvcu_device { struct clk *aclk; void __iomem *logicore_reg_ba; void __iomem *vcu_slcr_ba; + struct clk_onecell_data clk_data; u32 coreclk; + u32 mcuclk; }; /** @@ -375,10 +380,10 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) } xvcu->coreclk = pll_clk / divisor_core; - mcuclk = pll_clk / divisor_mcu; + xvcu->mcuclk = pll_clk / divisor_mcu; dev_dbg(xvcu->dev, "Actual Ref clock freq is %uHz\n", refclk); dev_dbg(xvcu->dev, "Actual Core clock freq is %uHz\n", xvcu->coreclk); - dev_dbg(xvcu->dev, "Actual Mcu clock freq is %uHz\n", mcuclk); + dev_dbg(xvcu->dev, "Actual Mcu clock freq is %uHz\n", xvcu->mcuclk); vcu_pll_ctrl &= ~(VCU_PLL_CTRL_FBDIV_MASK << VCU_PLL_CTRL_FBDIV_SHIFT); vcu_pll_ctrl |= (found->fbdiv & VCU_PLL_CTRL_FBDIV_MASK) << @@ -485,6 +490,63 @@ static int xvcu_set_pll(struct xvcu_device *xvcu) return -ETIMEDOUT; } +static int xvcu_register_clock_provider(struct xvcu_device *xvcu) +{ + struct device *dev = xvcu->dev; + const char *parent_name = __clk_get_name(xvcu->pll_ref); + struct clk_onecell_data *data = &xvcu->clk_data; + struct clk **clks; + size_t num_clks = CLK_XVCU_MAX; + + clks = devm_kcalloc(dev, num_clks, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + data->clk_num = num_clks; + data->clks = clks; + + clks[CLK_XVCU_ENC_CORE] = + clk_register_fixed_rate(dev, "venc_core_clk", + parent_name, 0, xvcu->coreclk); + clks[CLK_XVCU_ENC_MCU] = + clk_register_fixed_rate(dev, "venc_mcu_clk", + parent_name, 0, xvcu->mcuclk); + clks[CLK_XVCU_DEC_CORE] = + clk_register_fixed_rate(dev, "vdec_core_clk", + parent_name, 0, xvcu->coreclk); + clks[CLK_XVCU_DEC_MCU] = + clk_register_fixed_rate(dev, "vdec_mcu_clk", + parent_name, 0, xvcu->mcuclk); + + return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); +} + +static void xvcu_unregister_clock_provider(struct xvcu_device *xvcu) +{ + struct device *dev = xvcu->dev; + struct clk_onecell_data *data = &xvcu->clk_data; + struct clk **clks = data->clks; + + of_clk_del_provider(dev->of_node); + + clk_unregister_fixed_rate(clks[CLK_XVCU_DEC_MCU]); + clk_unregister_fixed_rate(clks[CLK_XVCU_DEC_CORE]); + clk_unregister_fixed_rate(clks[CLK_XVCU_ENC_MCU]); + clk_unregister_fixed_rate(clks[CLK_XVCU_ENC_CORE]); +} + +static void xvcu_reset(struct xvcu_device *xvcu) +{ + if (!xvcu->reset_gpio) + return; + + gpiod_set_value(xvcu->reset_gpio, 0); + /* min 2 clock cycle of vcu pll_ref, slowest freq is 33.33KHz */ + usleep_range(60, 120); + gpiod_set_value(xvcu->reset_gpio, 1); + usleep_range(60, 120); +} + /** * xvcu_probe - Probe existence of the logicoreIP * and initialize PLL @@ -569,10 +631,18 @@ static int xvcu_probe(struct platform_device *pdev) goto error_pll_ref; } + ret = xvcu_register_clock_provider(xvcu); + if (ret) { + dev_err(&pdev->dev, "failed to register clock provider\n"); + goto error_clk_provider; + } + dev_set_drvdata(&pdev->dev, xvcu); return 0; +error_clk_provider: + xvcu_unregister_clock_provider(xvcu); error_pll_ref: clk_disable_unprepare(xvcu->pll_ref); error_aclk: @@ -596,6 +666,8 @@ static int xvcu_remove(struct platform_device *pdev) if (!xvcu) return -ENODEV; + xvcu_unregister_clock_provider(xvcu); + /* Add the the Gasket isolation and put the VCU in reset. */ xvcu_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0); -- 2.20.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel