From patchwork Wed Jun 3 15:43:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adam Ford X-Patchwork-Id: 11585957 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4729290 for ; Wed, 3 Jun 2020 15:43:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 14DBC207D5 for ; Wed, 3 Jun 2020 15:43:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Rrb1P1Go" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726148AbgFCPnm (ORCPT ); Wed, 3 Jun 2020 11:43:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725944AbgFCPnm (ORCPT ); Wed, 3 Jun 2020 11:43:42 -0400 Received: from mail-io1-xd41.google.com (mail-io1-xd41.google.com [IPv6:2607:f8b0:4864:20::d41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 681DBC08C5C0; Wed, 3 Jun 2020 08:43:42 -0700 (PDT) Received: by mail-io1-xd41.google.com with SMTP id h4so2739536iob.10; Wed, 03 Jun 2020 08:43:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=9qRGYE9VepujAcHZSqqCVwT3Q7eiBwVFx2pYpMwBWYk=; b=Rrb1P1GoH5Q+LDAxoi30RFhNeWjFTfPXPQWiOWcsYeJMBePeW6FQFzQA5s4TG1pyIL w4NwlyY6O6v/AflkwmEItw2IZWXFqImm2pz2jDBK316VYgXNa5etiMcuvvOeUrxx1SZn CLFfE0XCkUcRs+UajgHfHJ/UveMnh7dc/qesrvqzDvesPj0D1Shpvzsddz9vFQTwFPI1 kMTbTtaxWcNJzej+LuTCfF91CnfWo1LE/fH4Dfwll2Zw96gjLhnDudDBJV7AGN9+cKRs vpkKFqOv6CvqOdubSjDOVzi5CcUHolY0KHYjqrcRKpaDCqTmlowT/BKnFM6bW4aR3Gtf 4AkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=9qRGYE9VepujAcHZSqqCVwT3Q7eiBwVFx2pYpMwBWYk=; b=Fk+89yTwl8BN4V1K9YPUBtfnlVQgLv3qZ2XcrwFfWq0cekPgJaeY+06aKgoi6zeEVW BQUW2jjN0cXglROEWuagbBTNxrbMuJkKCZOHJr4SlOFCL+MhtJZZaFLRLp81bMcqada8 GspSBsIgKTD8akvmnEeJwWSj99AHhjngcw0VzxinQv/38lW1wgYm0BqOZGbXZp8g2buM nWOSf1q5HehT1JRrCB1CqRkCIRV1PRP4eHA8D5WqNVwHGTkMAE4GxeaQcmTl4mDyOxol URxFfMqZf23QhEkcGeIBHAzPi2ltb6decuKC0aBqx3MOSJdGHr+Fh3SC8foQMKs5E19O ku1A== X-Gm-Message-State: AOAM533/9YVbLV3zpJLolRUShgnXdVcWgVjH+SBNO7YHRSusVXO8zwQ1 EKazFN8dTdaShphDqus9WAMXmQe9 X-Google-Smtp-Source: ABdhPJwZNRUzimYYnQ0Jqhu46D11hnpKXJuNWO8oieGYqfBR2gEjj7PW8WJl3juaPayr1R66MffajA== X-Received: by 2002:a5e:c112:: with SMTP id v18mr329060iol.37.1591199021174; Wed, 03 Jun 2020 08:43:41 -0700 (PDT) Received: from aford-OptiPlex-7050.logicpd.com ([174.46.170.158]) by smtp.gmail.com with ESMTPSA id l26sm1237027ild.59.2020.06.03.08.43.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2020 08:43:38 -0700 (PDT) From: Adam Ford To: linux-clk@vger.kernel.org Cc: Adam Ford , Michael Turquette , Stephen Boyd , Rob Herring , Marek Vasut , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V3 1/3] clk: vc5: Allow Versaclock driver to support multiple instances Date: Wed, 3 Jun 2020 10:43:27 -0500 Message-Id: <20200603154329.31579-1-aford173@gmail.com> X-Mailer: git-send-email 2.17.1 Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Currently, the Versaclock driver is only expecting one instance and uses hard-coded names for the various clock names. Unfortunately, this is a problem when there is more than one instance of the driver, because the subsequent instantiations of the driver use the identical name. Each clock after the fist fails to load, because the clock subsystem cannot handle two clocks with identical name. This patch removes the hard-coded name arrays and uses kasprintf to assign clock names based on names of their respective node and parent node which gives each clock a unique identifying name. For a verasaclock node with a name like: versaclock5: versaclock_som@6a The updated clock names would appear like: versaclock_som.mux versaclock_som.out0_sel_i2cb versaclock_som.pfd versaclock_som.pll versaclock_som.fod3 versaclock_som.out4 versaclock_som.fod2 versaclock_som.out3 versaclock_som.fod1 versaclock_som.out2 versaclock_som.fod0 versaclock_som.out1 Signed-off-by: Adam Ford --- V3: Remove 'probed' message V2: No change diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index fa96659f8023..41e3a75963b9 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -161,30 +161,6 @@ struct vc5_driver_data { struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM]; }; -static const char * const vc5_mux_names[] = { - "mux" -}; - -static const char * const vc5_dbl_names[] = { - "dbl" -}; - -static const char * const vc5_pfd_names[] = { - "pfd" -}; - -static const char * const vc5_pll_names[] = { - "pll" -}; - -static const char * const vc5_fod_names[] = { - "fod0", "fod1", "fod2", "fod3", -}; - -static const char * const vc5_clk_out_names[] = { - "out0_sel_i2cb", "out1", "out2", "out3", "out4", -}; - /* * VersaClock5 i2c regmap */ @@ -692,8 +668,7 @@ static int vc5_map_index_to_output(const enum vc5_model model, static const struct of_device_id clk_vc5_of_match[]; -static int vc5_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct vc5_driver_data *vc5; struct clk_init_data init; @@ -742,7 +717,7 @@ static int vc5_probe(struct i2c_client *client, if (!IS_ERR(vc5->pin_clkin)) { vc5->clk_mux_ins |= VC5_MUX_IN_CLKIN; parent_names[init.num_parents++] = - __clk_get_name(vc5->pin_clkin); + __clk_get_name(vc5->pin_clkin); } if (!init.num_parents) { @@ -750,12 +725,13 @@ static int vc5_probe(struct i2c_client *client, return -EINVAL; } - init.name = vc5_mux_names[0]; + init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node); init.ops = &vc5_mux_ops; init.flags = 0; init.parent_names = parent_names; vc5->clk_mux.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux); + kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); goto err_clk; @@ -764,13 +740,16 @@ static int vc5_probe(struct i2c_client *client, if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) { /* Register frequency doubler */ memset(&init, 0, sizeof(init)); - init.name = vc5_dbl_names[0]; + init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl", + client->dev.of_node); init.ops = &vc5_dbl_ops; init.flags = CLK_SET_RATE_PARENT; - init.parent_names = vc5_mux_names; + init.parent_names = parent_names; + parent_names[0] = clk_hw_get_name(&vc5->clk_mux); init.num_parents = 1; vc5->clk_mul.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul); + kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); @@ -780,16 +759,18 @@ static int vc5_probe(struct i2c_client *client, /* Register PFD */ memset(&init, 0, sizeof(init)); - init.name = vc5_pfd_names[0]; + init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node); init.ops = &vc5_pfd_ops; init.flags = CLK_SET_RATE_PARENT; + init.parent_names = parent_names; if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) - init.parent_names = vc5_dbl_names; + parent_names[0] = clk_hw_get_name(&vc5->clk_mul); else - init.parent_names = vc5_mux_names; + parent_names[0] = clk_hw_get_name(&vc5->clk_mux); init.num_parents = 1; vc5->clk_pfd.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd); + kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); goto err_clk; @@ -797,15 +778,17 @@ static int vc5_probe(struct i2c_client *client, /* Register PLL */ memset(&init, 0, sizeof(init)); - init.name = vc5_pll_names[0]; + init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node); init.ops = &vc5_pll_ops; init.flags = CLK_SET_RATE_PARENT; - init.parent_names = vc5_pfd_names; + init.parent_names = parent_names; + parent_names[0] = clk_hw_get_name(&vc5->clk_pfd); init.num_parents = 1; vc5->clk_pll.num = 0; vc5->clk_pll.vc5 = vc5; vc5->clk_pll.hw.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw); + kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); goto err_clk; @@ -815,15 +798,18 @@ static int vc5_probe(struct i2c_client *client, for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) { idx = vc5_map_index_to_output(vc5->chip_info->model, n); memset(&init, 0, sizeof(init)); - init.name = vc5_fod_names[idx]; + init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d", + client->dev.of_node, idx); init.ops = &vc5_fod_ops; init.flags = CLK_SET_RATE_PARENT; - init.parent_names = vc5_pll_names; + init.parent_names = parent_names; + parent_names[0] = clk_hw_get_name(&vc5->clk_pll.hw); init.num_parents = 1; vc5->clk_fod[n].num = idx; vc5->clk_fod[n].vc5 = vc5; vc5->clk_fod[n].hw.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw); + kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); @@ -833,32 +819,36 @@ static int vc5_probe(struct i2c_client *client, /* Register MUX-connected OUT0_I2C_SELB output */ memset(&init, 0, sizeof(init)); - init.name = vc5_clk_out_names[0]; + init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb", + client->dev.of_node); init.ops = &vc5_clk_out_ops; init.flags = CLK_SET_RATE_PARENT; - init.parent_names = vc5_mux_names; + init.parent_names = parent_names; + parent_names[0] = clk_hw_get_name(&vc5->clk_mux); init.num_parents = 1; vc5->clk_out[0].num = idx; vc5->clk_out[0].vc5 = vc5; vc5->clk_out[0].hw.init = &init; ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw); + kfree(init.name); /* clock framework made a copy of the name */ if (ret) { - dev_err(&client->dev, "unable to register %s\n", - init.name); + dev_err(&client->dev, "unable to register %s\n", init.name); goto err_clk; } /* Register FOD-connected OUTx outputs */ for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) { idx = vc5_map_index_to_output(vc5->chip_info->model, n - 1); - parent_names[0] = vc5_fod_names[idx]; + parent_names[0] = clk_hw_get_name(&vc5->clk_fod[idx].hw); if (n == 1) - parent_names[1] = vc5_mux_names[0]; + parent_names[1] = clk_hw_get_name(&vc5->clk_mux); else - parent_names[1] = vc5_clk_out_names[n - 1]; + parent_names[1] = + clk_hw_get_name(&vc5->clk_out[n - 1].hw); memset(&init, 0, sizeof(init)); - init.name = vc5_clk_out_names[idx + 1]; + init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d", + client->dev.of_node, idx + 1); init.ops = &vc5_clk_out_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -866,8 +856,8 @@ static int vc5_probe(struct i2c_client *client, vc5->clk_out[n].num = idx; vc5->clk_out[n].vc5 = vc5; vc5->clk_out[n].hw.init = &init; - ret = devm_clk_hw_register(&client->dev, - &vc5->clk_out[n].hw); + ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[n].hw); + kfree(init.name); /* clock framework made a copy of the name */ if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); From patchwork Wed Jun 3 15:43:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adam Ford X-Patchwork-Id: 11585961 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 026D660D for ; Wed, 3 Jun 2020 15:43:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DDAE620772 for ; Wed, 3 Jun 2020 15:43:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MFh28SEI" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726195AbgFCPno (ORCPT ); Wed, 3 Jun 2020 11:43:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725944AbgFCPnn (ORCPT ); Wed, 3 Jun 2020 11:43:43 -0400 Received: from mail-io1-xd44.google.com (mail-io1-xd44.google.com [IPv6:2607:f8b0:4864:20::d44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B0D9C08C5C0; Wed, 3 Jun 2020 08:43:43 -0700 (PDT) Received: by mail-io1-xd44.google.com with SMTP id j8so2728972iog.13; Wed, 03 Jun 2020 08:43:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Hp0r2xPnJNrha2DVieLRioPgVG67WvOK9q2U4d3AFHc=; b=MFh28SEIZjKIYeTS80r07x+w06bvc1UCEKGMOjk0KHFvIIlbCuO422TotrvXhE0mOu ryVPWQhyUuvGkkEp71ZcHvYE4CigstOKWyNDU0Govmn4wSeZDEOYebIVVpIff0xlgmmF q52W1f2NBZefYBh50hFBUiG7wKEy8Z/YVRf+U21LzCgKuZnErN/KGTZqHPuAsX4WYc4X Vhhx54YLg0frMCcCk3JzL+miR/BADdRhJJZrKm5/NyY4LkUpClQskG+cojjoXlUgvjiH GKxjLgf2oHPYx6zXL6rGVM9/RoOLKtAzr+f7mRuJFAW5qmK2zxgsV4a7XD6XmNvtNGd7 ZSsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Hp0r2xPnJNrha2DVieLRioPgVG67WvOK9q2U4d3AFHc=; b=EKa4Z64HS5evGLp5IR6oX32ZKrXheKCAUoE8MGG7D/siwvmgfXdPwwPQ0hbD52dWwu P4EYDDJjyU0a8qGNA2emtSOyiqgUScB8y6MALDu7xpgdHUoCUHV3liPh+SuaLjZNe0b2 vYVSElwJx+zXG2h+zbems+ShSjTlfXJ3KRCCECRWrbwnyHRuYl6hIDIVFEZ/XtU5fX4+ 4flwq66Cmp3yvjtGj12HVDru+Msf93srUk9mTKJDpMB33a3+6Jpp97CW0RT9znIGPsbQ 4TGXEtR8wAMtPH5MxAzSb2geXS+t3eXO2z/n1I1oYrMUhplSL94tBUDT8OlpdiObsErU /oyw== X-Gm-Message-State: AOAM5327BwZCHTdknVhf36ZnYlM1A3VZINFHdDgneJtHkssxW5Yu/2+M V1TmNdQ9HkU03n4l2ib7Hd1drTKy X-Google-Smtp-Source: ABdhPJwsnQ72Fvrna00tnTvxOZZ8L8lkwgQMAioS/xu3IHnWU2WUl+mCzyHwnBaJ7jXzwSP4dFQJYw== X-Received: by 2002:a6b:f911:: with SMTP id j17mr301135iog.139.1591199022484; Wed, 03 Jun 2020 08:43:42 -0700 (PDT) Received: from aford-OptiPlex-7050.logicpd.com ([174.46.170.158]) by smtp.gmail.com with ESMTPSA id l26sm1237027ild.59.2020.06.03.08.43.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2020 08:43:41 -0700 (PDT) From: Adam Ford To: linux-clk@vger.kernel.org Cc: Adam Ford , Michael Turquette , Stephen Boyd , Rob Herring , Marek Vasut , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V3 2/3] dt: Add additional option bindings for IDT VersaClock Date: Wed, 3 Jun 2020 10:43:28 -0500 Message-Id: <20200603154329.31579-2-aford173@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200603154329.31579-1-aford173@gmail.com> References: <20200603154329.31579-1-aford173@gmail.com> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org The VersaClock driver now supports some additional bindings to support child nodes which can configure optional settings like mode, voltage and slew. This patch updates the binding document to describe what is available in the driver. Signed-off-by: Adam Ford Reviewed-by: Rob Herring --- V3: Re-order binding change and driver change so biding comes first. Move all binding related changes to this patch. diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt index bcff681a4bd0..6165b6ddb1a9 100644 --- a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt +++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt @@ -31,6 +31,29 @@ Required properties: - 5p49v5933 and - 5p49v5935: (optional) property not present or "clkin". +For all output ports, a corresponding, optional child node named OUT1, +OUT2, etc. can represent a each output, and the node can be used to +specify the following: + +- itd,mode: can be one of the following: + - VC5_LVPECL + - VC5_CMOS + - VC5_HCSL33 + - VC5_LVDS + - VC5_CMOS2 + - VC5_CMOSD + - VC5_HCSL25 + +- idt,voltage-microvolts: can be one of the following + - 1800000 + - 2500000 + - 3300000 +- idt,slew-percent: Percent of normal, can be one of + - 80 + - 85 + - 90 + - 100 + ==Mapping between clock specifier and physical pins== When referencing the provided clock in the DT using phandle and @@ -81,6 +104,16 @@ i2c-master-node { /* Connect XIN input to 25MHz reference */ clocks = <&ref25m>; clock-names = "xin"; + + OUT1 { + itd,mode = ; + idt,voltage-microvolts = <1800000>; + idt,slew-percent = <80>; + }; + OUT2 { + ... + }; + ... }; }; diff --git a/include/dt-bindings/clk/versaclock.h b/include/dt-bindings/clk/versaclock.h new file mode 100644 index 000000000000..c6a6a0946564 --- /dev/null +++ b/include/dt-bindings/clk/versaclock.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* This file defines field values used by the versaclock 6 family + * for defining output type + */ + +#define VC5_LVPECL 0 +#define VC5_CMOS 1 +#define VC5_HCSL33 2 +#define VC5_LVDS 3 +#define VC5_CMOS2 4 +#define VC5_CMOSD 5 +#define VC5_HCSL25 6 From patchwork Wed Jun 3 15:43:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Adam Ford X-Patchwork-Id: 11585959 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6707F90 for ; Wed, 3 Jun 2020 15:43:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4A3C220825 for ; Wed, 3 Jun 2020 15:43:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IUrQZkJx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725944AbgFCPnr (ORCPT ); Wed, 3 Jun 2020 11:43:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726207AbgFCPnp (ORCPT ); Wed, 3 Jun 2020 11:43:45 -0400 Received: from mail-il1-x143.google.com (mail-il1-x143.google.com [IPv6:2607:f8b0:4864:20::143]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2EBEBC08C5C0; Wed, 3 Jun 2020 08:43:45 -0700 (PDT) Received: by mail-il1-x143.google.com with SMTP id b5so2946886iln.5; Wed, 03 Jun 2020 08:43:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tLRrk+5TE7AqBI0mMmOMi48T5DlCW6ljfttlxXJKiYE=; b=IUrQZkJxLQS8vRxDz1Ix+0rHj99xB3GbUzrWZj/JZPNQPvkIJu3B16AggQhDBSagKZ Pf1KVl1wtwQGVZmIdODKBgyzQEyhXXXe9DMnsDBbAdxzlq7tN/XHQrx5QSD9hyvfx8Yq 4zspKiKPrPVlC+lrqHYZP306yG7jynMXx96z9NRlWqITDkN4XABIC9Gwk5yAb8mtohsv vyG3Y0JwrmpO2tdQKKFwK0Glt5tx18+kR3WeLqcxI9hhwEIHxluIv3PVSsPo0XA1RlpG eW7S2OGyn9NlAlKNM1UQ3Hwm2SgS+muzoDxTC1Vjodk8bqpgasLPsecs3OjblPcH47l5 WhqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tLRrk+5TE7AqBI0mMmOMi48T5DlCW6ljfttlxXJKiYE=; b=gJtRiALzf23Sb/vndPmJxjj2ss7COxBs/aSi9MO1rchzVz4XhkBX5exijxpy/uY+lI SwoJ4QIvSVK9DOsINotBqKJHhZUMEdsadJNSjEnup5XzX5GDRYFJFBf+/Ri+ycxdDmxY FNAC6MMW28cRLoKJhVuayh6WMP5opQNqGedFepWKL7i2oMt5csy+YyoROnNv7lYmINb0 E3Lhp7m0t9rKkYBKlYbtjATneCOrBpswgl3CgqNxqM3SFioTwTfbtp1urC8BfJhiDpXW xkYVsqeYSPZB5jo83lQdQOp+WcOSqbiPXEXQJgMxSo5oTmf3cereNzLRP5gJJoLZjDIn UwPA== X-Gm-Message-State: AOAM532828iRqd834oMxVAUxSG9T18WJdKed0XxNtEuE14O4kcPaVyQ0 Nvf5ksqnF/KskfDtZZ9pcqn5dCxi X-Google-Smtp-Source: ABdhPJwy5l9sjRB7900J+AVZRjv/sYrReTt7uHRcax/vKGx9WOIeiCHAJoHdz3889FuO3WgMPS3CDg== X-Received: by 2002:a05:6e02:50c:: with SMTP id d12mr170386ils.140.1591199023986; Wed, 03 Jun 2020 08:43:43 -0700 (PDT) Received: from aford-OptiPlex-7050.logicpd.com ([174.46.170.158]) by smtp.gmail.com with ESMTPSA id l26sm1237027ild.59.2020.06.03.08.43.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jun 2020 08:43:43 -0700 (PDT) From: Adam Ford To: linux-clk@vger.kernel.org Cc: Adam Ford , Michael Turquette , Stephen Boyd , Rob Herring , Marek Vasut , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V3 3/3] clk: vc5: Enable addition output configurations of the Versaclock Date: Wed, 3 Jun 2020 10:43:29 -0500 Message-Id: <20200603154329.31579-3-aford173@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200603154329.31579-1-aford173@gmail.com> References: <20200603154329.31579-1-aford173@gmail.com> MIME-Version: 1.0 Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org The existing driver is expecting the Versaclock to be pre-programmed, and only sets the output frequency. Unfortunately, not all devices are pre-programmed, and the Versaclock chip has more options beyond just the frequency. This patch enables the following additional features: - Programmable voltage: 1.8V, 2.5V, or 3.3V​ - Slew Percentage of normal: 85%, 90%, or 100% - Output Type: LVPECL, CMOS, HCSL, or LVDS Signed-off-by: Adam Ford --- V3: Make source code change following the binding changes since there is a dependency and move changes to binding header file to the patch with bindings changes. diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 41e3a75963b9..9a5fb3834b9a 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -24,6 +24,8 @@ #include #include +#include + /* VersaClock5 registers */ #define VC5_OTP_CONTROL 0x00 @@ -89,6 +91,28 @@ /* Clock control register for clock 1,2 */ #define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n)) +#define VC5_CLK_OUTPUT_CFG0_CFG_SHIFT 5 +#define VC5_CLK_OUTPUT_CFG0_CFG_MASK GENMASK(7, VC5_CLK_OUTPUT_CFG0_CFG_SHIFT) + +#define VC5_CLK_OUTPUT_CFG0_CFG_LVPECL (VC5_LVPECL) +#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS (VC5_CMOS) +#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL33 (VC5_HCSL33) +#define VC5_CLK_OUTPUT_CFG0_CFG_LVDS (VC5_LVDS) +#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS2 (VC5_CMOS2) +#define VC5_CLK_OUTPUT_CFG0_CFG_CMOSD (VC5_CMOSD) +#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL25 (VC5_HCSL25) + +#define VC5_CLK_OUTPUT_CFG0_PWR_SHIFT 3 +#define VC5_CLK_OUTPUT_CFG0_PWR_MASK GENMASK(4, VC5_CLK_OUTPUT_CFG0_PWR_SHIFT) +#define VC5_CLK_OUTPUT_CFG0_PWR_18 (0<regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, VC5_CLK_OUTPUT_CFG1_EN_CLKBUF); + if (hwdata->clk_output_cfg0_mask) { + dev_dbg(&vc5->client->dev, "Update output %d mask 0x%0X val 0x%0X\n", + hwdata->num, hwdata->clk_output_cfg0_mask, + hwdata->clk_output_cfg0); + + regmap_update_bits(vc5->regmap, + VC5_CLK_OUTPUT_CFG(hwdata->num, 0), + hwdata->clk_output_cfg0_mask, + hwdata->clk_output_cfg0); + } + return 0; } @@ -666,6 +703,120 @@ static int vc5_map_index_to_output(const enum vc5_model model, } } +static int vc5_update_mode(struct device_node *np_output, + struct vc5_hw_data *clk_out) +{ + u32 value; + + if (!of_property_read_u32(np_output, "idt,mode", &value)) { + clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_CFG_MASK; + switch (value) { + case VC5_CLK_OUTPUT_CFG0_CFG_LVPECL: + case VC5_CLK_OUTPUT_CFG0_CFG_CMOS: + case VC5_CLK_OUTPUT_CFG0_CFG_HCSL33: + case VC5_CLK_OUTPUT_CFG0_CFG_LVDS: + case VC5_CLK_OUTPUT_CFG0_CFG_CMOS2: + case VC5_CLK_OUTPUT_CFG0_CFG_CMOSD: + case VC5_CLK_OUTPUT_CFG0_CFG_HCSL25: + clk_out->clk_output_cfg0 |= + value << VC5_CLK_OUTPUT_CFG0_CFG_SHIFT; + break; + default: + return -EINVAL; + } + } + return 0; +} + +static int vc5_update_power(struct device_node *np_output, + struct vc5_hw_data *clk_out) +{ + u32 value; + + if (!of_property_read_u32(np_output, + "idt,voltage-microvolts", &value)) { + clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_PWR_MASK; + switch (value) { + case 1800000: + clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_18; + break; + case 2500000: + clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_25; + break; + case 3300000: + clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_33; + break; + default: + return -EINVAL; + } + } + return 0; +} + +static int vc5_update_slew(struct device_node *np_output, + struct vc5_hw_data *clk_out) +{ + u32 value; + + if (!of_property_read_u32(np_output, "idt,slew-percent", &value)) { + clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_SLEW_MASK; + switch (value) { + case 80: + clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_80; + break; + case 85: + clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_85; + break; + case 90: + clk_out->clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_90; + break; + case 100: + clk_out->clk_output_cfg0 |= + VC5_CLK_OUTPUT_CFG0_SLEW_100; + break; + default: + return -EINVAL; + } + } + return 0; +} + +static int vc5_get_output_config(struct i2c_client *client, + struct vc5_hw_data *clk_out) +{ + struct device_node *np_output; + char *child_name; + int ret = 0; + + child_name = kasprintf(GFP_KERNEL, "OUT%d", clk_out->num + 1); + np_output = of_get_child_by_name(client->dev.of_node, child_name); + kfree(child_name); + if (!np_output) + goto output_done; + + ret = vc5_update_mode(np_output, clk_out); + if (ret) + goto output_error; + + ret = vc5_update_power(np_output, clk_out); + if (ret) + goto output_error; + + ret = vc5_update_slew(np_output, clk_out); + +output_error: + if (ret) { + dev_err(&client->dev, + "Invalid clock output configuration OUT%d\n", + clk_out->num + 1); + } + + of_node_put(np_output); + +output_done: + return ret; +} + static const struct of_device_id clk_vc5_of_match[]; static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -863,6 +1014,11 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) init.name); goto err_clk; } + + /* Fetch Clock Output configuration from DT (if specified) */ + ret = vc5_get_output_config(client, &vc5->clk_out[n]); + if (ret) + goto err_clk; } ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);