From patchwork Wed Oct 19 17:20:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 2451 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id C6BBA3F342 for ; Wed, 19 Oct 2022 19:20:29 +0200 (CEST) Received: by mail-ed1-f70.google.com with SMTP id z7-20020a05640235c700b0045d3841ccf2sf11082162edc.9 for ; Wed, 19 Oct 2022 10:20:29 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1666200029; cv=pass; d=google.com; s=arc-20160816; b=E5qakv4fmw1EHnq623nXHdCPGwNpnk4292iukYzr/3mdnrSmosc06EgM1par6IF3/R cAe5Xdu0zjQc1GZLaY6DIVZYkvhJurrW5vQm3gLlLgJ+v9/9LWmEvY6WJKklAILsdVc2 tXAJZOxHWL6Olyza8kyh53GFH9oXepGMGDxc5jeODdED7SMj4RXTy2Et9mnpcIbwyJom W+jnnzoEgu+bXOwDBZsEOs6W5AGKZ4g7da4hDOux1Z0b+fpD9103rt5ialb3Kj31VlWA uwz+W87pq0pbf01ZK8Ge7Y7yWdQ7pSOIOUFr3llor3c0cjd9LDYpVfLlPS0MBmBLsGN7 OI2A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=Jc97s34TWH6IK5v7Vdhqf/zjDXgcLEk/pXDO8rx/bVw=; b=UlegCo/WuJEmZ8UTV2PBRb6BJ+/13p22zSacBKv+DESDiZFJgv8lSE8o+Ytkv2T2w/ 1EUpO+OYluf1mvPRcSXZ5Czaochqv+Op+2lruD2tXBYWN2Yfq9Vqvv9c9HrhTkrostkD dxV9MUmRDhbZh266TJ3ci73ig197O5tGDfUjv3IqLkJ/uGx5eARf3F/OrclSP7RnhBn3 fFaW2EVwkVvc8PlcENDr9VrSsM0lTavJ0Lx//Y/7yFXcaYAMLJhmjsII673r9eG+CgCR RvtR0DboiigAvqQ6u7npbsf4juzEHbU2Z3o/QBsCRq7ZCbkCEOw57tRZ4mOSZD9/T6K8 qZCg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="fON5/9dx"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=Jc97s34TWH6IK5v7Vdhqf/zjDXgcLEk/pXDO8rx/bVw=; b=EVuoOKOJGPq+2y7VNR4z5xBHW1czzChIuEeC36XXuSNea74/TnpT0ZbC8CZkm0BZg8 dsYndOWdsnns7NjZVofrSJ3Z+jRW2egEkaWWHjC8u1J7SZgmzI/t2b6W8TQpffhE5c27 Ku8GsihNM61Ou6l70iSb7lqRqiKDoLaIjoyPs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=list-unsubscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Jc97s34TWH6IK5v7Vdhqf/zjDXgcLEk/pXDO8rx/bVw=; b=dfic7DkqlmhZ0CV3STqyG/TcxWcL2u7OQ8kgVzTGRq6deY2O/patHmQxA06IpKkGoa Fv8qULlknUKA6oa7l26Pw8JG5bUTcNEenoBPy3GJzJDUcPGpYpaGbYVrL7e82ywLW0Wg CRMF777pEyac//Hwj9S7z0En1zyVRMHnQ+Geuv1bWp+X34ZWCTLlzJUfh240URabRMCG czacOMEg0wikXdzRaSSyR6IuWdtEaZxRqhcadBKuax8pojRresK7yIUQVgtE+Dts7vnZ Gt0S7z0TSAtFR5rIBxHa2tWQbgEV4f5a/Y8RYPFR/pQjYxtTHwdvVRl+2sdiRi1E2ScO /0Bw== X-Gm-Message-State: ACrzQf2kEvpTMhiq7MyjuPMOns2THUvHhEQ4eWAnohQxnZqM8xXb8t/3 wgAXDvL33AHhHSPogFBLOGN62zS4 X-Google-Smtp-Source: AMsMyM6GORpI4B5XhrHQuroDYAfKxbyGSUA8TpW9jiGa3WFWmRnUgwkaC6FElVQW5u3+bFn2e769Uw== X-Received: by 2002:a05:6402:3c5:b0:45b:55d8:21ff with SMTP id t5-20020a05640203c500b0045b55d821ffmr8500790edw.253.1666200029433; Wed, 19 Oct 2022 10:20:29 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:906:f03:b0:776:305f:399f with SMTP id z3-20020a1709060f0300b00776305f399fls9807700eji.1.-pod-prod-gmail; Wed, 19 Oct 2022 10:20:28 -0700 (PDT) X-Received: by 2002:a17:907:1c17:b0:78d:df89:26c6 with SMTP id nc23-20020a1709071c1700b0078ddf8926c6mr8046056ejc.20.1666200028185; Wed, 19 Oct 2022 10:20:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666200028; cv=none; d=google.com; s=arc-20160816; b=oYDK1VnWU3DPPEIWt2nU2OzyF4joBh24iXUPGsRX1uKLx1F7raSKO7aYZmY4+I95yR bUiKpVQqBeYPkLJWKOZE4xjuTfoMy+MvbJhf531W2g8KLinSGyYueTSbqmefq0AWO5aX R5Xfh9bQr1O5zXwOvqU3zY1kYRk+zXIDsetCUcXwIMRcUu8pXAq1Oj58H6apmitBY0el RnPz67d29ElRIDN5FqER3KifTN9Cz5vD3wVbb0lWjJZ6R/kwIasooFXejYjxGK/VlsuS MSkElu80LxmYJxItEBzQ9zeFei/PCpG15MvbmYUA/aqACTMgoegq5i2/+HWcIH1gvGGH MQLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=DyU1pGyWLlmZsBZdF4iMM6fw21qktmFwyLCpzW18Lb4=; b=lb8DGjf9dc37y8zjG6JqLIUkG4wsZSc6W3Pusl8zcMuIhLUjRdjL3vgYIIlOEqLnpF u9i0SmWlJGL3uy9Q+ocQ26+xKrkQfIRJPmt8EwyzHNzDhHbiHUr5ynfYJNIQXUVzkXFs 3UdaUqwC+ZmgQxRawZdpRNIkF0J65RyGOLUK6GT4/TVATaUsKviqWmamIkcbgz1uE0OF qxq2DzLvh1rwwiK/qBcac4EFExywcnY+GcJUEWJ3EO9nhyWg61sCcfz53XMv/OWE4dVv NAOqvczI2PCdHcnDaYYwMwo+vMNuPXEE1GiiK4KvyG8Q5/zXNsJDJKRfwFwglHuhZO5d b2jw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="fON5/9dx"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id c23-20020a50d657000000b0045812625983sor8626795edj.15.2022.10.19.10.20.28 for (Google Transport Security); Wed, 19 Oct 2022 10:20:28 -0700 (PDT) Received-SPF: pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a05:6402:28ca:b0:43b:5235:f325 with SMTP id ef10-20020a05640228ca00b0043b5235f325mr8443708edb.320.1666200027716; Wed, 19 Oct 2022 10:20:27 -0700 (PDT) Received: from dario-ThinkPad-T14s-Gen-2i.homenet.telecomitalia.it (host-95-233-42-253.retail.telecomitalia.it. [95.233.42.253]) by smtp.gmail.com with ESMTPSA id b27-20020a17090630db00b0073dbaeb50f6sm9237983ejb.169.2022.10.19.10.20.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Oct 2022 10:20:27 -0700 (PDT) From: Dario Binacchi To: linux-amarula@amarulasolutions.com Cc: anthony@amarulasolutions.com, jagan@amarulasolutions.com, dario.binacchi@amarulasolutions.com, michael@amarulasolutions.com, tommaso.merciai@amarulasolutions.com Subject: [RFC PATCH 5/8] clk: imx: add support for imx8mn mux clock Date: Wed, 19 Oct 2022 19:20:16 +0200 Message-Id: <20221019172019.2303223-6-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20221019172019.2303223-1-dario.binacchi@amarulasolutions.com> References: <20221019172019.2303223-1-dario.binacchi@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: dario.binacchi@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="fON5/9dx"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch adds support for freescale imx8mn mux clock. Let's start with this specific clock driver and hope that other variants can be handled in the future as well. Signed-off-by: Dario Binacchi --- drivers/clk/imx/Makefile | 1 + drivers/clk/imx/clk-mux.c | 239 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 drivers/clk/imx/clk-mux.c diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 539add92be47..ea8c4bed7709 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -14,6 +14,7 @@ mxc-clk-objs += clk-frac-pll.o mxc-clk-objs += clk-gate.o mxc-clk-objs += clk-gate2.o mxc-clk-objs += clk-gate-exclusive.o +mxc-clk-objs += clk-mux.o mxc-clk-objs += clk-pfd.o mxc-clk-objs += clk-pfdv2.o mxc-clk-objs += clk-pllv1.o diff --git a/drivers/clk/imx/clk-mux.c b/drivers/clk/imx/clk-mux.c new file mode 100644 index 000000000000..a54129756318 --- /dev/null +++ b/drivers/clk/imx/clk-mux.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Amarula Solutions + * + * Dario Binacchi + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +#define to_clk_imx_mux(_hw) container_of(_hw, struct clk_imx_mux, hw) + +struct clk_imx_mux { + struct clk_hw hw; + struct imx_clk_iomap iomap; + u32 mask; + u8 shift; + u8 saved_parent; +}; + +static u8 imx_clk_mux_get_parent(struct clk_hw *hw) +{ + + struct clk_imx_mux *mux = to_clk_imx_mux(hw); + struct imx_clk_iomap *io = &mux->iomap; + int num_parents = clk_hw_get_num_parents(hw); + unsigned int val; + + if (regmap_read(io->regmap, io->offset, &val)) + return -EIO; + + val = (val >> mux->shift) && mux->mask; + + if (val >= num_parents) + return -EINVAL; + + return val; +} + +static int imx_clk_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_imx_mux *mux = to_clk_imx_mux(hw); + struct imx_clk_iomap *io = &mux->iomap; + unsigned int val; + + if (regmap_read(io->regmap, io->offset, &val)) + return -EIO; + + val &= ~(mux->mask << mux->shift); + val |= index << mux->shift; + return regmap_write(io->regmap, io->offset, val); +} + +/** + * imx_clk_mux_save_context - Save the parent selcted in the mux + * @hw: pointer struct clk_hw + * + * Save the parent mux value. + */ +static int imx_clk_mux_save_context(struct clk_hw *hw) +{ + struct clk_imx_mux *mux = to_clk_imx_mux(hw); + + mux->saved_parent = imx_clk_mux_get_parent(hw); + return 0; +} + +/** + * imx_clk_mux_restore_context - Restore the parent in the mux + * @hw: pointer struct clk_hw + * + * Restore the saved parent mux value. + */ +static void imx_clk_mux_restore_context(struct clk_hw *hw) +{ + struct clk_imx_mux *mux = to_clk_imx_mux(hw); + + imx_clk_mux_set_parent(hw, mux->saved_parent); +} + +const struct clk_ops imx_clk_mux_ops = { + .get_parent = imx_clk_mux_get_parent, + .set_parent = imx_clk_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, + .save_context = imx_clk_mux_save_context, + .restore_context = imx_clk_mux_restore_context, +}; + +static void imx_clk_hw_unregister_mux(struct clk_hw *hw) +{ + struct clk_imx_mux *mux = to_clk_imx_mux(hw); + + clk_hw_unregister(hw); + kfree(mux); +} + +static struct clk_hw *imx_clk_hw_register_mux(struct device *dev, + const char *name, + const char * const *parent_names, + u8 num_parents, + unsigned long flags, + struct imx_clk_iomap *iomap, + u8 shift, u32 mask) +{ + struct clk_init_data init = { NULL }; + struct clk_imx_mux *mux; + struct clk_hw *hw; + + int ret; + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.flags = flags; + init.ops = &imx_clk_mux_ops; + init.parent_names = parent_names; + init.num_parents = 1; + + /* struct clk_mux assignments */ + memcpy(&mux->iomap, iomap, sizeof(*iomap)); + mux->hw.init = &init; + + hw = &mux->hw; + ret = clk_hw_register(dev, hw); + if (ret) { + kfree(mux); + return ERR_PTR(ret); + } + + return hw; +} + +static struct clk_hw *_of_imx_mux_clk_setup(struct device_node *node) +{ + struct clk_hw *hw; + struct device_node *parent_node; + unsigned int num_parents; + const char **parent_names; + const char *name; + struct imx_clk_iomap io; + u32 shift = 0; + u32 flags = CLK_SET_RATE_NO_REPARENT; + u32 val; + u32 mask; + int ret; + + parent_node = of_get_parent(node); + if (!parent_node) { + pr_err("%s: %pOFn must have 1 parent\n", __func__, node); + return ERR_PTR(-ENODEV); + } + + num_parents = of_clk_get_parent_count(node); + if (num_parents < 2) { + pr_err("%s: %pOFn must have parents\n", __func__, node); + return ERR_PTR(-ENODEV); + } + + parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL); + if (!parent_names) + return ERR_PTR(-ENOMEM); + + of_clk_parent_fill(node, parent_names, num_parents); + io.regmap = syscon_node_to_regmap(parent_node); + of_node_put(parent_node); + if (IS_ERR(io.regmap)) { + pr_err("%s: missing regmap for %pOFn\n", __func__, node); + ret = PTR_ERR(io.regmap); + goto free_parent_names; + } + + if (of_property_read_u32(node, "fsl,regmap-offset", &val)) { + pr_err("%s: missing regmap offset for %pOFn\n", __func__, + node); + ret = -EIO; + goto free_parent_names; + } + + io.offset = val; + + of_property_read_u32(node, "fsl,bit-shift", &shift); + + if (of_property_read_bool(node, "fsl,set-rate-parent")) + flags |= CLK_SET_RATE_PARENT; + + if (of_property_read_bool(node, "fsl,ops-parent-enable")) + flags |= CLK_OPS_PARENT_ENABLE; + + /* Generate bit-mask based on parent info */ + mask = num_parents - 1; + mask = (1 << fls(mask)) - 1; + + name = imx_dt_clk_name(node); + hw = imx_clk_hw_register_mux(NULL, name, parent_names, num_parents, + flags, &io, shift, mask); + if (IS_ERR(hw)) { + /* + * Clear OF_POPULATED flag so that clock registration can be + * attempted again from probe function. + */ + of_node_clear_flag(node, OF_POPULATED); + ret = PTR_ERR(hw); + goto free_parent_names; + } + + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); + if (ret) { + imx_clk_hw_unregister_mux(hw); + goto free_parent_names; + } + + pr_debug("%s: name: %s, offset: 0x%x, shift: %d, mask: 0x%x, ret: %d\n", + __func__, name, io.offset, shift, mask, ret); + +free_parent_names: + kfree(parent_names); + return ret ? ERR_PTR(ret) : hw; +} + +/** + * of_imx_mux_clk_setup() - Setup function for imx mux clock + * @node: device node for the clock + */ +void __init of_imx_mux_clk_setup(struct device_node *node) +{ + _of_imx_mux_clk_setup(node); +} +CLK_OF_DECLARE(fsl_imx8mn_mux_clk, "fsl,imx8mn-mux-clock", + of_imx_mux_clk_setup);