Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp293473imm; Thu, 6 Sep 2018 02:32:49 -0700 (PDT) X-Google-Smtp-Source: ANB0Vdbll5bcq9gx3DZbzKKxTLisWu6OcD8r4qe/ts2K1eViHjS2LmLwSxVSJ206sB1QcL3Dk/78 X-Received: by 2002:a17:902:6806:: with SMTP id h6-v6mr1823218plk.304.1536226369742; Thu, 06 Sep 2018 02:32:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536226369; cv=none; d=google.com; s=arc-20160816; b=lJiRyYjOJBy+CH+bLmkkQvno8ldYrUIBZW6e/pL7QGCjyn9BDaMfMSQ7xezRfU6iTd vV0ZM8h6PZWyVk6SaSP5Z8hcctl0WthV91z0DrBWxu+5tS1c+DWKXNIj70fB6t6Snch5 xnQ9RqoZLIh/d+ahSZZvpqRt4+FH1qu4dYKulqaT5U1ghmmIerGbgBvrDuXeVGXFLxnq 4jDK0pD8ZaxUefhg7u3mdjFQY0lr1uuc+U7kSCeY+aQKh9e9/W3wKJrY6RVhTrUh3eTG HcCE4naqjez6kYep/B0r0fxGjUnmFVKiseJuH1ofiLkXctg1vUKJagXiFSOX68HCviX1 qdAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature; bh=xkc98GbyouHW+qOU3eD2jleCNC5CCKrGkcSf59kxs60=; b=sQP4H5QDs+5uENwD+aT1XUgqfISrRg7jO/o7OulJNd4BIEkx8OXCAiTxEEvqSL2sve cQLy5QW5eth/y+SvyqV04DAvY3yT43IJrDNk02teKSRuUPC6rThNKql5DIpfiUknIvuT UCxG4XJQ4FmqZQmgT1k2PWv0VsffIi5pUAvGcDj4HTaWACKBl8gGkPMW0iqVCYdKjr4l jmhVgQZvyS/Wyr0UyIj1xfTVxWFXxuEMIub6L2CjQZ+Jm696NFJbTYs9DGskfSllwxHW raFGpGMLK/3xSRZLT6SdmAIwQohSpLFJDEAYfXcl2gHx52qx47fmNDbhHxQZRfLbZPKF XYoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=g+8x1rMn; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h9-v6si4445504pgk.121.2018.09.06.02.32.03; Thu, 06 Sep 2018 02:32:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=g+8x1rMn; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728340AbeIFODP (ORCPT + 99 others); Thu, 6 Sep 2018 10:03:15 -0400 Received: from lelv0142.ext.ti.com ([198.47.23.249]:38992 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728098AbeIFODP (ORCPT ); Thu, 6 Sep 2018 10:03:15 -0400 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w869S6qX087576; Thu, 6 Sep 2018 04:28:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1536226086; bh=xkc98GbyouHW+qOU3eD2jleCNC5CCKrGkcSf59kxs60=; h=Subject:To:CC:References:From:Date:In-Reply-To; b=g+8x1rMnBd0atM/giIqWlaEaYOkBB6le1VFlbOtdwbG7gXVXs6h/jmBt95dBg/oc0 Qm4ZVYaWxkAu17dVIdOdvtkKCKYh7T1125iClhy9zLahfTATwMXqCoQlYyiqcHa7X0 SgDZZRMDNK02L3mCrUBc2OsSpdDoSIQLLJmPqv8c= Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w869S6Ye023226; Thu, 6 Sep 2018 04:28:06 -0500 Received: from DFLE104.ent.ti.com (10.64.6.25) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Thu, 6 Sep 2018 04:28:05 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Thu, 6 Sep 2018 04:28:05 -0500 Received: from [172.24.190.233] (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w869S1RC015779; Thu, 6 Sep 2018 04:28:02 -0500 Subject: Re: [PATCH 02/10] phy: Add configuration interface To: Maxime Ripard , Boris Brezillon CC: Thomas Petazzoni , Laurent Pinchart , , Archit Taneja , Andrzej Hajda , Chen-Yu Tsai , , , , Krzysztof Witos , Rafal Ciepiela References: From: Kishon Vijay Abraham I Message-ID: <1ed01c1f-76d5-fa96-572b-9bfd269ad11b@ti.com> Date: Thu, 6 Sep 2018 14:57:58 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On Wednesday 05 September 2018 02:46 PM, Maxime Ripard wrote: > The phy framework is only allowing to configure the power state of the PHY > using the init and power_on hooks, and their power_off and exit > counterparts. > > While it works for most, simple, PHYs supported so far, some more advanced > PHYs need some configuration depending on runtime parameters. These PHYs > have been supported by a number of means already, often by using ad-hoc > drivers in their consumer drivers. > > That doesn't work too well however, when a consumer device needs to deal > multiple PHYs, or when multiple consumers need to deal with the same PHY (a > DSI driver and a CSI driver for example). > > So we'll add a new interface, through two funtions, phy_validate and > phy_configure. The first one will allow to check that a current > configuration, for a given mode, is applicable. It will also allow the PHY > driver to tune the settings given as parameters as it sees fit. > > phy_configure will actually apply that configuration in the phy itself. > > Signed-off-by: Maxime Ripard > --- > drivers/phy/phy-core.c | 62 ++++++++++++++++++++++++++++++++++++++++++- > include/linux/phy/phy.h | 42 ++++++++++++++++++++++++++++- > 2 files changed, 104 insertions(+) > > diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c > index 35fd38c5a4a1..6eaf655e370f 100644 > --- a/drivers/phy/phy-core.c > +++ b/drivers/phy/phy-core.c > @@ -408,6 +408,68 @@ int phy_calibrate(struct phy *phy) > EXPORT_SYMBOL_GPL(phy_calibrate); > > /** > + * phy_configure() - Changes the phy parameters > + * @phy: the phy returned by phy_get() > + * @mode: phy_mode the configuration is applicable to. mode should be used if the same PHY can be configured in multiple modes. But with phy_set_mode() and phy_calibrate() we could achieve the same. > + * @opts: New configuration to apply Should these configuration come from the consumer driver? Can't the helper functions be directly invoked by the PHY driver for the configuration. > + * > + * Used to change the PHY parameters. phy_init() must have > + * been called on the phy. > + * > + * Returns: 0 if successful, an negative error code otherwise > + */ > +int phy_configure(struct phy *phy, enum phy_mode mode, > + union phy_configure_opts *opts) > +{> + int ret; > + > + if (!phy) > + return -EINVAL; > + > + if (!phy->ops->configure) > + return 0; > + > + mutex_lock(&phy->mutex); > + ret = phy->ops->configure(phy, mode, opts); > + mutex_unlock(&phy->mutex); > + > + return ret; > +} > + > +/** > + * phy_validate() - Checks the phy parameters > + * @phy: the phy returned by phy_get() > + * @mode: phy_mode the configuration is applicable to. > + * @opts: Configuration to check > + * > + * Used to check that the current set of parameters can be handled by > + * the phy. Implementations are free to tune the parameters passed as > + * arguments if needed by some implementation detail or > + * constraints. It will not change any actual configuration of the > + * PHY, so calling it as many times as deemed fit will have no side > + * effect. > + * > + * Returns: 0 if successful, an negative error code otherwise > + */ > +int phy_validate(struct phy *phy, enum phy_mode mode, > + union phy_configure_opts *opts) IIUC the consumer driver will pass configuration options (or PHY parameters) which will be validated by the PHY driver and in some cases the PHY driver can modify the configuration options? And these modified configuration options will again be given to phy_configure? Looks like it's a round about way of doing the same thing. > +{ > + int ret; > + > + if (!phy) > + return -EINVAL; > + > + if (!phy->ops->validate) > + return 0; > + > + mutex_lock(&phy->mutex); > + ret = phy->ops->validate(phy, mode, opts); > + mutex_unlock(&phy->mutex); > + > + return ret; > +} > + > +/** > * _of_phy_get() - lookup and obtain a reference to a phy by phandle > * @np: device_node for which to get the phy > * @index: the index of the phy > diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h > index 9cba7fe16c23..3cc315dcfcd0 100644 > --- a/include/linux/phy/phy.h > +++ b/include/linux/phy/phy.h > @@ -44,6 +44,12 @@ enum phy_mode { > }; > > /** > + * union phy_configure_opts - Opaque generic phy configuration > + */ > +union phy_configure_opts { > +}; > + > +/** > * struct phy_ops - set of function pointers for performing phy operations > * @init: operation to be performed for initializing phy > * @exit: operation to be performed while exiting > @@ -60,6 +66,38 @@ struct phy_ops { > int (*power_on)(struct phy *phy); > int (*power_off)(struct phy *phy); > int (*set_mode)(struct phy *phy, enum phy_mode mode); > + > + /** > + * @configure: > + * > + * Optional. > + * > + * Used to change the PHY parameters. phy_init() must have > + * been called on the phy. > + * > + * Returns: 0 if successful, an negative error code otherwise > + */ > + int (*configure)(struct phy *phy, enum phy_mode mode, > + union phy_configure_opts *opts); > + > + /** > + * @validate: > + * > + * Optional. > + * > + * Used to check that the current set of parameters can be > + * handled by the phy. Implementations are free to tune the > + * parameters passed as arguments if needed by some > + * implementation detail or constraints. It must not change > + * any actual configuration of the PHY, so calling it as many > + * times as deemed fit by the consumer must have no side > + * effect. > + * > + * Returns: 0 if the configuration can be applied, an negative > + * error code otherwise > + */ > + int (*validate)(struct phy *phy, enum phy_mode mode, > + union phy_configure_opts *opts); > int (*reset)(struct phy *phy); > int (*calibrate)(struct phy *phy); > struct module *owner; > @@ -164,6 +202,10 @@ int phy_exit(struct phy *phy); > int phy_power_on(struct phy *phy); > int phy_power_off(struct phy *phy); > int phy_set_mode(struct phy *phy, enum phy_mode mode); > +int phy_configure(struct phy *phy, enum phy_mode mode, > + union phy_configure_opts *opts); > +int phy_validate(struct phy *phy, enum phy_mode mode, > + union phy_configure_opts *opts); Stub function when CONFIG_GENERIC_PHY is not set is also required. Thanks Kishon