From patchwork Mon Feb 26 12:53:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 10242183 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 5AFCA602DC for ; Mon, 26 Feb 2018 12:54:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4B57929FCD for ; Mon, 26 Feb 2018 12:54:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4064029FD3; Mon, 26 Feb 2018 12:54:13 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8B06929FCD for ; Mon, 26 Feb 2018 12:54:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752664AbeBZMyM (ORCPT ); Mon, 26 Feb 2018 07:54:12 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:39384 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752451AbeBZMyH (ORCPT ); Mon, 26 Feb 2018 07:54:07 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20180226125405euoutp01f0b83cc5152c32e7e408018db77b7105~W4U0ImUgy1566615666euoutp01M; Mon, 26 Feb 2018 12:54:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20180226125405euoutp01f0b83cc5152c32e7e408018db77b7105~W4U0ImUgy1566615666euoutp01M DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1519649645; bh=8NKUt4YdaPbxjrfEAty884Sf/aop/Nij/qE257W+mJg=; h=From:To:Cc:Subject:Date:In-reply-to:References:From; b=bB2v2dGJZy18HjKmELdwKz8+ietdsSuxq1IlWVNrhpB4Gr+dA4GFgRGwr9sfdxxxX jRu7zsyGAcpQjg82Q7D8TutJRnF2W+ITTIsZUuOGWCUldV2o6Dgh4aNc2umCwDPSwa 87GAeVi06G2VRasmbxwoBIF0RiOOICHXGqFbouW0= Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20180226125404eucas1p2a7acc54b75ddb57c947d866bcd319f24~W4UzHBbRK0420404204eucas1p2Q; Mon, 26 Feb 2018 12:54:04 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id 55.78.10409.B63049A5; Mon, 26 Feb 2018 12:54:03 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20180226125402eucas1p1ac3e0a5853218cd77f469864f70ae89d~W4UxmDfhH0324403244eucas1p1E; Mon, 26 Feb 2018 12:54:02 +0000 (GMT) X-AuditID: cbfec7f5-f95739c0000028a9-db-5a94036bf202 Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 23.9A.04178.A63049A5; Mon, 26 Feb 2018 12:54:02 +0000 (GMT) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P4R0055KD5X67D0@eusync3.samsung.com>; Mon, 26 Feb 2018 12:54:02 +0000 (GMT) From: Marek Szyprowski To: linux-clk@vger.kernel.org, linux-samsung-soc@vger.kernel.org Cc: Marek Szyprowski , Sylwester Nawrocki , Chanwoo Choi , Inki Dae , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz Subject: [PATCH v2 2/6] clk: samsung: Add Exynos5 sub-CMU clock driver Date: Mon, 26 Feb 2018 13:53:51 +0100 Message-id: <20180226125355.9052-3-m.szyprowski@samsung.com> X-Mailer: git-send-email 2.15.0 In-reply-to: <20180226125355.9052-1-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrIIsWRmVeSWpSXmKPExsWy7djPc7rZzFOiDE71ylhsnLGe1eL6l+es FpPuT2CxOH9+A7vFx557rBYzzu9jslh75C67xeE37awOHB6bVnWyefRtWcXo8XmTXABzFJdN SmpOZllqkb5dAldGz7kTrAWd1hXNj8+wNzDuMexi5OSQEDCR2Nj7i6WLkYtDSGAFo8TGU2fY IJzPjBIv7t5lganadfEPO0RiGaPErRvbWCGcBiaJKSua2EGq2AQMJbredrGB2CICDhKfP71m BCliFmhjkjh7YD9TFyMHh7CAm8TVp9IgNSwCqhL7Di0Fq+cVsJE4NrsVapu8xOLvO8HinAK2 Ep23poGdJCHQyCZx+ftmZpA5EgIuEjs7RCDqhSVeHd/CDmHLSHR2HGSCqO9nlPj3/yWUM4NR Yv3HVqgqa4nDxy+ygtjMAnwSk7ZNhxrKK9HRJgRR4iHxccdUNgjbUaLr3SJGiI8nMEos3TmB bQKj1AJGhlWM4qmlxbnpqcXGeanlesWJucWleel6yfm5mxiBEXn63/GvOxj3/Uk6xCjAwajE w/vjzuQoIdbEsuLK3EOMEhzMSiK8KxcDhXhTEiurUovy44tKc1KLDzFKc7AoifPGadRFCQmk J5akZqemFqQWwWSZODilGhiTl18tdI5VYf5W+G2H/0qHbXc4/2dXXSubXfQldlbKZGb7LyeW epadVBNxv3P7g92jnZE3GN/s6/MvezhtwqorMfMX/FZwigxqLvx3ZYHy8ZMp1l+UuURiO+ot 95+Iiigz3Bbq/USqLPgEp+L9jJydnGm7ZpVsD/WvEwha7lm0V0p7ys69m/SUWIozEg21mIuK EwHB3i6kxAIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpkluLIzCtJLcpLzFFi42I5/e/4Vd0s5ilRBrP3SVlsnLGe1eL6l+es FpPuT2CxOH9+A7vFx557rBYzzu9jslh75C67xeE37awOHB6bVnWyefRtWcXo8XmTXABzFJdN SmpOZllqkb5dAldGz7kTrAWd1hXNj8+wNzDuMexi5OSQEDCR2HXxD3sXIxeHkMASRomJzRvY QRJCAk1MEhuaFUFsNgFDia63XWwgtoiAg8TnT68ZQRqYBTqYJPbsfQiU4OAQFnCTuPpUGqSG RUBVYt+hpWD1vAI2Esdmt7JALJOXWPx9J1icU8BWovPWNDaIXTYS2/9tYZrAyLOAkWEVo0hq aXFuem6xoV5xYm5xaV66XnJ+7iZGYMBsO/Zz8w7GSxuDDzEKcDAq8fAu+DkpSog1say4MvcQ owQHs5II78rFk6OEeFMSK6tSi/Lji0pzUosPMUpzsCiJ8543qIwSEkhPLEnNTk0tSC2CyTJx cEo1MM6Mkrq50toq/61rbXnnj0t5/JdECpfo9iZHPEmqs9i/3in99cyC6PmPVrTW+HuZTzdc bmgz13DinUWXTwRob1Ngna7yPXp/2Aqm88e5vy+8Ebu8bNJuT9MTIktlrk5dkHg1d53suYrk WGO5jqqD29UbWb6u0FKT1rj74/j+L9waEx/b66zI7lBiKc5INNRiLipOBAAWoaBxFAIAAA== X-CMS-MailID: 20180226125402eucas1p1ac3e0a5853218cd77f469864f70ae89d X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20180226125402eucas1p1ac3e0a5853218cd77f469864f70ae89d X-RootMTR: 20180226125402eucas1p1ac3e0a5853218cd77f469864f70ae89d References: <20180226125355.9052-1-m.szyprowski@samsung.com> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Exynos5250/5420/5800 have only one clock constroller, but some of their clock depends on respective power domains. Handling integration of clock controller and power domain can be done using runtime PM feature of CCF framework. This however needs a separate struct device for each power domain. This patch adds such separate driver for a group of such clocks, which can be instantiated more than once, each time for a different power domain. Signed-off-by: Marek Szyprowski Reviewed-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-exynos5-subcmu.c | 185 +++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-exynos5-subcmu.h | 26 +++++ 2 files changed, 211 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos5-subcmu.c create mode 100644 drivers/clk/samsung/clk-exynos5-subcmu.h diff --git a/drivers/clk/samsung/clk-exynos5-subcmu.c b/drivers/clk/samsung/clk-exynos5-subcmu.c new file mode 100644 index 000000000000..41bf5c3cf178 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5-subcmu.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2018 Samsung Electronics Co., Ltd. +// Author: Marek Szyprowski +// Common Clock Framework support for Exynos5 power-domain dependent clocks + +#include +#include +#include +#include + +#include "clk.h" +#include "clk-exynos5-subcmu.h" + +static struct samsung_clk_provider *ctx; +static const struct exynos5_subcmu_info *cmu; +static int nr_cmus; + +static void samsung_ext_clk_save(void __iomem *base, + struct samsung_clk_ext_reg_dump *rd, + unsigned int num_regs) +{ + for (; num_regs > 0; --num_regs, ++rd) { + rd->save = readl(base + rd->offset); + writel((rd->save & ~rd->mask) | rd->value, base + rd->offset); + rd->save &= rd->mask; + } +}; + +static void samsung_ext_clk_restore(void __iomem *base, + struct samsung_clk_ext_reg_dump *rd, + unsigned int num_regs) +{ + for (; num_regs > 0; --num_regs, ++rd) + writel((readl(base + rd->offset) & ~rd->mask) | rd->save, + base + rd->offset); +} + +static void samsung_clk_defer_gate(struct samsung_clk_provider *ctx, + const struct samsung_gate_clock *list, int nr_clk) +{ + while (nr_clk--) + samsung_clk_add_lookup(ctx, ERR_PTR(-EPROBE_DEFER), list++->id); +} + +/* + * Pass the needed clock provider context and register sub-CMU clocks + * + * NOTE: This function has to be called from the main, OF_CLK_DECLARE- + * initialized clock provider driver. This happens very early during boot + * process. Then this driver, during core_initcall registers two platform + * drivers: one which binds to the same device-tree node as OF_CLK_DECLARE + * driver and second, for handling its per-domain child-devices. Those + * platform drivers are bound to their devices a bit later in arch_initcall, + * when OF-core populates all device-tree nodes. + */ +void exynos5_subcmus_init(struct samsung_clk_provider *_ctx, int _nr_cmus, + const struct exynos5_subcmu_info *_cmu) +{ + ctx = _ctx; + cmu = _cmu; + nr_cmus = _nr_cmus; + + for (; _nr_cmus--; _cmu++) { + samsung_clk_defer_gate(ctx, _cmu->gate_clks, _cmu->nr_gate_clks); + samsung_ext_clk_save(ctx->reg_base, _cmu->suspend_regs, + _cmu->nr_suspend_regs); + } +} + +static int __maybe_unused exynos5_clk_subcmu_suspend(struct device *dev) +{ + struct exynos5_subcmu_info *info = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&ctx->lock, flags); + samsung_ext_clk_save(ctx->reg_base, info->suspend_regs, + info->nr_suspend_regs); + spin_unlock_irqrestore(&ctx->lock, flags); + + return 0; +} + +static int __maybe_unused exynos5_clk_subcmu_resume(struct device *dev) +{ + struct exynos5_subcmu_info *info = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&ctx->lock, flags); + samsung_ext_clk_restore(ctx->reg_base, info->suspend_regs, + info->nr_suspend_regs); + spin_unlock_irqrestore(&ctx->lock, flags); + + return 0; +} + +static int __init exynos5_clk_subcmu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct exynos5_subcmu_info *info = dev_get_drvdata(dev); + + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + pm_runtime_get(dev); + + ctx->dev = dev; + samsung_clk_register_div(ctx, info->div_clks, info->nr_div_clks); + samsung_clk_register_gate(ctx, info->gate_clks, info->nr_gate_clks); + ctx->dev = NULL; + + pm_runtime_put_sync(dev); + + return 0; +} + +static const struct dev_pm_ops exynos5_clk_subcmu_pm_ops = { + SET_RUNTIME_PM_OPS(exynos5_clk_subcmu_suspend, + exynos5_clk_subcmu_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +static struct platform_driver exynos5_clk_subcmu_driver __refdata = { + .driver = { + .name = "exynos5-clock-subcmu", + .suppress_bind_attrs = true, + .pm = &exynos5_clk_subcmu_pm_ops, + }, + .probe = exynos5_clk_subcmu_probe, +}; + +static int __init exynos5_clk_register_subcmu_drv(struct device *parent, + const struct exynos5_subcmu_info *info, + struct device_node *pd_node) +{ + struct of_phandle_args genpdspec = { .np = pd_node }; + struct platform_device *pdev; + + pdev = platform_device_alloc(info->pd_name, -1); + pdev->dev.parent = parent; + pdev->driver_override = "exynos5-clock-subcmu"; + platform_set_drvdata(pdev, (void *)info); + of_genpd_add_device(&genpdspec, &pdev->dev); + platform_device_add(pdev); + + return 0; +} + +static int __init exynos5_clk_probe(struct platform_device *pdev) +{ + struct device_node *np; + const char *name; + int i; + + for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { + if (of_property_read_string(np, "label", &name) < 0) + continue; + for (i = 0; i < nr_cmus; i++) + if (strcmp(cmu[i].pd_name, name) == 0) + exynos5_clk_register_subcmu_drv(&pdev->dev, + &cmu[i], np); + } + return 0; +} + +static const struct of_device_id exynos5_clk_of_match[] = { + { }, +}; + +static struct platform_driver exynos5_clk_driver __refdata = { + .driver = { + .name = "exynos5-clock", + .of_match_table = exynos5_clk_of_match, + .suppress_bind_attrs = true, + }, + .probe = exynos5_clk_probe, +}; + +static int __init exynos5_clk_drv_init(void) +{ + platform_driver_register(&exynos5_clk_driver); + platform_driver_register(&exynos5_clk_subcmu_driver); + return 0; +} +core_initcall(exynos5_clk_drv_init); diff --git a/drivers/clk/samsung/clk-exynos5-subcmu.h b/drivers/clk/samsung/clk-exynos5-subcmu.h new file mode 100644 index 000000000000..364ca4051d9e --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5-subcmu.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __CLK_EXYNOS5_SUBCMU_H +#define __CLK_EXYNOS5_SUBCMU_H + +struct samsung_clk_ext_reg_dump { + u32 offset; + u32 value; + u32 mask; + u32 save; +}; + +struct exynos5_subcmu_info { + const struct samsung_div_clock *div_clks; + unsigned int nr_div_clks; + const struct samsung_gate_clock *gate_clks; + unsigned int nr_gate_clks; + struct samsung_clk_ext_reg_dump *suspend_regs; + unsigned int nr_suspend_regs; + const char *pd_name; +}; + +void exynos5_subcmus_init(struct samsung_clk_provider *ctx, int nr_cmus, + const struct exynos5_subcmu_info *cmu); + +#endif