From patchwork Wed Feb 21 10:15:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 10231715 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 E7D4760392 for ; Wed, 21 Feb 2018 10:15:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D147128ABF for ; Wed, 21 Feb 2018 10:15:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C56BB28AE1; Wed, 21 Feb 2018 10:15:42 +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 2450028ABF for ; Wed, 21 Feb 2018 10:15:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932719AbeBUKPl (ORCPT ); Wed, 21 Feb 2018 05:15:41 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:53932 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932720AbeBUKPi (ORCPT ); Wed, 21 Feb 2018 05:15:38 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20180221101535euoutp02b5096f994b9dfe3e6f9ec566bbe93cb9~VT8Aa8KW_0099800998euoutp02Y; Wed, 21 Feb 2018 10:15:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20180221101535euoutp02b5096f994b9dfe3e6f9ec566bbe93cb9~VT8Aa8KW_0099800998euoutp02Y DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1519208135; bh=bleasS6P1n45q18DHLxcwnnyDGhNrgM95Tr1wBSt7Vc=; h=From:To:Cc:Subject:Date:In-reply-to:References:From; b=P07KePiBRmGKOdVLsZ+kmJ920rBR5CRaH+jDXsIXRu1yxQFq0LlvcDpIZLfjPxHIq SZJjtF+AzbjUWlmNihUbiYa6j6mykql8Xr1Dlo76+wSD1T8KBxbbFIJzdHFN1Gm2Wq ePlREXhSUqzIjotOJKn9lv0lGo84/mOOPyrwCa+M= Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20180221101534eucas1p1abd5adf6c4ac15b7442609aa6dd4c5a9~VT7-N2Sdx0845308453eucas1p1U; Wed, 21 Feb 2018 10:15:34 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id 98.BB.10409.6C64D8A5; Wed, 21 Feb 2018 10:15:34 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20180221101533eucas1p27bcfd237d2c851402b3e99248fec5a6c~VT7_UsUie1445814458eucas1p2q; Wed, 21 Feb 2018 10:15:33 +0000 (GMT) X-AuditID: cbfec7f5-b45ff700000028a9-66-5a8d46c6da32 Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 8E.E2.04178.5C64D8A5; Wed, 21 Feb 2018 10:15:33 +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 <0P4H005K9WHT4SB0@eusync3.samsung.com>; Wed, 21 Feb 2018 10:15:33 +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 2/6] clk: samsung: Add Exynos5x sub-CMU clock driver Date: Wed, 21 Feb 2018 11:15:23 +0100 Message-id: <20180221101527.25554-3-m.szyprowski@samsung.com> X-Mailer: git-send-email 2.15.0 In-reply-to: <20180221101527.25554-1-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrHIsWRmVeSWpSXmKPExsWy7djPc7rH3HqjDB6t5bDYOGM9q8X1L89Z LSbdn8Bicf78BnaLjz33WC1mnN/HZLH2yF12i8Nv2lkdODw2repk8+jbsorR4/MmuQDmKC6b lNSczLLUIn27BK6MU4c+sBb0WFXc3F/dwLjFoIuRk0NCwERixvYJzF2MXBxCAisYJa7tb2GE cD4zSnRvP8oOU3Xp8EE2EFtIYBmjxI/9kRBFDUwSP7obmUESbAKGEl1vu8CKRAQcJD5/eg02 iVmgjUni7IH9TCAJYQEXibdrPoJNZRFQldh06SoriM0rYCux69deZoht8hKLv+8EGsTBwSlg J7HzJQfIHAmBv6wStw/PYISocZG4dO86G4QtLPHq+BaoS2UkOjsOMkE09DNK/Pv/EsqZwSix /mMrVJW1xOHjF8E2MwvwSUzaNp0ZZJuEAK9ER5sQRImHxKEd3ewQYUeJ11frIb6fyCgx5WfZ BEapBYwMqxjFU0uLc9NTi43zUsv1ihNzi0vz0vWS83M3MQJj8fS/4193MO77k3SIUYCDUYmH 10KnJ0qINbGsuDL3EKMEB7OSCG+lUG+UEG9KYmVValF+fFFpTmrxIUZpDhYlcd44jbooIYH0 xJLU7NTUgtQimCwTB6dUA2NNxI9HDKF6JXuU1jsc0+rl1g2Kq/yV6iF4L/1K86tVrz4tX+Oo NrXnxqZ8OZOOli9mm8JuVGvpbrHmDf+e+UZvh81Wxbq/DudmcecFL/d6+zR5jyv/D6MZs47P fX7FJq/Z+FDGPv5tRWbtdstn/lv8uUVU+/F3ljP2ri9aBac+ddgbuUizy0GJpTgj0VCLuag4 EQCDuxkmwQIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpkluLIzCtJLcpLzFFi42I5/e/4Vd2jbr1RBpN+ylpsnLGe1eL6l+es FpPuT2CxOH9+A7vFx557rBYzzu9jslh75C67xeE37awOHB6bVnWyefRtWcXo8XmTXABzFJdN SmpOZllqkb5dAlfGqUMfWAt6rCpu7q9uYNxi0MXIySEhYCJx6fBBti5GLg4hgSWMEpdf/2KF cJqYJNq6l7OBVLEJGEp0ve0Cs0UEHCQ+f3rNCFLELNDBJLFn70OwhLCAi8TbNR/ZQWwWAVWJ TZeusoLYvAK2Ert+7WWGWCcvsfj7TqB6Dg5OATuJnS85QMJCQCXT1r5ln8DIs4CRYRWjSGpp cW56brGhXnFibnFpXrpecn7uJkZgwGw79nPzDsZLG4MPMQpwMCrx8Fro9EQJsSaWFVfmHmKU 4GBWEuGtFOqNEuJNSaysSi3Kjy8qzUktPsQozcGiJM573qAySkggPbEkNTs1tSC1CCbLxMEp 1cCYFSnSvHnZ3Ew7SZNobb9ood0dnpcb846cZV0XO0VmyeNZz6/3lPh7SVyfMvfT5Wfvag+2 s678FLzye3766tb6hN05RYzy2/dWGbclmRlPqC+aXS41+dAkNo3fhys5JrabJbxcw3Ny5RqN sPUqYixc9zNqtsh+COg++TXZ+bfrHZFDJpx3mzSVWIozEg21mIuKEwEFVPhZFAIAAA== X-CMS-MailID: 20180221101533eucas1p27bcfd237d2c851402b3e99248fec5a6c X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20180221101533eucas1p27bcfd237d2c851402b3e99248fec5a6c X-RootMTR: 20180221101533eucas1p27bcfd237d2c851402b3e99248fec5a6c References: <20180221101527.25554-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 group such clocks, which can be instantiated more than once, each time for a different power domain. Signed-off-by: Marek Szyprowski --- drivers/clk/samsung/clk-exynos5x-subcmu.c | 180 ++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-exynos5x-subcmu.h | 30 +++++ 2 files changed, 210 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos5x-subcmu.c create mode 100644 drivers/clk/samsung/clk-exynos5x-subcmu.h diff --git a/drivers/clk/samsung/clk-exynos5x-subcmu.c b/drivers/clk/samsung/clk-exynos5x-subcmu.c new file mode 100644 index 000000000000..9ff6d5d17f57 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5x-subcmu.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Author: Marek Szyprowski + * + * 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. + * + * Common Clock Framework support for Exynos5x power-domain dependent + * sub-CMUs + */ + +#include +#include +#include +#include + +#include "clk.h" +#include "clk-exynos5x-subcmu.h" + +static struct samsung_clk_provider *ctx; +static const struct samsung_5x_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 int __maybe_unused exynos5x_clk_subcmu_suspend(struct device *dev) +{ + struct samsung_5x_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 exynos5x_clk_subcmu_resume(struct device *dev) +{ + struct samsung_5x_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 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); +} + +void samsung_clk_subcmus_init(struct samsung_clk_provider *_ctx, int _nr_cmus, + const struct samsung_5x_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 __init exynos5x_clk_subcmu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct samsung_5x_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 exynos5x_disp_pm_ops = { + SET_RUNTIME_PM_OPS(exynos5x_clk_subcmu_suspend, + exynos5x_clk_subcmu_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +static struct platform_driver exynos5x_clk_subcmu_driver __refdata = { + .driver = { + .name = "exynos5x-clock-subcmu", + .suppress_bind_attrs = true, + .pm = &exynos5x_disp_pm_ops, + }, + .probe = exynos5x_clk_subcmu_probe, +}; + +static int __init exynos_5x_clk_register_subcmu(struct device *parent, + const struct samsung_5x_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 = "exynos5x-clock-subcmu"; + platform_set_drvdata(pdev, (void *)info); + of_genpd_add_device(&genpdspec, &pdev->dev); + platform_device_add(pdev); + + return 0; +} + +static int __init exynos5x_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) + exynos_5x_clk_register_subcmu(&pdev->dev, + &cmu[i], np); + } + return 0; +} + +static const struct of_device_id exynos5x_clk_of_match[] = { + { }, +}; + +static struct platform_driver exynos5x_clk_driver __refdata = { + .driver = { + .name = "exynos5x-clock", + .of_match_table = exynos5x_clk_of_match, + .suppress_bind_attrs = true, + }, + .probe = exynos5x_clk_probe, +}; + +static int __init exynos5x_clk_drv_init(void) +{ + platform_driver_register(&exynos5x_clk_driver); + platform_driver_register(&exynos5x_clk_subcmu_driver); + return 0; +} +core_initcall(exynos5x_clk_drv_init); diff --git a/drivers/clk/samsung/clk-exynos5x-subcmu.h b/drivers/clk/samsung/clk-exynos5x-subcmu.h new file mode 100644 index 000000000000..b44c238e54fa --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5x-subcmu.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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. + * + * Common Clock Framework support for Exynos5x power-domain dependent + * sub-CMUs +*/ + +struct samsung_clk_ext_reg_dump { + u32 offset; + u32 value; + u32 mask; + u32 save; +}; + +struct samsung_5x_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 samsung_clk_subcmus_init(struct samsung_clk_provider *ctx, int nr_cmus, + const struct samsung_5x_subcmu_info *cmu);