From patchwork Fri Oct 13 10:21:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 115736 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp564008qgn; Fri, 13 Oct 2017 03:32:00 -0700 (PDT) X-Google-Smtp-Source: AOwi7QCDtVqNLjpZPNTQz/RNEIExT2W4abcqa2EOAjrgYFg4suJhelWpnNZOkH+AnefjL6pw5caf X-Received: by 10.80.135.73 with SMTP id 9mr1496204edv.266.1507890720495; Fri, 13 Oct 2017 03:32:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507890720; cv=none; d=google.com; s=arc-20160816; b=rL2SceCqQ/Lke/fsexDm1dkSc4a+hVAHvWNkfk9HfACOhkxNX/P7WTAGGYJYXduvYB 2MqVUq8xhyHjfffR6atOD4ffRKAOOHrmNbCUbwaI2D2tPfLb92qkoC2jyiUgPVBVCJzq UFPo3zS2mKhNMtX1cdEma+XzTk2r9heOTXBmOcbOF4LBpZTHGSs8MXQgx9eyVtt7tla3 t9A8cfIT4ClUsg8IQDF0i1nX6wtUE7btSaI8ha+Kwe4wJ5a9dR3kOk8ldIhkCkVc7tuu YbqgkfTyBPpDzSpbPQnt1vsfyLQTHenEXXGWaMGc7GJyxKpzN5sb19TXarXD/DjPHHQs mZjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:dkim-filter:arc-authentication-results; bh=MjGIkTYk5hRe9KqKMQ1M+YJkzG+Duj+u7CBExjivPsE=; b=DabUTARuCzSBvC2Ny0zocxn3gbxsUhD7a5O3cRwLibMoNK2ZLNo1d8CB6fhxlHUROH 8jBFEMgLbGObsXHYPUJnRu5sGkUuKkiPfHR4nB8GMnz9cVXBPdt2651EdryEHlnzqGgg Hbl7ccwkgNTkUR6317QoJWhwAvBXSwCcvUGbQ9AbDcE6RhqbsPbmdJvY3EYA0QPkZfE+ OptnEgXHJbZSdIDWq/HOK6/uKZQauvHqXCEMnH0JO5eNRBD0zsx35HgG9SKR5zHNIDX6 GBUkNoO43malnqeFmENvatHZxmZ6Z/m7EZJ6P/TNhHKCPmGRbJePum41ftGusESRyuxK fjlA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=WpCwHI0f; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id j33si723111edb.403.2017.10.13.03.32.00; Fri, 13 Oct 2017 03:32:00 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=WpCwHI0f; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by lists.denx.de (Postfix, from userid 105) id 195CBC21EEF; Fri, 13 Oct 2017 10:30:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 0A86DC22036; Fri, 13 Oct 2017 10:22:58 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 6AC4FC21F3D; Fri, 13 Oct 2017 10:22:41 +0000 (UTC) Received: from conuserg-12.nifty.com (conuserg-12.nifty.com [210.131.2.79]) by lists.denx.de (Postfix) with ESMTPS id B74BDC21F1F for ; Fri, 13 Oct 2017 10:22:39 +0000 (UTC) Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-12.nifty.com with ESMTP id v9DAMGxD009903; Fri, 13 Oct 2017 19:22:22 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-12.nifty.com v9DAMGxD009903 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1507890142; bh=YxDzA1ezdfk/+pJA9Q4HIyRaGOPCY2HBkBiQrHCcKFc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WpCwHI0f7Gr3NkzlZBiKSlIvI61qetVgvGhsMpGatXt7XfJRFHlBXoB2Ub0FjpbT8 bBUoHu2AVk1F0qBE9kCLQ5x3o76UWtYCbXNXAjl1UnZVb2NUhSEyNlqzRm3rbj9vrJ TX5n7r1k52h4JCi9045Eag9p84qOJfT9Ddq0mQodEcmMz5gnptl5gGmwLqbgRzMhf8 0lQkM15PTUTrp1pGMhsL4+mrttQOw0435so3DbIoHywJVbwCghdaNDtv8hAbdCWYYZ f/0Tfh30wLrkTZUxf/SSOFNdAPoodi7v5FWwjKhTR3nKBurJpWYz0lQ4OUxHAijOLn Gtxl43FCJzT9Q== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: u-boot@lists.denx.de Date: Fri, 13 Oct 2017 19:21:59 +0900 Message-Id: <1507890129-1543-11-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1507890129-1543-1-git-send-email-yamada.masahiro@socionext.com> References: <1507890129-1543-1-git-send-email-yamada.masahiro@socionext.com> Subject: [U-Boot] [PATCH 10/20] clk: uniphier: rework for better clock tree structure X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" U-Boot does not support fancy clock tree structures like the Linux common clock framework. Implement a simple clock tree model at the driver level. With this, the clock data will be simplified. Signed-off-by: Masahiro Yamada --- drivers/clk/uniphier/clk-uniphier-core.c | 267 ++++++++++++++++++++++--------- drivers/clk/uniphier/clk-uniphier-mio.c | 118 +++++++------- drivers/clk/uniphier/clk-uniphier-sys.c | 42 +++-- drivers/clk/uniphier/clk-uniphier.h | 79 +++++---- 4 files changed, 323 insertions(+), 183 deletions(-) diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c index 722cd6b..3d1d411 100644 --- a/drivers/clk/uniphier/clk-uniphier-core.c +++ b/drivers/clk/uniphier/clk-uniphier-core.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Socionext Inc. + * Copyright (C) 2016-2017 Socionext Inc. * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ @@ -21,104 +21,224 @@ * @data: SoC specific data */ struct uniphier_clk_priv { + struct udevice *dev; void __iomem *base; const struct uniphier_clk_data *data; }; -static int uniphier_clk_enable(struct clk *clk) +static void uniphier_clk_gate_enable(struct uniphier_clk_priv *priv, + const struct uniphier_clk_gate_data *gate) { - struct uniphier_clk_priv *priv = dev_get_priv(clk->dev); - unsigned long id = clk->id; - const struct uniphier_clk_gate_data *p; + u32 val; - for (p = priv->data->gate; p->id != UNIPHIER_CLK_ID_END; p++) { - u32 val; + val = readl(priv->base + gate->reg); + val |= BIT(gate->bit); + writel(val, priv->base + gate->reg); +} - if (p->id != id) - continue; +static void uniphier_clk_mux_set_parent(struct uniphier_clk_priv *priv, + const struct uniphier_clk_mux_data *mux, + u8 id) +{ + u32 val; + int i; - val = readl(priv->base + p->reg); - val |= BIT(p->bit); - writel(val, priv->base + p->reg); + for (i = 0; i < mux->num_parents; i++) { + if (mux->parent_ids[i] != id) + continue; - return 0; + val = readl(priv->base + mux->reg); + val &= ~mux->masks[i]; + val |= mux->vals[i]; + writel(val, priv->base + mux->reg); + return; } - dev_err(priv->dev, "clk_id=%lu was not handled\n", id); - return -EINVAL; + WARN_ON(1); } -static const struct uniphier_clk_mux_data * -uniphier_clk_get_mux_data(struct uniphier_clk_priv *priv, unsigned long id) +static u8 uniphier_clk_mux_get_parent(struct uniphier_clk_priv *priv, + const struct uniphier_clk_mux_data *mux) { - const struct uniphier_clk_mux_data *p; + u32 val; + int i; - for (p = priv->data->mux; p->id != UNIPHIER_CLK_ID_END; p++) { - if (p->id == id) - return p; - } + val = readl(priv->base + mux->reg); + + for (i = 0; i < mux->num_parents; i++) + if ((mux->masks[i] & val) == mux->vals[i]) + return mux->parent_ids[i]; + + dev_err(priv->dev, "invalid mux setting\n"); + + return UNIPHIER_CLK_ID_INVALID; +} + +static const struct uniphier_clk_data *uniphier_clk_get_data( + struct uniphier_clk_priv *priv, u8 id) +{ + const struct uniphier_clk_data *data; + + for (data = priv->data; data->type != UNIPHIER_CLK_TYPE_END; data++) + if (data->id == id) + return data; + + dev_err(priv->dev, "id=%u not found\n", id); return NULL; } -static ulong uniphier_clk_get_rate(struct clk *clk) +static const struct uniphier_clk_data *uniphier_clk_get_parent_data( + struct uniphier_clk_priv *priv, + const struct uniphier_clk_data *data) { - struct uniphier_clk_priv *priv = dev_get_priv(clk->dev); - const struct uniphier_clk_mux_data *mux; - u32 val; - int i; + const struct uniphier_clk_data *parent_data; + u8 parent_id = UNIPHIER_CLK_ID_INVALID; + + switch (data->type) { + case UNIPHIER_CLK_TYPE_GATE: + parent_id = data->data.gate.parent_id; + break; + case UNIPHIER_CLK_TYPE_MUX: + parent_id = uniphier_clk_mux_get_parent(priv, &data->data.mux); + break; + default: + break; + } - mux = uniphier_clk_get_mux_data(priv, clk->id); - if (!mux) - return 0; + if (parent_id == UNIPHIER_CLK_ID_INVALID) + return NULL; - if (!mux->nr_muxs) /* fixed-rate */ - return mux->rates[0]; + parent_data = uniphier_clk_get_data(priv, parent_id); - val = readl(priv->base + mux->reg); + WARN_ON(!parent_data); - for (i = 0; i < mux->nr_muxs; i++) - if ((mux->masks[i] & val) == mux->vals[i]) - return mux->rates[i]; + return parent_data; +} + +static void __uniphier_clk_enable(struct uniphier_clk_priv *priv, + const struct uniphier_clk_data *data) +{ + const struct uniphier_clk_data *parent_data; - return -EINVAL; + if (data->type == UNIPHIER_CLK_TYPE_GATE) + uniphier_clk_gate_enable(priv, &data->data.gate); + + parent_data = uniphier_clk_get_parent_data(priv, data); + if (!parent_data) + return; + + return __uniphier_clk_enable(priv, parent_data); } -static ulong uniphier_clk_set_rate(struct clk *clk, ulong rate) +static int uniphier_clk_enable(struct clk *clk) { struct uniphier_clk_priv *priv = dev_get_priv(clk->dev); - const struct uniphier_clk_mux_data *mux; - u32 val; - int i, best_rate_id = -1; - ulong best_rate = 0; + const struct uniphier_clk_data *data; + + data = uniphier_clk_get_data(priv, clk->id); + if (!data) + return -ENODEV; + + __uniphier_clk_enable(priv, data); + + return 0; +} + +static unsigned long __uniphier_clk_get_rate( + struct uniphier_clk_priv *priv, + const struct uniphier_clk_data *data) +{ + const struct uniphier_clk_data *parent_data; - mux = uniphier_clk_get_mux_data(priv, clk->id); - if (!mux) + if (data->type == UNIPHIER_CLK_TYPE_FIXED_RATE) + return data->data.rate.fixed_rate; + + parent_data = uniphier_clk_get_parent_data(priv, data); + if (!parent_data) return 0; - if (!mux->nr_muxs) /* fixed-rate */ - return mux->rates[0]; + return __uniphier_clk_get_rate(priv, parent_data); +} - /* first, decide the best match rate */ - for (i = 0; i < mux->nr_muxs; i++) { - if (mux->rates[i] > best_rate && mux->rates[i] <= rate) { - best_rate = mux->rates[i]; - best_rate_id = i; +static unsigned long uniphier_clk_get_rate(struct clk *clk) +{ + struct uniphier_clk_priv *priv = dev_get_priv(clk->dev); + const struct uniphier_clk_data *data; + + data = uniphier_clk_get_data(priv, clk->id); + if (!data) + return -ENODEV; + + return __uniphier_clk_get_rate(priv, data); +} + +static unsigned long __uniphier_clk_set_rate( + struct uniphier_clk_priv *priv, + const struct uniphier_clk_data *data, + unsigned long rate, bool set) +{ + const struct uniphier_clk_data *best_parent_data = NULL; + const struct uniphier_clk_data *parent_data; + unsigned long best_rate = 0; + unsigned long parent_rate; + u8 parent_id; + int i; + + if (data->type == UNIPHIER_CLK_TYPE_FIXED_RATE) + return data->data.rate.fixed_rate; + + if (data->type == UNIPHIER_CLK_TYPE_GATE) { + parent_data = uniphier_clk_get_parent_data(priv, data); + if (!parent_data) + return 0; + + return __uniphier_clk_set_rate(priv, parent_data, rate, set); + } + + if (WARN_ON(data->type != UNIPHIER_CLK_TYPE_MUX)) + return -EINVAL; + + for (i = 0; i < data->data.mux.num_parents; i++) { + parent_id = data->data.mux.parent_ids[i]; + parent_data = uniphier_clk_get_data(priv, parent_id); + if (WARN_ON(!parent_data)) + return -EINVAL; + + parent_rate = __uniphier_clk_set_rate(priv, parent_data, rate, + false); + + if (parent_rate <= rate && best_rate < parent_rate) { + best_rate = parent_rate; + best_parent_data = parent_data; } } - if (best_rate_id < 0) + dev_dbg(priv->dev, "id=%u, best_rate=%lu\n", data->id, best_rate); + + if (!best_parent_data) return -EINVAL; - val = readl(priv->base + mux->reg); - val &= ~mux->masks[best_rate_id]; - val |= mux->vals[best_rate_id]; - writel(val, priv->base + mux->reg); + if (!set) + return best_rate; + + uniphier_clk_mux_set_parent(priv, &data->data.mux, + best_parent_data->id); + + return best_rate = __uniphier_clk_set_rate(priv, best_parent_data, + rate, true); +} + +static unsigned long uniphier_clk_set_rate(struct clk *clk, ulong rate) +{ + struct uniphier_clk_priv *priv = dev_get_priv(clk->dev); + const struct uniphier_clk_data *data; - debug("%s: requested rate = %lu, set rate = %lu\n", __func__, - rate, best_rate); + data = uniphier_clk_get_data(priv, clk->id); + if (!data) + return -ENODEV; - return best_rate; + return __uniphier_clk_set_rate(priv, data, rate, true); } static const struct clk_ops uniphier_clk_ops = { @@ -140,6 +260,7 @@ static int uniphier_clk_probe(struct udevice *dev) if (!priv->base) return -ENOMEM; + priv->dev = dev; priv->data = (void *)dev_get_driver_data(dev); return 0; @@ -149,60 +270,60 @@ static const struct udevice_id uniphier_clk_match[] = { /* System clock */ { .compatible = "socionext,uniphier-ld4-clock", - .data = (ulong)&uniphier_pxs2_sys_clk_data, + .data = (ulong)uniphier_pxs2_sys_clk_data, }, { .compatible = "socionext,uniphier-pro4-clock", - .data = (ulong)&uniphier_pxs2_sys_clk_data, + .data = (ulong)uniphier_pxs2_sys_clk_data, }, { .compatible = "socionext,uniphier-sld8-clock", - .data = (ulong)&uniphier_pxs2_sys_clk_data, + .data = (ulong)uniphier_pxs2_sys_clk_data, }, { .compatible = "socionext,uniphier-pro5-clock", - .data = (ulong)&uniphier_pxs2_sys_clk_data, + .data = (ulong)uniphier_pxs2_sys_clk_data, }, { .compatible = "socionext,uniphier-pxs2-clock", - .data = (ulong)&uniphier_pxs2_sys_clk_data, + .data = (ulong)uniphier_pxs2_sys_clk_data, }, { .compatible = "socionext,uniphier-ld11-clock", - .data = (ulong)&uniphier_ld20_sys_clk_data, + .data = (ulong)uniphier_ld20_sys_clk_data, }, { .compatible = "socionext,uniphier-ld20-clock", - .data = (ulong)&uniphier_ld20_sys_clk_data, + .data = (ulong)uniphier_ld20_sys_clk_data, }, /* Media I/O clock */ { .compatible = "socionext,uniphier-ld4-mio-clock", - .data = (ulong)&uniphier_mio_clk_data, + .data = (ulong)uniphier_mio_clk_data, }, { .compatible = "socionext,uniphier-pro4-mio-clock", - .data = (ulong)&uniphier_mio_clk_data, + .data = (ulong)uniphier_mio_clk_data, }, { .compatible = "socionext,uniphier-sld8-mio-clock", - .data = (ulong)&uniphier_mio_clk_data, + .data = (ulong)uniphier_mio_clk_data, }, { .compatible = "socionext,uniphier-pro5-sd-clock", - .data = (ulong)&uniphier_mio_clk_data, + .data = (ulong)uniphier_mio_clk_data, }, { .compatible = "socionext,uniphier-pxs2-sd-clock", - .data = (ulong)&uniphier_mio_clk_data, + .data = (ulong)uniphier_mio_clk_data, }, { .compatible = "socionext,uniphier-ld11-mio-clock", - .data = (ulong)&uniphier_mio_clk_data, + .data = (ulong)uniphier_mio_clk_data, }, { .compatible = "socionext,uniphier-ld20-sd-clock", - .data = (ulong)&uniphier_mio_clk_data, + .data = (ulong)uniphier_mio_clk_data, }, { /* sentinel */ } }; diff --git a/drivers/clk/uniphier/clk-uniphier-mio.c b/drivers/clk/uniphier/clk-uniphier-mio.c index 9c13dcd..5c73848 100644 --- a/drivers/clk/uniphier/clk-uniphier-mio.c +++ b/drivers/clk/uniphier/clk-uniphier-mio.c @@ -7,59 +7,71 @@ #include "clk-uniphier.h" -#define UNIPHIER_MIO_CLK_SD_GATE(id, ch) \ - UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 8) +#define UNIPHIER_MIO_CLK_SD_FIXED \ + UNIPHIER_CLK_RATE(128, 44444444), \ + UNIPHIER_CLK_RATE(129, 33333333), \ + UNIPHIER_CLK_RATE(130, 50000000), \ + UNIPHIER_CLK_RATE(131, 66666667), \ + UNIPHIER_CLK_RATE(132, 100000000), \ + UNIPHIER_CLK_RATE(133, 40000000), \ + UNIPHIER_CLK_RATE(134, 25000000), \ + UNIPHIER_CLK_RATE(135, 22222222) + +#define UNIPHIER_MIO_CLK_SD(_id, ch) \ + { \ + .type = UNIPHIER_CLK_TYPE_MUX, \ + .id = (_id) + 32, \ + .data.mux = { \ + .parent_ids = { \ + 128, \ + 129, \ + 130, \ + 131, \ + 132, \ + 133, \ + 134, \ + 135, \ + }, \ + .num_parents = 8, \ + .reg = 0x30 + 0x200 * (ch), \ + .masks = { \ + 0x00031000, \ + 0x00031000, \ + 0x00031000, \ + 0x00031000, \ + 0x00001300, \ + 0x00001300, \ + 0x00001300, \ + 0x00001300, \ + }, \ + .vals = { \ + 0x00000000, \ + 0x00010000, \ + 0x00020000, \ + 0x00030000, \ + 0x00001000, \ + 0x00001100, \ + 0x00001200, \ + 0x00001300, \ + }, \ + }, \ + }, \ + UNIPHIER_CLK_GATE((_id), (_id) + 32, 0x20 + 0x200 * (ch), 8) #define UNIPHIER_MIO_CLK_USB2(id, ch) \ - UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 28) + UNIPHIER_CLK_GATE_SIMPLE((id), 0x20 + 0x200 * (ch), 28) #define UNIPHIER_MIO_CLK_USB2_PHY(id, ch) \ - UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 29) + UNIPHIER_CLK_GATE_SIMPLE((id), 0x20 + 0x200 * (ch), 29) #define UNIPHIER_MIO_CLK_DMAC(id) \ - UNIPHIER_CLK_GATE((id), 0x20, 25) - -#define UNIPHIER_MIO_CLK_SD_MUX(_id, ch) \ - { \ - .id = (_id), \ - .nr_muxs = 8, \ - .reg = 0x30 + 0x200 * (ch), \ - .masks = { \ - 0x00031000, \ - 0x00031000, \ - 0x00031000, \ - 0x00031000, \ - 0x00001300, \ - 0x00001300, \ - 0x00001300, \ - 0x00001300, \ - }, \ - .vals = { \ - 0x00000000, \ - 0x00010000, \ - 0x00020000, \ - 0x00030000, \ - 0x00001000, \ - 0x00001100, \ - 0x00001200, \ - 0x00001300, \ - }, \ - .rates = { \ - 44444444, \ - 33333333, \ - 50000000, \ - 66666666, \ - 100000000, \ - 40000000, \ - 25000000, \ - 22222222, \ - }, \ - } + UNIPHIER_CLK_GATE_SIMPLE((id), 0x20, 25) -static const struct uniphier_clk_gate_data uniphier_mio_clk_gate[] = { - UNIPHIER_MIO_CLK_SD_GATE(0, 0), - UNIPHIER_MIO_CLK_SD_GATE(1, 1), - UNIPHIER_MIO_CLK_SD_GATE(2, 2), /* for PH1-Pro4 only */ +const struct uniphier_clk_data uniphier_mio_clk_data[] = { + UNIPHIER_MIO_CLK_SD_FIXED, + UNIPHIER_MIO_CLK_SD(0, 0), + UNIPHIER_MIO_CLK_SD(1, 1), + UNIPHIER_MIO_CLK_SD(2, 2), UNIPHIER_MIO_CLK_DMAC(7), UNIPHIER_MIO_CLK_USB2(8, 0), UNIPHIER_MIO_CLK_USB2(9, 1), @@ -67,17 +79,5 @@ static const struct uniphier_clk_gate_data uniphier_mio_clk_gate[] = { UNIPHIER_MIO_CLK_USB2_PHY(12, 0), UNIPHIER_MIO_CLK_USB2_PHY(13, 1), UNIPHIER_MIO_CLK_USB2_PHY(14, 2), - UNIPHIER_CLK_END -}; - -static const struct uniphier_clk_mux_data uniphier_mio_clk_mux[] = { - UNIPHIER_MIO_CLK_SD_MUX(0, 0), - UNIPHIER_MIO_CLK_SD_MUX(1, 1), - UNIPHIER_MIO_CLK_SD_MUX(2, 2), /* for PH1-Pro4 only */ - UNIPHIER_CLK_END -}; - -const struct uniphier_clk_data uniphier_mio_clk_data = { - .gate = uniphier_mio_clk_gate, - .mux = uniphier_mio_clk_mux, + { /* sentinel */ } }; diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c index 709fa50..e9df885 100644 --- a/drivers/clk/uniphier/clk-uniphier-sys.c +++ b/drivers/clk/uniphier/clk-uniphier-sys.c @@ -7,28 +7,26 @@ #include "clk-uniphier.h" -const struct uniphier_clk_gate_data uniphier_pxs2_sys_clk_gate[] = { - UNIPHIER_CLK_GATE(8, 0x2104, 10), /* stdmac */ - UNIPHIER_CLK_GATE(12, 0x2104, 6), /* gio (Pro4, Pro5) */ - UNIPHIER_CLK_GATE(14, 0x2104, 16), /* usb30 (Pro4, Pro5, PXs2) */ - UNIPHIER_CLK_GATE(15, 0x2104, 17), /* usb31 (Pro4, Pro5, PXs2) */ - UNIPHIER_CLK_GATE(16, 0x2104, 19), /* usb30-phy (PXs2) */ - UNIPHIER_CLK_GATE(20, 0x2104, 20), /* usb31-phy (PXs2) */ - UNIPHIER_CLK_END +const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = { +#if defined(CONFIG_ARCH_UNIPHIER_LD4) || defined(CONFIG_ARCH_UNIPHIER_SLD8) ||\ + defined(CONFIG_ARCH_UNIPHIER_PRO4) || defined(CONFIG_ARCH_UNIPHIER_PRO5) ||\ + defined(CONFIG_ARCH_UNIPHIER_PXS2) || defined(CONFIG_ARCH_UNIPHIER_LD6B) + UNIPHIER_CLK_GATE_SIMPLE(8, 0x2104, 10), /* stdmac */ + UNIPHIER_CLK_GATE_SIMPLE(12, 0x2104, 6), /* gio (Pro4, Pro5) */ + UNIPHIER_CLK_GATE_SIMPLE(14, 0x2104, 16), /* usb30 (Pro4, Pro5, PXs2) */ + UNIPHIER_CLK_GATE_SIMPLE(15, 0x2104, 17), /* usb31 (Pro4, Pro5, PXs2) */ + UNIPHIER_CLK_GATE_SIMPLE(16, 0x2104, 19), /* usb30-phy (PXs2) */ + UNIPHIER_CLK_GATE_SIMPLE(20, 0x2104, 20), /* usb31-phy (PXs2) */ + { /* sentinel */ } +#endif }; -const struct uniphier_clk_data uniphier_pxs2_sys_clk_data = { - .gate = uniphier_pxs2_sys_clk_gate, -}; - -const struct uniphier_clk_gate_data uniphier_ld20_sys_clk_gate[] = { - UNIPHIER_CLK_GATE(8, 0x210c, 8), /* stdmac */ - UNIPHIER_CLK_GATE(14, 0x210c, 14), /* usb30 (LD20) */ - UNIPHIER_CLK_GATE(16, 0x210c, 12), /* usb30-phy0 (LD20) */ - UNIPHIER_CLK_GATE(17, 0x210c, 13), /* usb30-phy1 (LD20) */ - UNIPHIER_CLK_END -}; - -const struct uniphier_clk_data uniphier_ld20_sys_clk_data = { - .gate = uniphier_ld20_sys_clk_gate, +const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { +#if defined(CONFIG_ARCH_UNIPHIER_LD11) || defined(CONFIG_ARCH_UNIPHIER_LD20) + UNIPHIER_CLK_GATE_SIMPLE(8, 0x210c, 8), /* stdmac */ + UNIPHIER_CLK_GATE_SIMPLE(14, 0x210c, 14), /* usb30 (LD20) */ + UNIPHIER_CLK_GATE_SIMPLE(16, 0x210c, 12), /* usb30-phy0 (LD20) */ + UNIPHIER_CLK_GATE_SIMPLE(17, 0x210c, 13), /* usb30-phy1 (LD20) */ + { /* sentinel */ } +#endif }; diff --git a/drivers/clk/uniphier/clk-uniphier.h b/drivers/clk/uniphier/clk-uniphier.h index 770a322..9b6c94f 100644 --- a/drivers/clk/uniphier/clk-uniphier.h +++ b/drivers/clk/uniphier/clk-uniphier.h @@ -9,49 +9,70 @@ #define __CLK_UNIPHIER_H__ #include +#include -#define UNIPHIER_CLK_MAX_NR_MUXS 8 +#define UNIPHIER_CLK_MUX_MAX_PARENTS 8 + +#define UNIPHIER_CLK_TYPE_END 0 +#define UNIPHIER_CLK_TYPE_FIXED_RATE 2 +#define UNIPHIER_CLK_TYPE_GATE 3 +#define UNIPHIER_CLK_TYPE_MUX 4 + +#define UNIPHIER_CLK_ID_INVALID (U8_MAX) + +struct uniphier_clk_fixed_rate_data { + unsigned long fixed_rate; +}; struct uniphier_clk_gate_data { - unsigned int id; - unsigned int reg; - unsigned int bit; + u8 parent_id; + u16 reg; + u8 bit; }; struct uniphier_clk_mux_data { - unsigned int id; - unsigned int nr_muxs; - unsigned int reg; - unsigned int masks[UNIPHIER_CLK_MAX_NR_MUXS]; - unsigned int vals[UNIPHIER_CLK_MAX_NR_MUXS]; - unsigned long rates[UNIPHIER_CLK_MAX_NR_MUXS]; + u8 parent_ids[UNIPHIER_CLK_MUX_MAX_PARENTS]; + u8 num_parents; + u16 reg; + u32 masks[UNIPHIER_CLK_MUX_MAX_PARENTS]; + u32 vals[UNIPHIER_CLK_MUX_MAX_PARENTS]; }; struct uniphier_clk_data { - const struct uniphier_clk_gate_data *gate; - const struct uniphier_clk_mux_data *mux; + u8 type; + u8 id; + union { + struct uniphier_clk_fixed_rate_data rate; + struct uniphier_clk_gate_data gate; + struct uniphier_clk_mux_data mux; + } data; }; -#define UNIPHIER_CLK_ID_END (unsigned int)(-1) - -#define UNIPHIER_CLK_END \ - { .id = UNIPHIER_CLK_ID_END } - -#define UNIPHIER_CLK_GATE(_id, _reg, _bit) \ - { \ - .id = (_id), \ - .reg = (_reg), \ - .bit = (_bit), \ +#define UNIPHIER_CLK_RATE(_id, _rate) \ + { \ + .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \ + .id = (_id), \ + .data.rate = { \ + .fixed_rate = (_rate), \ + }, \ } -#define UNIPHIER_CLK_FIXED_RATE(_id, _rate) \ - { \ - .id = (_id), \ - .rates = {(_reg),}, \ +#define UNIPHIER_CLK_GATE(_id, _parent, _reg, _bit) \ + { \ + .type = UNIPHIER_CLK_TYPE_GATE, \ + .id = (_id), \ + .data.gate = { \ + .parent_id = (_parent), \ + .reg = (_reg), \ + .bit = (_bit), \ + }, \ } -extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data; -extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data; -extern const struct uniphier_clk_data uniphier_mio_clk_data; +#define UNIPHIER_CLK_GATE_SIMPLE(_id, _reg, _bit) \ + UNIPHIER_CLK_GATE(_id, UNIPHIER_CLK_ID_INVALID, _reg, _bit) + +extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[]; +extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[]; +extern const struct uniphier_clk_data uniphier_mio_clk_data[]; #endif /* __CLK_UNIPHIER_H__ */