* RE: [PATCH v3 2/2] misc: Add Xilinx ZYNQMP VCU logicoreIP init driver
From: Dhaval Rajeshbhai Shah @ 2017-12-15 6:00 UTC (permalink / raw)
To: Randy Dunlap, arnd-r2nGTMty4D4@public.gmane.org,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org,
pombredanne-od1rfyK75/E@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org, Hyun Kwon
In-Reply-To: <29198c0a-783e-8aa0-00e4-44b1fa1acef7-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 19325 bytes --]
Hi Randy,
Thanks a lot for the review.
> -----Original Message-----
> From: Randy Dunlap [mailto:rdunlap@infradead.org]
> Sent: Thursday, December 14, 2017 10:43 AM
> To: Dhaval Rajeshbhai Shah <DSHAH@xilinx.com>; arnd@arndb.de;
> gregkh@linuxfoundation.org; pombredanne@nexb.com; robh+dt@kernel.org;
> mark.rutland@arm.com
> Cc: devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> michal.simek@xilinx.com; Hyun Kwon <hyunk@xilinx.com>; Dhaval Rajeshbhai
> Shah <DSHAH@xilinx.com>
> Subject: Re: [PATCH v3 2/2] misc: Add Xilinx ZYNQMP VCU logicoreIP init driver
>
> On 12/13/2017 09:55 PM, Dhaval Shah wrote:
> > Xilinx ZYNQMP logicoreIP Init driver is based on the new LogiCoreIP
> > design created. This driver provides the processing system and
> > programmable logic isolation. Set the frequency based on the clock
> > information get from the logicoreIP register set.
> >
> > It is put in drivers/misc as there is no subsystem for this logicoreIP.
> >
> > Signed-off-by: Dhaval Shah <dshah@xilinx.com>
> > ---
> > Changes since v3:
> > No Changes.
> > Changes since v2:
> > * Removed the "default n" from the Kconfig
> > * More help text added to explain more about the logicoreIP driver
> > * SPDX id is relocated at top of the file with // style comment
> > * Removed the export API and header file and make it a single driver
> > which provides logocoreIP init.
> > * Provide the information in commit message as well for the why driver
> > in drivers/misc.
> >
> > drivers/misc/Kconfig | 15 ++
> > drivers/misc/Makefile | 1 +
> > drivers/misc/xlnx_vcu.c | 629
> > ++++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 645 insertions(+)
> > create mode 100644 drivers/misc/xlnx_vcu.c
> >
> > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index
> > f1a5c23..24ea516 100644
> > --- a/drivers/misc/Kconfig
> > +++ b/drivers/misc/Kconfig
> > @@ -496,6 +496,21 @@ config PCI_ENDPOINT_TEST
> > Enable this configuration option to enable the host side test driver
> > for PCI Endpoint.
> >
> > +config XILINX_VCU
> > + tristate "Xilinx VCU logicoreIP Init"
> > + help
>
> Please indent the help text (below) by 2 additional spaces, as documented in
> coding-style.rst.
I will update this.
>
> > + Provides the driver to enable and disable the isolation between the
> > + processing system and programmable logic part by using the
> logicoreIP
> > + register set. This driver also configure the frequency based on
> > +the
>
> configures
>
I will update this.
> > + clock information get from the logicoreIP register set.
>
> drop ^get^
>
I will update this.
> > +
> > + If you say yes here you get support for the logcoreIP.
>
> logicoreIP.
>
> > +
> > + If unsure, say N.
> > +
> > + To compile this driver as a module, choose M here: the
> > + module will be called xlnx_vcu.
> > +
> > source "drivers/misc/c2port/Kconfig"
> > source "drivers/misc/eeprom/Kconfig"
> > source "drivers/misc/cb710/Kconfig"
> > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index
> > 5ca5f64..a6bd0b1 100644
> > --- a/drivers/misc/Makefile
> > +++ b/drivers/misc/Makefile
> > @@ -55,6 +55,7 @@ obj-$(CONFIG_CXL_BASE) += cxl/
> > obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o
> > obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
> > obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
> > +obj-$(CONFIG_XILINX_VCU) += xlnx_vcu.o
> >
> > lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
> > lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
> > diff --git a/drivers/misc/xlnx_vcu.c b/drivers/misc/xlnx_vcu.c new
> > file mode 100644 index 0000000..41819f0
> > --- /dev/null
> > +++ b/drivers/misc/xlnx_vcu.c
> > @@ -0,0 +1,629 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Xilinx VCU Init
> > + *
> > + * Copyright (C) 2016 - 2017 Xilinx, Inc.
> > + *
> > + * Contacts Dhaval Shah <dshah@xilinx.com>
> > + */
> > +#include <linux/clk.h>
> > +#include <linux/device.h>
> > +#include <linux/errno.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/platform_device.h>
> > +> +/* Address map for different registers implemented in the VCU
> > +> +LogiCORE IP. */
>
> [snip]
>
>
> > +/**
> > + * xvcu_read - Read from the VCU register space
> > + * @iomem: vcu reg space base address
> > + * @offset: vcu reg offset from base
> > + *
> > + * Return: Returns 32bit value from VCU register specified
> > + *
> > + */
> > +static u32 xvcu_read(void __iomem *iomem, u32 offset)
>
> You could inline the read() and write() functions...
>
I will check and will update if required.
> > +{
> > + return ioread32(iomem + offset);
> > +}
> > +
> > +/**
> > + * xvcu_write - Write to the VCU register space
> > + * @iomem: vcu reg space base address
> > + * @offset: vcu reg offset from base
> > + * @value: Value to write
> > + */
> > +static void xvcu_write(void __iomem *iomem, u32 offset, u32 value) {
> > + iowrite32(value, iomem + offset);
> > +}
> > +
> > +/**
> > + * xvcu_write_field_reg - Write to the vcu reg field
> > + * @iomem: vcu reg space base address
> > + * @offset: vcu reg offset from base
> > + * @field: vcu reg field to write to
> > + * @mask: vcu reg mask
> > + * @shift: vcu reg number of bits to shift the bitfield
> > + */
> > +static void xvcu_write_field_reg(void __iomem *iomem, int offset,
> > + u32 field, u32 mask, int shift)
> > +{
> > + u32 val = xvcu_read(iomem, offset);
> > +
> > + val &= ~(mask << shift);
> > + val |= (field & mask) << shift;
> > +
> > + xvcu_write(iomem, offset, val);
> > +}
> > +
> > +/**
> > + * xvcu_set_vcu_pll_info - Set the VCU PLL info
> > + * @xvcu: Pointer to the xvcu_device structure
> > + *
> > + * Programming the VCU PLL based on the user configuration
> > + * (ref clock freq, core clock freq, mcu clock freq).
> > + * Core clock frequency has higher priority than mcu clock frequency
> > + * Errors in following cases
> > + * - When mcu or clock clock get from logicoreIP is 0
> > + * - When VCU PLL DIV related bits value other than 1
> > + * - When proper data not found for given data
> > + * - When sis570_1 clocksource related operation failed
> > + *
> > + * Return: Returns status, either success or error+reason
> > + */
> > +static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu) {
> > + u32 refclk, coreclk, mcuclk, inte, deci;
> > + u32 divisor_mcu, divisor_core, fvco;
> > + u32 clkoutdiv, vcu_pll_ctrl, pll_clk;
> > + u32 cfg_val, mod, ctrl;
> > + int ret;
> > + unsigned int i;
> > + const struct xvcu_pll_cfg *found = NULL;
> > +
> > + inte = xvcu_read(xvcu->logicore_reg_ba, VCU_PLL_CLK);
> > + deci = xvcu_read(xvcu->logicore_reg_ba, VCU_PLL_CLK_DEC);
> > + coreclk = xvcu_read(xvcu->logicore_reg_ba, VCU_CORE_CLK) * MHZ;
> > + mcuclk = xvcu_read(xvcu->logicore_reg_ba, VCU_MCU_CLK) * MHZ;
> > + if (!mcuclk || !coreclk) {
> > + dev_err(xvcu->dev, "Invalid mcu and core clock data\n");
> > + return -EINVAL;
> > + }
> > +
> > + refclk = (inte * MHZ) + (deci * (MHZ / FRAC));
> > + dev_dbg(xvcu->dev, "Ref clock from logicoreIP is %uHz\n", refclk);
> > + dev_dbg(xvcu->dev, "Core clock from logicoreIP is %uHz\n", coreclk);
> > + dev_dbg(xvcu->dev, "Mcu clock from logicoreIP is %uHz\n", mcuclk);
> > +
> > + clk_disable_unprepare(xvcu->pll_ref);
> > + ret = clk_set_rate(xvcu->pll_ref, refclk);
> > + if (ret)
> > + dev_warn(xvcu->dev, "failed to set logicoreIP refclk rate\n");
> > +
> > + ret = clk_prepare_enable(xvcu->pll_ref);
> > + if (ret) {
> > + dev_err(xvcu->dev, "failed to enable pll_ref clock source\n");
> > + return ret;
> > + }
> > +
> > + refclk = clk_get_rate(xvcu->pll_ref);
> > +
> > + /* The divide-by-2 should be always enabled (==1)
>
> multi-line comment style:
> /*
> * The divide-by-2 should always be enabled (==1)
>
I will update this.
> > + * to meet the timing in the design.
> > + * Otherwise, it's an error
> > + */
> > + vcu_pll_ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_PLL_CTRL);
> > + clkoutdiv = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT;
> > + clkoutdiv = clkoutdiv && VCU_PLL_CTRL_CLKOUTDIV_MASK;
> > + if (clkoutdiv != 1) {
> > + dev_err(xvcu->dev, "clkoutdiv value is invalid\n");
> > + return -EINVAL;
> > + }
> > +
> > + for (i = ARRAY_SIZE(xvcu_pll_cfg) - 1; i > 0; i--) {
> > + const struct xvcu_pll_cfg *cfg = &xvcu_pll_cfg[i];
> > +
> > + fvco = cfg->fbdiv * refclk;
> > + if (fvco >= FVCO_MIN && fvco <= FVCO_MAX) {
> > + pll_clk = fvco / VCU_PLL_DIV2;
> > + if (fvco % VCU_PLL_DIV2 != 0)
> > + pll_clk++;
> > + mod = pll_clk % coreclk;
> > + if (mod < LIMIT) {
> > + divisor_core = pll_clk / coreclk;
> > + } else if (coreclk - mod < LIMIT) {
> > + divisor_core = pll_clk / coreclk;
> > + divisor_core++;
> > + } else {
> > + continue;
> > + }
> > + if (divisor_core >= DIVISOR_MIN &&
> > + divisor_core <= DIVISOR_MAX) {
> > + found = cfg;
> > + divisor_mcu = pll_clk / mcuclk;
> > + mod = pll_clk % mcuclk;
> > + if (mcuclk - mod < LIMIT)
> > + divisor_mcu++;
> > + break;
> > + }
> > + }
> > + }
> > +
> > + if (!found) {
> > + dev_err(xvcu->dev, "Invalid clock combination.\n");
> > + return -EINVAL;
> > + }
> > +
> > + xvcu->coreclk = pll_clk / divisor_core;
> > + mcuclk = pll_clk / divisor_mcu;
> > + dev_dbg(xvcu->dev, "Actual Ref clock freq is %uHz\n", refclk);
> > + dev_dbg(xvcu->dev, "Actual Core clock freq is %uHz\n", xvcu->coreclk);
> > + dev_dbg(xvcu->dev, "Actual Mcu clock freq is %uHz\n", mcuclk);
> > +
> > + vcu_pll_ctrl &= ~(VCU_PLL_CTRL_FBDIV_MASK <<
> VCU_PLL_CTRL_FBDIV_SHIFT);
> > + vcu_pll_ctrl |= (found->fbdiv & VCU_PLL_CTRL_FBDIV_MASK) <<
> > + VCU_PLL_CTRL_FBDIV_SHIFT;
> > + vcu_pll_ctrl &= ~(VCU_PLL_CTRL_POR_IN_MASK <<
> > + VCU_PLL_CTRL_POR_IN_SHIFT);
> > + vcu_pll_ctrl |= (VCU_PLL_CTRL_DEFAULT &
> VCU_PLL_CTRL_POR_IN_MASK) <<
> > + VCU_PLL_CTRL_POR_IN_SHIFT;
> > + vcu_pll_ctrl &= ~(VCU_PLL_CTRL_PWR_POR_MASK <<
> > + VCU_PLL_CTRL_PWR_POR_SHIFT);
> > + vcu_pll_ctrl |= (VCU_PLL_CTRL_DEFAULT &
> VCU_PLL_CTRL_PWR_POR_MASK) <<
> > + VCU_PLL_CTRL_PWR_POR_SHIFT;
> > + xvcu_write(xvcu->vcu_slcr_ba, VCU_PLL_CTRL, vcu_pll_ctrl);
> > +
> > + /* Set divisor for the core and mcu clock */
> > + ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_ENC_CORE_CTRL);
> > + ctrl &= ~(VCU_PLL_DIVISOR_MASK << VCU_PLL_DIVISOR_SHIFT);
> > + ctrl |= (divisor_core & VCU_PLL_DIVISOR_MASK) <<
> > + VCU_PLL_DIVISOR_SHIFT;
> > + ctrl &= ~(VCU_SRCSEL_MASK << VCU_SRCSEL_SHIFT);
> > + ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) <<
> VCU_SRCSEL_SHIFT;
> > + xvcu_write(xvcu->vcu_slcr_ba, VCU_ENC_CORE_CTRL, ctrl);
> > +
> > + ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_DEC_CORE_CTRL);
> > + ctrl &= ~(VCU_PLL_DIVISOR_MASK << VCU_PLL_DIVISOR_SHIFT);
> > + ctrl |= (divisor_core & VCU_PLL_DIVISOR_MASK) <<
> > + VCU_PLL_DIVISOR_SHIFT;
> > + ctrl &= ~(VCU_SRCSEL_MASK << VCU_SRCSEL_SHIFT);
> > + ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) <<
> VCU_SRCSEL_SHIFT;
> > + xvcu_write(xvcu->vcu_slcr_ba, VCU_DEC_CORE_CTRL, ctrl);
> > +
> > + ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_ENC_MCU_CTRL);
> > + ctrl &= ~(VCU_PLL_DIVISOR_MASK << VCU_PLL_DIVISOR_SHIFT);
> > + ctrl |= (divisor_mcu & VCU_PLL_DIVISOR_MASK) <<
> VCU_PLL_DIVISOR_SHIFT;
> > + ctrl &= ~(VCU_SRCSEL_MASK << VCU_SRCSEL_SHIFT);
> > + ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) <<
> VCU_SRCSEL_SHIFT;
> > + xvcu_write(xvcu->vcu_slcr_ba, VCU_ENC_MCU_CTRL, ctrl);
> > +
> > + ctrl = xvcu_read(xvcu->vcu_slcr_ba, VCU_DEC_MCU_CTRL);
> > + ctrl &= ~(VCU_PLL_DIVISOR_MASK << VCU_PLL_DIVISOR_SHIFT);
> > + ctrl |= (divisor_mcu & VCU_PLL_DIVISOR_MASK) <<
> VCU_PLL_DIVISOR_SHIFT;
> > + ctrl &= ~(VCU_SRCSEL_MASK << VCU_SRCSEL_SHIFT);
> > + ctrl |= (VCU_SRCSEL_PLL & VCU_SRCSEL_MASK) <<
> VCU_SRCSEL_SHIFT;
> > + xvcu_write(xvcu->vcu_slcr_ba, VCU_DEC_MCU_CTRL, ctrl);
> > +
> > + /* Set RES, CP, LFHF, LOCK_CNT and LOCK_DLY cfg values */
> > + cfg_val = (found->res << VCU_PLL_CFG_RES_SHIFT) |
> > + (found->cp << VCU_PLL_CFG_CP_SHIFT) |
> > + (found->lfhf << VCU_PLL_CFG_LFHF_SHIFT) |
> > + (found->lock_cnt << VCU_PLL_CFG_LOCK_CNT_SHIFT) |
> > + (found->lock_dly << VCU_PLL_CFG_LOCK_DLY_SHIFT);
> > + xvcu_write(xvcu->vcu_slcr_ba, VCU_PLL_CFG, cfg_val);
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * xvcu_set_pll - PLL init sequence
> > + * @xvcu: Pointer to the xvcu_device structure
> > + *
> > + * Call the api to set the PLL info and once that is done then
> > + * init the PLL sequence to make the PLL stable.
> > + *
> > + * Return: Returns status, either success or error+reason
> > + */
> > +static int xvcu_set_pll(struct xvcu_device *xvcu) {
> > + u32 lock_status;
> > + unsigned long timeout;
> > + int ret;
> > +
> > + ret = xvcu_set_vcu_pll_info(xvcu);
> > + if (ret) {
> > + dev_err(xvcu->dev, "failed to set pll info\n");
> > + return ret;
> > + }
> > +
> > + xvcu_write_field_reg(xvcu->vcu_slcr_ba, VCU_PLL_CTRL,
> > + 1, VCU_PLL_CTRL_BYPASS_MASK,
> > + VCU_PLL_CTRL_BYPASS_SHIFT);
> > + xvcu_write_field_reg(xvcu->vcu_slcr_ba, VCU_PLL_CTRL,
> > + 1, VCU_PLL_CTRL_RESET_MASK,
> > + VCU_PLL_CTRL_RESET_SHIFT);
> > + xvcu_write_field_reg(xvcu->vcu_slcr_ba, VCU_PLL_CTRL,
> > + 0, VCU_PLL_CTRL_RESET_MASK,
> > + VCU_PLL_CTRL_RESET_SHIFT);
> > + /* Defined the timeout for the max time to wait the
>
> comment style.
>
I will update this.
> > + * PLL_STATUS to be locked.
> > + */
> > + timeout = jiffies + msecs_to_jiffies(2000);
> > + do {
> > + lock_status = xvcu_read(xvcu->vcu_slcr_ba, VCU_PLL_STATUS);
> > + if (lock_status & VCU_PLL_STATUS_LOCK_STATUS_MASK) {
> > + xvcu_write_field_reg(xvcu->vcu_slcr_ba,
> VCU_PLL_CTRL,
> > + 0, VCU_PLL_CTRL_BYPASS_MASK,
> > + VCU_PLL_CTRL_BYPASS_SHIFT);
> > + return 0;
> > + }
> > + } while (!time_after(jiffies, timeout));
> > +
> > + /* PLL is not locked even after the timeout of the 2sec */
> > + dev_err(xvcu->dev, "PLL is not locked\n");
> > + return -ETIMEDOUT;
> > +}
> > +
> > +/**
> > + * xvcu_probe - Probe existence of the logicoreIP
> > + * and initialize PLL
> > + *
> > + * @pdev: Pointer to the platform_device structure
> > + *
> > + * Return: Returns 0 on success
> > + * Negative error code otherwise
> > + */
> > +static int xvcu_probe(struct platform_device *pdev) {
> > + struct resource *res;
> > + struct xvcu_device *xvcu;
> > + int ret;
> > +
> > + xvcu = devm_kzalloc(&pdev->dev, sizeof(*xvcu), GFP_KERNEL);
> > + if (!xvcu)
> > + return -ENOMEM;
> > +
> > + xvcu->dev = &pdev->dev;
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "vcu_slcr");
> > + if (!res) {
> > + dev_err(&pdev->dev, "get vcu_slcr memory resource
> failed.\n");
> > + return -ENODEV;
> > + }
> > +
> > + xvcu->vcu_slcr_ba = devm_ioremap_nocache(&pdev->dev,
> > + res->start, resource_size(res));
> > + if (!xvcu->vcu_slcr_ba) {
> > + dev_err(&pdev->dev, "vcu_slcr register mapping failed.\n");
> > + return -ENOMEM;
> > + }
> > +
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "logicore");
> > + if (!res) {
> > + dev_err(&pdev->dev, "get logicore memory resource
> failed.\n");
> > + return -ENODEV;
> > + }
> > +
> > + xvcu->logicore_reg_ba = devm_ioremap_nocache(&pdev->dev,
> > + res->start, resource_size(res));
> > + if (!xvcu->logicore_reg_ba) {
> > + dev_err(&pdev->dev, "logicore register mapping failed.\n");
> > + return -ENOMEM;
> > + }
> > +
> > + xvcu->aclk = devm_clk_get(&pdev->dev, "aclk");
> > + if (IS_ERR(xvcu->aclk)) {
> > + dev_err(&pdev->dev, "Could not get aclk clock\n");
> > + return PTR_ERR(xvcu->aclk);
> > + }
> > +
> > + xvcu->pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
> > + if (IS_ERR(xvcu->pll_ref)) {
> > + dev_err(&pdev->dev, "Could not get pll_ref clock\n");
> > + return PTR_ERR(xvcu->pll_ref);
> > + }
> > +
> > + ret = clk_prepare_enable(xvcu->aclk);
> > + if (ret) {
> > + dev_err(&pdev->dev, "aclk clock enable failed\n");
> > + return ret;
> > + }
> > +
> > + ret = clk_prepare_enable(xvcu->pll_ref);
> > + if (ret) {
> > + dev_err(&pdev->dev, "pll_ref clock enable failed\n");
> > + goto error_aclk;
> > + }
> > +
> > + /* Do the Gasket isolation and put the VCU out of reset
>
> comment style.
>
I will update this.
> > + * Bit 0 : Gasket isolation
> > + * Bit 1 : put VCU out of reset
> > + */
> > + xvcu_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT,
> > +VCU_GASKET_VALUE);
> > +
> > + /* Do the PLL Settings based on the ref clk,core and mcu clk freq */
> > + ret = xvcu_set_pll(xvcu);
> > + if (ret) {
> > + dev_err(&pdev->dev, "Failed to set the pll\n");
> > + goto error_pll_ref;
> > + }
> > +
> > + dev_set_drvdata(&pdev->dev, xvcu);
> > +
> > + dev_info(&pdev->dev, "%s: Probed successfully\n", __func__);
> > +
> > + return 0;
> > +
> > +error_pll_ref:
> > + clk_disable_unprepare(xvcu->pll_ref);
> > +error_aclk:
> > + clk_disable_unprepare(xvcu->aclk);
> > + return ret;
> > +}
> > +
> > +/**
> > + * xvcu_remove - Insert gasket isolation
> > + * and disable the clock
> > + * @pdev: Pointer to the platform_device structure
> > + *
> > + * Return: Returns 0 on success
> > + * Negative error code otherwise
> > + */
> > +static int xvcu_remove(struct platform_device *pdev) {
> > + struct xvcu_device *xvcu;
> > +
> > + xvcu = platform_get_drvdata(pdev);
> > + if (!xvcu)
> > + return -ENODEV;
> > +
> > + /* Add the the Gasket isolation and put the VCU in reset.
>
> style.
>
I will update this.
> > + */
> > + xvcu_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0);
> > +
> > + clk_disable_unprepare(xvcu->pll_ref);
> > + clk_disable_unprepare(xvcu->aclk);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id xvcu_of_id_table[] = {
> > + { .compatible = "xlnx,vcu" },
> > + { .compatible = "xlnx,vcu-logicoreip-1.0" },
> > + { }
> > +};
> > +MODULE_DEVICE_TABLE(of, xvcu_of_id_table);
> > +
> > +static struct platform_driver xvcu_driver = {
> > + .driver = {
> > + .name = "xilinx-vcu",
> > + .of_match_table = xvcu_of_id_table,
> > + },
> > + .probe = xvcu_probe,
> > + .remove = xvcu_remove,
> > +};
> > +
> > +module_platform_driver(xvcu_driver);
> > +
> > +MODULE_AUTHOR("Dhaval Shah <dshah@xilinx.com>");
> > +MODULE_DESCRIPTION("Xilinx VCU init Driver"); MODULE_LICENSE("GPL
> > +v2");
> >
>
> The code has several divide operations. Does it build OK for 32-bit target?
>
Yes. I have verified on both 32 bit and 64 bit target.
> --
> ~Randy
Thanks & Regards,
Dhaval
N§²æìr¸yúèØb²X¬¶Ç§vØ^)Þº{.nÇ+·zøzÚÞz)í
æèw*\x1fjg¬±¨\x1e¶Ý¢j.ïÛ°\½½MúgjÌæa×\x02' ©Þ¢¸\f¢·¦j:+v¨wèjØm¶ÿ¾\a«êçzZ+ùÝ¢j"ú!¶i
^ permalink raw reply
* Re: [PATCH v7 0/6] Mediatek MT2712 clock and scpsys support
From: Weiyi Lu @ 2017-12-15 5:50 UTC (permalink / raw)
To: Matthias Brugger
Cc: Stephen Boyd, Mike Turquette, Rob Herring, James Liao, Fan Chen,
devicetree, linux-arm-kernel, linux-kernel, linux-mediatek,
linux-clk, srv_heupstream
In-Reply-To: <1511854102-23195-2-git-send-email-weiyi.lu@mediatek.com>
On Tue, 2017-11-28 at 15:28 +0800, Weiyi Lu wrote:
Hi Matthias,
Just gentle ping. Many thanks.
> This series is based on v4.15-rc1 and composed of
> scpsys control (PATCH 1-4) and device tree (PATCH 5-6)
>
> changes since v6:
> - Rebase to v4.15-rc1.
>
> changes since v5:
> - Refine bus protection with proper variable name
> and better implementation for the if statement.
>
> changes since v4:
> - Refine scpsys and infracfg for bus protection by passing
> a boolean flag to determine the register update method
>
> changes since v3:
> - Rebase to v4.14-rc1.
>
> changes since v2:
> - ensure the clocks used by clocksource driver are registered
> before clocksource init() by using CLK_OF_DECLARE()
> - correct the frequency of clk32k/clkrtc_ext/clkrtc_int
>
> changes since v1:
> - Rebase to v4.13-next-soc.
> - Refine scpsys and infracfg for bus protection.
>
> *** BLURB HERE ***
>
> Weiyi Lu (6):
> dt-bindings: soc: add MT2712 power dt-bindings
> soc: mediatek: extend bus protection API
> soc: mediatek: add dependent clock jpgdec/audio for scpsys
> soc: mediatek: add MT2712 scpsys support
> arm: dts: mt2712: Add clock controller device nodes
> arm: dts: Add power controller device node of MT2712
>
> .../devicetree/bindings/soc/mediatek/scpsys.txt | 3 +
> arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 131 +++++++++++++++++++
> drivers/soc/mediatek/mtk-infracfg.c | 26 +++-
> drivers/soc/mediatek/mtk-scpsys.c | 140 ++++++++++++++++++---
> include/dt-bindings/power/mt2712-power.h | 26 ++++
> include/linux/soc/mediatek/infracfg.h | 7 +-
> 6 files changed, 311 insertions(+), 22 deletions(-)
> create mode 100644 include/dt-bindings/power/mt2712-power.h
>
^ permalink raw reply
* Re: [PATCH 5/5] PCI: cadence: add EndPoint Controller driver for Cadence PCIe controller
From: Kishon Vijay Abraham I @ 2017-12-15 5:49 UTC (permalink / raw)
To: Cyrille Pitchen, Lorenzo Pieralisi
Cc: bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, linux-pci-u79uwXL29TY76Z2rM5mHXA,
adouglas-vna1KIf7WgpBDgjK7y7TUQ, stelford-vna1KIf7WgpBDgjK7y7TUQ,
dgary-vna1KIf7WgpBDgjK7y7TUQ, kgopi-vna1KIf7WgpBDgjK7y7TUQ,
eandrews-vna1KIf7WgpBDgjK7y7TUQ,
thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
sureshp-vna1KIf7WgpBDgjK7y7TUQ, nsekhar-l0cyMroinI0,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, robh-DgEjT+Ai2ygdnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <e43929c8-e283-f774-eca3-3b0ffcdfb49d-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Hi Cyrille,
On Thursday 14 December 2017 10:33 PM, Cyrille Pitchen wrote:
> Le 13/12/2017 à 17:50, Cyrille Pitchen a écrit :
>> Hi Kishon,
>>
>> Le 05/12/2017 à 10:19, Kishon Vijay Abraham I a écrit :
>>> Hi,
>>>
>>> On Friday 01 December 2017 05:50 PM, Lorenzo Pieralisi wrote:
>>>> On Thu, Nov 23, 2017 at 04:01:50PM +0100, Cyrille Pitchen wrote:
>>>>> This patch adds support to the Cadence PCIe controller in endpoint mode.
>>>>
>>>> Please add a brief description to the log to describe the most salient
>>>> features.
>>>>
>>>>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
>>>>> ---
>>>>> drivers/pci/cadence/Kconfig | 9 +
>>>>> drivers/pci/cadence/Makefile | 1 +
>>>>> drivers/pci/cadence/pcie-cadence-ep.c | 553 ++++++++++++++++++++++++++++++++++
>>>>> 3 files changed, 563 insertions(+)
>>>>> create mode 100644 drivers/pci/cadence/pcie-cadence-ep.c
> [...]
>>>>> +static int cdns_pcie_ep_write_header(struct pci_epc *epc,
>>>>> + struct pci_epf_header *hdr)
>>>>> +{
>>>>> + struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>>>>> + struct cdns_pcie *pcie = &ep->pcie;
>>>>> + u8 fn = 0;
>>>>> +
>>>>> + if (fn == 0) {
>>>>
>>>> I think there is some code to retrieve fn missing here.
>>>
>>> hmm.. the endpoint core has to send the function number which right now it's
>>> not doing though it has the function number info in pci_epf.
>>
>> Would it be OK if I add a new patch in the next series adding a
>> 'struct pcie_epf *epf' as a 2nd argument to all handlers in the
>> 'struct pcie_epc_ops'? This way I could have access to epf->func_no as needed.
I prefer we just pass the func_no as the second argument. Do you see a problem
with that?
>>
>
> Except for pci_epc_start() and pci_epc_stop(), both only called from
> pci_epc_start_store(), I don't have trouble getting the epf value to be passed
> as a 2nd argument to all other handlers in 'struct pcie_epc_ops'.
pci_epc_start()/pci_epc_stop() is used to start/stop the end point controller
as a whole and shouldn't need epf.
>
> Now my next question is: is it better to keep the 'struct pci_epc *epc' as
> the 1st argument of all those handlers or do you prefer me to remove it as
> the value can always be retrieved from epf->epc, since now we provide epf as
> a new argument ?
Do we really need to pass epf when func_no is all we need?
Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 6/6] phy: renesas: rcar-gen3-usb2: add gpio handling
From: Yoshihiro Shimoda @ 2017-12-15 5:45 UTC (permalink / raw)
To: kishon, robh+dt, mark.rutland
Cc: linux-kernel, devicetree, linux-renesas-soc, Yoshihiro Shimoda
In-Reply-To: <1513316726-14387-1-git-send-email-yoshihiro.shimoda.uh@renesas.com>
Some R-Car SoCs (e.g. R-Car D3) doesn't have dedicated pins of VBUS
and ID. So, they may be connected to gpio pins. To handle the gpio
pins, this patch adds the handling of VBUS and ID pins instead of
dedicated pins.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
.../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt | 2 +
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 77 ++++++++++++++++++++--
2 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
index 99b651b..999a6ef 100644
--- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
+++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
@@ -27,6 +27,8 @@ channel as USB OTG:
- interrupts: interrupt specifier for the PHY.
- vbus-supply: Phandle to a regulator that provides power to the VBUS. This
regulator will be managed during the PHY power on/off sequence.
+- vbus-gpios: use gpio to control vbus instead of dedicated pin.
+- id-gpios: use gpio to detect id instead of dedicated pin.
Example (R-Car H3):
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index f470fb3..ea76973 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -13,6 +13,7 @@
*/
#include <linux/extcon-provider.h>
+#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
@@ -100,9 +101,12 @@ struct rcar_gen3_chan {
struct phy *phy;
struct regulator *vbus;
const struct rcar_gen3_role_swap_ops *rs_ops;
+ struct gpio_desc *gpio_vbus;
+ struct gpio_desc *gpio_id;
struct work_struct work;
bool extcon_host;
bool has_otg_pins;
+ bool has_gpio;
};
static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
@@ -199,6 +203,36 @@ static void has_otg_pins_init(struct rcar_gen3_chan *ch)
usb2_base + USB2_LINECTRL1);
}
+static void gpio_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable)
+{
+ gpiod_set_value(ch->gpio_vbus, enable);
+}
+
+static bool gpio_check_id(struct rcar_gen3_chan *ch)
+{
+ return gpiod_get_value(ch->gpio_id);
+}
+
+static void gpio_set_host(struct rcar_gen3_chan *ch, int host)
+{
+ /* In gpio ops, this driver will modify the extcon_host by sysfs */
+ if (ch->extcon_host != !!host) {
+ ch->extcon_host = !!host;
+ schedule_work(&ch->work);
+ }
+}
+
+static bool gpio_is_host(struct rcar_gen3_chan *ch)
+{
+ return ch->extcon_host;
+}
+
+static irqreturn_t gpio_irq_handler(struct rcar_gen3_chan *ch)
+{
+ /* Nop because the driver will get gpio value after exited */
+ return IRQ_HANDLED;
+}
+
static void rcar_gen3_phy_usb2_work(struct work_struct *work)
{
struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan,
@@ -323,7 +357,7 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
bool is_b_device;
enum phy_mode cur_mode, new_mode;
- if (!ch->has_otg_pins || !ch->phy->init_count)
+ if (!(ch->has_otg_pins || ch->has_gpio) || !ch->phy->init_count)
return -EIO;
if (!strncmp(buf, "host", strlen("host")))
@@ -361,7 +395,7 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
{
struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
- if (!ch->has_otg_pins || !ch->phy->init_count)
+ if (!(ch->has_otg_pins || ch->has_gpio) || !ch->phy->init_count)
return -EIO;
return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" :
@@ -388,7 +422,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
/* Initialize otg part */
- if (channel->has_otg_pins)
+ if (channel->has_otg_pins || channel->has_gpio)
rcar_gen3_init_otg(channel);
return 0;
@@ -489,6 +523,14 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
.irq_handler = has_otg_pins_irq_handler,
};
+static const struct rcar_gen3_role_swap_ops gpio_ops = {
+ .set_host = gpio_set_host,
+ .is_host = gpio_is_host,
+ .set_vbus_ctrl = gpio_set_vbus_ctrl,
+ .check_id = gpio_check_id,
+ .irq_handler = gpio_irq_handler,
+};
+
static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -513,9 +555,30 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work);
- /* call request_irq for OTG */
+ channel->gpio_vbus = devm_gpiod_get(dev, "vbus", GPIOD_OUT_LOW);
+ if (IS_ERR(channel->gpio_vbus) &&
+ PTR_ERR(channel->gpio_vbus) == -EPROBE_DEFER)
+ return PTR_ERR(channel->gpio_vbus);
+
+ channel->gpio_id = devm_gpiod_get(dev, "id", GPIOD_IN);
+ if (!IS_ERR(channel->gpio_vbus) && !IS_ERR(channel->gpio_id)) {
+ irq = gpiod_to_irq(channel->gpio_id);
+ if (irq > 0) {
+ ret = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ dev_name(dev), channel);
+ if (ret < 0) {
+ dev_err(dev, "No gpio irq handler (%d)\n", irq);
+ } else {
+ channel->has_gpio = true;
+ channel->rs_ops = &gpio_ops;
+ }
+ }
+ }
+
+ /* call request_irq for OTG if doesn't have gpio */
irq = platform_get_irq(pdev, 0);
- if (irq >= 0) {
+ if (!channel->has_gpio && irq >= 0) {
irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
IRQF_SHARED, dev_name(dev), channel);
if (irq < 0)
@@ -569,7 +632,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
dev_err(dev, "Failed to register PHY provider\n");
ret = PTR_ERR(provider);
goto error;
- } else if (channel->has_otg_pins) {
+ } else if (channel->has_otg_pins || channel->has_gpio) {
int ret;
ret = device_create_file(dev, &dev_attr_role);
@@ -589,7 +652,7 @@ static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
{
struct rcar_gen3_chan *channel = platform_get_drvdata(pdev);
- if (channel->has_otg_pins)
+ if (channel->has_otg_pins || channel->has_gpio)
device_remove_file(&pdev->dev, &dev_attr_role);
pm_runtime_disable(&pdev->dev);
--
1.9.1
^ permalink raw reply related
* [PATCH v2 5/6] phy: renesas: rcar-gen3-usb2: add rcar_gen3_role_swap_ops
From: Yoshihiro Shimoda @ 2017-12-15 5:45 UTC (permalink / raw)
To: kishon, robh+dt, mark.rutland
Cc: linux-kernel, devicetree, linux-renesas-soc, Yoshihiro Shimoda
In-Reply-To: <1513316726-14387-1-git-send-email-yoshihiro.shimoda.uh@renesas.com>
This patch add rcar_gen3_role_swap_ops to support other feature
(e.g. gpio handling) easily.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 51 +++++++++++++++++++++++++++-----
1 file changed, 43 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index b121f07..f470fb3 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -83,11 +83,23 @@
#define RCAR_GEN3_PHY_HAS_DEDICATED_PINS 1
+struct rcar_gen3_chan;
+struct rcar_gen3_role_swap_ops {
+ void (*init)(struct rcar_gen3_chan *ch);
+ void (*set_host)(struct rcar_gen3_chan *ch, int host);
+ bool (*is_host)(struct rcar_gen3_chan *ch);
+ void (*set_vbus_ctrl)(struct rcar_gen3_chan *ch, int enable);
+ bool (*check_id)(struct rcar_gen3_chan *ch);
+ void (*control_irq)(struct rcar_gen3_chan *ch, int enable);
+ irqreturn_t (*irq_handler)(struct rcar_gen3_chan *ch);
+};
+
struct rcar_gen3_chan {
void __iomem *base;
struct extcon_dev *extcon;
struct phy *phy;
struct regulator *vbus;
+ const struct rcar_gen3_role_swap_ops *rs_ops;
struct work_struct work;
bool extcon_host;
bool has_otg_pins;
@@ -203,17 +215,20 @@ static void rcar_gen3_phy_usb2_work(struct work_struct *work)
static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
{
- has_otg_pins_set_host(ch, host);
+ if (ch->rs_ops && ch->rs_ops->set_host)
+ ch->rs_ops->set_host(ch, host);
}
static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable)
{
- has_otg_pins_set_vbus_ctrl(ch, enable);
+ if (ch->rs_ops && ch->rs_ops->set_vbus_ctrl)
+ ch->rs_ops->set_vbus_ctrl(ch, enable);
}
static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
{
- has_otg_pins_control_irq(ch, enable);
+ if (ch->rs_ops && ch->rs_ops->control_irq)
+ ch->rs_ops->control_irq(ch, enable);
}
static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
@@ -271,7 +286,10 @@ static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
{
- return has_otg_pins_check_id(ch);
+ if (ch->rs_ops && ch->rs_ops->check_id)
+ return ch->rs_ops->check_id(ch);
+
+ return false;
}
static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
@@ -284,7 +302,10 @@ static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
static bool rcar_gen3_is_host(struct rcar_gen3_chan *ch)
{
- return has_otg_pins_is_host(ch);
+ if (ch->rs_ops && ch->rs_ops->is_host)
+ return ch->rs_ops->is_host(ch);
+
+ return false;
}
static enum phy_mode rcar_gen3_get_phy_mode(struct rcar_gen3_chan *ch)
@@ -350,7 +371,8 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
{
- has_otg_pins_init(ch);
+ if (ch->rs_ops && ch->rs_ops->init)
+ ch->rs_ops->init(ch);
rcar_gen3_device_recognition(ch);
}
@@ -425,9 +447,10 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p)
static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
{
struct rcar_gen3_chan *ch = _ch;
- irqreturn_t ret;
+ irqreturn_t ret = IRQ_NONE;
- ret = has_otg_pins_irq_handler(ch);
+ if (ch->rs_ops && ch->rs_ops->irq_handler)
+ ret = ch->rs_ops->irq_handler(ch);
if (ret == IRQ_HANDLED)
rcar_gen3_device_recognition(ch);
@@ -456,6 +479,16 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
EXTCON_NONE,
};
+static const struct rcar_gen3_role_swap_ops has_otg_pins_ops = {
+ .init = has_otg_pins_init,
+ .set_host = has_otg_pins_set_host,
+ .is_host = has_otg_pins_is_host,
+ .set_vbus_ctrl = has_otg_pins_set_vbus_ctrl,
+ .check_id = has_otg_pins_check_id,
+ .control_irq = has_otg_pins_control_irq,
+ .irq_handler = has_otg_pins_irq_handler,
+};
+
static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -493,6 +526,8 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
int ret;
channel->has_otg_pins = (uintptr_t)of_device_get_match_data(dev);
+ if (channel->has_otg_pins)
+ channel->rs_ops = &has_otg_pins_ops;
channel->extcon = devm_extcon_dev_allocate(dev,
rcar_gen3_phy_cable);
if (IS_ERR(channel->extcon))
--
1.9.1
^ permalink raw reply related
* [PATCH v2 4/6] phy: renesas: rcar-gen3-usb2: use prefix "has_otg_pins_" for dedicated pins handling
From: Yoshihiro Shimoda @ 2017-12-15 5:45 UTC (permalink / raw)
To: kishon, robh+dt, mark.rutland
Cc: linux-kernel, devicetree, linux-renesas-soc, Yoshihiro Shimoda
In-Reply-To: <1513316726-14387-1-git-send-email-yoshihiro.shimoda.uh@renesas.com>
To support gpio handling in the future, this patch clean-ups the code
to use prefix "has_otg_pins_" functions.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 130 ++++++++++++++++++++-----------
1 file changed, 85 insertions(+), 45 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index bca6162..b121f07 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -93,21 +93,21 @@ struct rcar_gen3_chan {
bool has_otg_pins;
};
-static void rcar_gen3_phy_usb2_work(struct work_struct *work)
+static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
{
- struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan,
- work);
+ void __iomem *usb2_base = ch->base;
+ u32 val = readl(usb2_base + USB2_LINECTRL1);
- if (ch->extcon_host) {
- extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, true);
- extcon_set_state_sync(ch->extcon, EXTCON_USB, false);
- } else {
- extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, false);
- extcon_set_state_sync(ch->extcon, EXTCON_USB, true);
- }
+ dev_vdbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm);
+ val &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
+ if (dp)
+ val |= USB2_LINECTRL1_DP_RPD;
+ if (dm)
+ val |= USB2_LINECTRL1_DM_RPD;
+ writel(val, usb2_base + USB2_LINECTRL1);
}
-static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
+static void has_otg_pins_set_host(struct rcar_gen3_chan *ch, int host)
{
void __iomem *usb2_base = ch->base;
u32 val = readl(usb2_base + USB2_COMMCTRL);
@@ -120,21 +120,27 @@ static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
writel(val, usb2_base + USB2_COMMCTRL);
}
-static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
+static bool has_otg_pins_is_host(struct rcar_gen3_chan *ch)
+{
+ return !(readl(ch->base + USB2_COMMCTRL) & USB2_COMMCTRL_OTG_PERI);
+}
+
+static irqreturn_t has_otg_pins_irq_handler(struct rcar_gen3_chan *ch)
{
void __iomem *usb2_base = ch->base;
- u32 val = readl(usb2_base + USB2_LINECTRL1);
+ u32 status = readl(usb2_base + USB2_OBINTSTA);
+ irqreturn_t ret = IRQ_NONE;
- dev_vdbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm);
- val &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
- if (dp)
- val |= USB2_LINECTRL1_DP_RPD;
- if (dm)
- val |= USB2_LINECTRL1_DM_RPD;
- writel(val, usb2_base + USB2_LINECTRL1);
+ if (status & USB2_OBINT_BITS) {
+ dev_vdbg(&ch->phy->dev, "%s: %08x\n", __func__, status);
+ writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
}
-static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable)
+static void has_otg_pins_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable)
{
void __iomem *usb2_base = ch->base;
u32 val = readl(usb2_base + USB2_ADPCTRL);
@@ -147,7 +153,7 @@ static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable)
writel(val, usb2_base + USB2_ADPCTRL);
}
-static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
+static void has_otg_pins_control_irq(struct rcar_gen3_chan *ch, int enable)
{
void __iomem *usb2_base = ch->base;
u32 val = readl(usb2_base + USB2_OBINTEN);
@@ -159,6 +165,57 @@ static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
writel(val, usb2_base + USB2_OBINTEN);
}
+static bool has_otg_pins_check_id(struct rcar_gen3_chan *ch)
+{
+ return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
+}
+
+static void has_otg_pins_init(struct rcar_gen3_chan *ch)
+{
+ void __iomem *usb2_base = ch->base;
+ u32 val;
+
+ val = readl(usb2_base + USB2_VBCTRL);
+ writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
+ writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
+ has_otg_pins_control_irq(ch, 1);
+ val = readl(usb2_base + USB2_ADPCTRL);
+ writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
+ val = readl(usb2_base + USB2_LINECTRL1);
+ rcar_gen3_set_linectrl(ch, 0, 0);
+ writel(val | USB2_LINECTRL1_DPRPD_EN | USB2_LINECTRL1_DMRPD_EN,
+ usb2_base + USB2_LINECTRL1);
+}
+
+static void rcar_gen3_phy_usb2_work(struct work_struct *work)
+{
+ struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan,
+ work);
+
+ if (ch->extcon_host) {
+ extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, true);
+ extcon_set_state_sync(ch->extcon, EXTCON_USB, false);
+ } else {
+ extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, false);
+ extcon_set_state_sync(ch->extcon, EXTCON_USB, true);
+ }
+}
+
+static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
+{
+ has_otg_pins_set_host(ch, host);
+}
+
+static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable)
+{
+ has_otg_pins_set_vbus_ctrl(ch, enable);
+}
+
+static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
+{
+ has_otg_pins_control_irq(ch, enable);
+}
+
static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
{
rcar_gen3_set_linectrl(ch, 1, 1);
@@ -214,7 +271,7 @@ static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
{
- return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
+ return has_otg_pins_check_id(ch);
}
static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
@@ -227,7 +284,7 @@ static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
static bool rcar_gen3_is_host(struct rcar_gen3_chan *ch)
{
- return !(readl(ch->base + USB2_COMMCTRL) & USB2_COMMCTRL_OTG_PERI);
+ return has_otg_pins_is_host(ch);
}
static enum phy_mode rcar_gen3_get_phy_mode(struct rcar_gen3_chan *ch)
@@ -293,19 +350,7 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
{
- void __iomem *usb2_base = ch->base;
- u32 val;
-
- val = readl(usb2_base + USB2_VBCTRL);
- writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
- writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
- rcar_gen3_control_otg_irq(ch, 1);
- val = readl(usb2_base + USB2_ADPCTRL);
- writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
- val = readl(usb2_base + USB2_LINECTRL1);
- rcar_gen3_set_linectrl(ch, 0, 0);
- writel(val | USB2_LINECTRL1_DPRPD_EN | USB2_LINECTRL1_DMRPD_EN,
- usb2_base + USB2_LINECTRL1);
+ has_otg_pins_init(ch);
rcar_gen3_device_recognition(ch);
}
@@ -380,16 +425,11 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p)
static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
{
struct rcar_gen3_chan *ch = _ch;
- void __iomem *usb2_base = ch->base;
- u32 status = readl(usb2_base + USB2_OBINTSTA);
- irqreturn_t ret = IRQ_NONE;
+ irqreturn_t ret;
- if (status & USB2_OBINT_BITS) {
- dev_vdbg(&ch->phy->dev, "%s: %08x\n", __func__, status);
- writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
+ ret = has_otg_pins_irq_handler(ch);
+ if (ret == IRQ_HANDLED)
rcar_gen3_device_recognition(ch);
- ret = IRQ_HANDLED;
- }
return ret;
}
--
1.9.1
^ permalink raw reply related
* [PATCH v2 3/6] phy: renesas: rcar-gen3-usb2: change the function name to set_vbus_ctrl()
From: Yoshihiro Shimoda @ 2017-12-15 5:45 UTC (permalink / raw)
To: kishon-l0cyMroinI0, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA, Yoshihiro Shimoda
In-Reply-To: <1513316726-14387-1-git-send-email-yoshihiro.shimoda.uh-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
This patch changes the function name from rcar_gen3_enable_vbus_ctrl()
to rcar_gen3_set_vbus_ctrl() because the fucntion both enables and
disables.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 480f912..bca6162 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -134,13 +134,13 @@ static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
writel(val, usb2_base + USB2_LINECTRL1);
}
-static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
+static void rcar_gen3_set_vbus_ctrl(struct rcar_gen3_chan *ch, int enable)
{
void __iomem *usb2_base = ch->base;
u32 val = readl(usb2_base + USB2_ADPCTRL);
- dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, vbus);
- if (vbus)
+ dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, enable);
+ if (enable)
val |= USB2_ADPCTRL_DRVVBUS;
else
val &= ~USB2_ADPCTRL_DRVVBUS;
@@ -163,7 +163,7 @@ static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
{
rcar_gen3_set_linectrl(ch, 1, 1);
rcar_gen3_set_host_mode(ch, 1);
- rcar_gen3_enable_vbus_ctrl(ch, 1);
+ rcar_gen3_set_vbus_ctrl(ch, 1);
ch->extcon_host = true;
schedule_work(&ch->work);
@@ -173,7 +173,7 @@ static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
{
rcar_gen3_set_linectrl(ch, 0, 1);
rcar_gen3_set_host_mode(ch, 0);
- rcar_gen3_enable_vbus_ctrl(ch, 0);
+ rcar_gen3_set_vbus_ctrl(ch, 0);
ch->extcon_host = false;
schedule_work(&ch->work);
@@ -189,7 +189,7 @@ static void rcar_gen3_init_for_b_host(struct rcar_gen3_chan *ch)
rcar_gen3_set_linectrl(ch, 1, 1);
rcar_gen3_set_host_mode(ch, 1);
- rcar_gen3_enable_vbus_ctrl(ch, 0);
+ rcar_gen3_set_vbus_ctrl(ch, 0);
val = readl(usb2_base + USB2_LINECTRL1);
writel(val & ~USB2_LINECTRL1_OPMODE_NODRV, usb2_base + USB2_LINECTRL1);
@@ -199,14 +199,14 @@ static void rcar_gen3_init_for_a_peri(struct rcar_gen3_chan *ch)
{
rcar_gen3_set_linectrl(ch, 0, 1);
rcar_gen3_set_host_mode(ch, 0);
- rcar_gen3_enable_vbus_ctrl(ch, 1);
+ rcar_gen3_set_vbus_ctrl(ch, 1);
}
static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
{
rcar_gen3_control_otg_irq(ch, 0);
- rcar_gen3_enable_vbus_ctrl(ch, 0);
+ rcar_gen3_set_vbus_ctrl(ch, 0);
rcar_gen3_init_for_host(ch);
rcar_gen3_control_otg_irq(ch, 1);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 2/6] phy: renesas: rcar-gen3-usb2: unify OBINTEN handling
From: Yoshihiro Shimoda @ 2017-12-15 5:45 UTC (permalink / raw)
To: kishon-l0cyMroinI0, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA, Yoshihiro Shimoda
In-Reply-To: <1513316726-14387-1-git-send-email-yoshihiro.shimoda.uh-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
This patch unifies the OBINTEN handling to clean-up the code.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index c22d65a..480f912 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -147,6 +147,18 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
writel(val, usb2_base + USB2_ADPCTRL);
}
+static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
+{
+ void __iomem *usb2_base = ch->base;
+ u32 val = readl(usb2_base + USB2_OBINTEN);
+
+ if (enable)
+ val |= USB2_OBINT_BITS;
+ else
+ val &= ~USB2_OBINT_BITS;
+ writel(val, usb2_base + USB2_OBINTEN);
+}
+
static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
{
rcar_gen3_set_linectrl(ch, 1, 1);
@@ -192,16 +204,12 @@ static void rcar_gen3_init_for_a_peri(struct rcar_gen3_chan *ch)
static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
{
- void __iomem *usb2_base = ch->base;
- u32 val;
-
- val = readl(usb2_base + USB2_OBINTEN);
- writel(val & ~USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
+ rcar_gen3_control_otg_irq(ch, 0);
rcar_gen3_enable_vbus_ctrl(ch, 0);
rcar_gen3_init_for_host(ch);
- writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
+ rcar_gen3_control_otg_irq(ch, 1);
}
static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
@@ -291,8 +299,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
val = readl(usb2_base + USB2_VBCTRL);
writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
- val = readl(usb2_base + USB2_OBINTEN);
- writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
+ rcar_gen3_control_otg_irq(ch, 1);
val = readl(usb2_base + USB2_ADPCTRL);
writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
val = readl(usb2_base + USB2_LINECTRL1);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 1/6] phy: renesas: rcar-gen3-usb2: call INIT_WORK() anyway
From: Yoshihiro Shimoda @ 2017-12-15 5:45 UTC (permalink / raw)
To: kishon-l0cyMroinI0, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA, Yoshihiro Shimoda
In-Reply-To: <1513316726-14387-1-git-send-email-yoshihiro.shimoda.uh-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
In the future, the work struct will be used by non-irq related code.
So, this patch moves the INIT_WORK() timing.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 9c90e7d..c22d65a 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -431,10 +431,11 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
if (IS_ERR(channel->base))
return PTR_ERR(channel->base);
+ INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work);
+
/* call request_irq for OTG */
irq = platform_get_irq(pdev, 0);
if (irq >= 0) {
- INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work);
irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
IRQF_SHARED, dev_name(dev), channel);
if (irq < 0)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 0/6] phy: renesas: rcar-gen3-usb2: add gpio handling for R-Car D3
From: Yoshihiro Shimoda @ 2017-12-15 5:45 UTC (permalink / raw)
To: kishon, robh+dt, mark.rutland
Cc: linux-kernel, devicetree, linux-renesas-soc, Yoshihiro Shimoda
This patch set is based on the latest linux-phy / next branch
(commit id = 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323).
This new feature will be used by the renesas_usbhs driver on R-Car D3.
Changes from v1:
- Drop "renesas," from the names of gpio property.
- Change function names of "enable_" to "control_" or "set_" that
will enable/disable irq or vbus.
Yoshihiro Shimoda (6):
phy: renesas: rcar-gen3-usb2: call INIT_WORK() anyway
phy: renesas: rcar-gen3-usb2: unify OBINTEN handling
phy: renesas: rcar-gen3-usb2: change the function name to
set_vbus_ctrl()
phy: renesas: rcar-gen3-usb2: use prefix "has_otg_pins_" for dedicated
pins handling
phy: renesas: rcar-gen3-usb2: add rcar_gen3_role_swap_ops
phy: renesas: rcar-gen3-usb2: add gpio handling
.../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt | 2 +
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 276 ++++++++++++++++-----
2 files changed, 213 insertions(+), 65 deletions(-)
--
1.9.1
^ permalink raw reply
* Re: [PATCH v2 0/4] PM / OPP: Introduce ti-opp-supply driver
From: Viresh Kumar @ 2017-12-15 4:27 UTC (permalink / raw)
To: Dave Gerlach
Cc: Rob Herring, Rafael J . Wysocki,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren, Nishanth Menon
In-Reply-To: <20171215042528.28715-1-d-gerlach-l0cyMroinI0@public.gmane.org>
On 14-12-17, 22:25, Dave Gerlach wrote:
> Hi,
> This is v2 of the series to introduce the ti-opp-supply driver which makes
> use of the OPP core to enable multiple regulator DVFS and AVS Class0 for
> TI DRA7 and AM57 platforms. Version 1 of this series can be found here [1].
>
> Very few changes since v1, just added Viresh's acks to patches 1 and 2 and
> added SPDX license to the ti-opp-supply driver in patch 4.
>
> Pushed updated branch here just in case [2].
>
> Regards,
> Dave
>
> [1] https://www.spinics.net/lists/devicetree/msg205957.html
> [2] https://github.com/dgerlach/linux-pm/tree/upstream/v4.15/ti-multireg-support-v2
>
> Dave Gerlach (4):
> cpufreq: ti-cpufreq: Convert to module_platform_driver
> cpufreq: ti-cpufreq: Add support for multiple regulators
> dt-bindings: opp: Introduce ti-opp-supply bindings
> PM / OPP: Add ti-opp-supply driver
>
> .../bindings/opp/ti-omap5-opp-supply.txt | 63 +++
> drivers/cpufreq/ti-cpufreq.c | 51 ++-
> drivers/opp/Makefile | 1 +
> drivers/opp/ti-opp-supply.c | 425 +++++++++++++++++++++
> 4 files changed, 534 insertions(+), 6 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt
> create mode 100644 drivers/opp/ti-opp-supply.c
Acked-by: Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
--
viresh
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 4/4] PM / OPP: Add ti-opp-supply driver
From: Dave Gerlach @ 2017-12-15 4:25 UTC (permalink / raw)
To: Viresh Kumar, Rob Herring, Rafael J . Wysocki
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren, Nishanth Menon,
Dave Gerlach
In-Reply-To: <20171215042528.28715-1-d-gerlach-l0cyMroinI0@public.gmane.org>
Introduce a ti-opp-supply driver that will use new multiple regulator
support that is part of the OPP core This is needed on TI platforms like
DRA7/AM57 in order to control both CPU regulator and Adaptive Body Bias
(ABB) regulator. These regulators must be scaled in sequence during an
OPP transition depending on whether or not the frequency is being scaled
up or down.
This driver also implements AVS Class0 for these parts by looking up the
required values from registers in the SoC and programming adjusted
optimal voltage values for each OPP.
Signed-off-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
---
drivers/opp/Makefile | 1 +
drivers/opp/ti-opp-supply.c | 425 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 426 insertions(+)
create mode 100644 drivers/opp/ti-opp-supply.c
diff --git a/drivers/opp/Makefile b/drivers/opp/Makefile
index e70ceb406fe9..6ce6aefacc81 100644
--- a/drivers/opp/Makefile
+++ b/drivers/opp/Makefile
@@ -2,3 +2,4 @@ ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
obj-y += core.o cpu.o
obj-$(CONFIG_OF) += of.o
obj-$(CONFIG_DEBUG_FS) += debugfs.o
+obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-opp-supply.o
diff --git a/drivers/opp/ti-opp-supply.c b/drivers/opp/ti-opp-supply.c
new file mode 100644
index 000000000000..44dae3e51aac
--- /dev/null
+++ b/drivers/opp/ti-opp-supply.c
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon <nm-l0cyMroinI0@public.gmane.org>
+ * Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
+ *
+ * TI OPP supply driver that provides override into the regulator control
+ * for generic opp core to handle devices with ABB regulator and/or
+ * SmartReflex Class0.
+ */
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+/**
+ * struct ti_opp_supply_optimum_voltage_table - optimized voltage table
+ * @reference_uv: reference voltage (usually Nominal voltage)
+ * @optimized_uv: Optimized voltage from efuse
+ */
+struct ti_opp_supply_optimum_voltage_table {
+ unsigned int reference_uv;
+ unsigned int optimized_uv;
+};
+
+/**
+ * struct ti_opp_supply_data - OMAP specific opp supply data
+ * @vdd_table: Optimized voltage mapping table
+ * @num_vdd_table: number of entries in vdd_table
+ * @vdd_absolute_max_voltage_uv: absolute maximum voltage in UV for the supply
+ */
+struct ti_opp_supply_data {
+ struct ti_opp_supply_optimum_voltage_table *vdd_table;
+ u32 num_vdd_table;
+ u32 vdd_absolute_max_voltage_uv;
+};
+
+static struct ti_opp_supply_data opp_data;
+
+/**
+ * struct ti_opp_supply_of_data - device tree match data
+ * @flags: specific type of opp supply
+ * @efuse_voltage_mask: mask required for efuse register representing voltage
+ * @efuse_voltage_uv: Are the efuse entries in micro-volts? if not, assume
+ * milli-volts.
+ */
+struct ti_opp_supply_of_data {
+#define OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE BIT(1)
+#define OPPDM_HAS_NO_ABB BIT(2)
+ const u8 flags;
+ const u32 efuse_voltage_mask;
+ const bool efuse_voltage_uv;
+};
+
+/**
+ * _store_optimized_voltages() - store optimized voltages
+ * @dev: ti opp supply device for which we need to store info
+ * @data: data specific to the device
+ *
+ * Picks up efuse based optimized voltages for VDD unique per device and
+ * stores it in internal data structure for use during transition requests.
+ *
+ * Return: If successful, 0, else appropriate error value.
+ */
+static int _store_optimized_voltages(struct device *dev,
+ struct ti_opp_supply_data *data)
+{
+ void __iomem *base;
+ struct property *prop;
+ struct resource *res;
+ const __be32 *val;
+ int proplen, i;
+ int ret = 0;
+ struct ti_opp_supply_optimum_voltage_table *table;
+ const struct ti_opp_supply_of_data *of_data = dev_get_drvdata(dev);
+
+ /* pick up Efuse based voltages */
+ res = platform_get_resource(to_platform_device(dev), IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "Unable to get IO resource\n");
+ ret = -ENODEV;
+ goto out_map;
+ }
+
+ base = ioremap_nocache(res->start, resource_size(res));
+ if (!base) {
+ dev_err(dev, "Unable to map Efuse registers\n");
+ ret = -ENOMEM;
+ goto out_map;
+ }
+
+ /* Fetch efuse-settings. */
+ prop = of_find_property(dev->of_node, "ti,efuse-settings", NULL);
+ if (!prop) {
+ dev_err(dev, "No 'ti,efuse-settings' property found\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ proplen = prop->length / sizeof(int);
+ data->num_vdd_table = proplen / 2;
+ /* Verify for corrupted OPP entries in dt */
+ if (data->num_vdd_table * 2 * sizeof(int) != prop->length) {
+ dev_err(dev, "Invalid 'ti,efuse-settings'\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "ti,absolute-max-voltage-uv",
+ &data->vdd_absolute_max_voltage_uv);
+ if (ret) {
+ dev_err(dev, "ti,absolute-max-voltage-uv is missing\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ table = kzalloc(sizeof(*data->vdd_table) *
+ data->num_vdd_table, GFP_KERNEL);
+ if (!table) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ data->vdd_table = table;
+
+ val = prop->value;
+ for (i = 0; i < data->num_vdd_table; i++, table++) {
+ u32 efuse_offset;
+ u32 tmp;
+
+ table->reference_uv = be32_to_cpup(val++);
+ efuse_offset = be32_to_cpup(val++);
+
+ tmp = readl(base + efuse_offset);
+ tmp &= of_data->efuse_voltage_mask;
+ tmp >>= __ffs(of_data->efuse_voltage_mask);
+
+ table->optimized_uv = of_data->efuse_voltage_uv ? tmp :
+ tmp * 1000;
+
+ dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d vset=%d\n",
+ i, efuse_offset, table->reference_uv,
+ table->optimized_uv);
+
+ /*
+ * Some older samples might not have optimized efuse
+ * Use reference voltage for those - just add debug message
+ * for them.
+ */
+ if (!table->optimized_uv) {
+ dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d:vset0\n",
+ i, efuse_offset, table->reference_uv);
+ table->optimized_uv = table->reference_uv;
+ }
+ }
+out:
+ iounmap(base);
+out_map:
+ return ret;
+}
+
+/**
+ * _free_optimized_voltages() - free resources for optvoltages
+ * @dev: device for which we need to free info
+ * @data: data specific to the device
+ */
+static void _free_optimized_voltages(struct device *dev,
+ struct ti_opp_supply_data *data)
+{
+ kfree(data->vdd_table);
+ data->vdd_table = NULL;
+ data->num_vdd_table = 0;
+}
+
+/**
+ * _get_optimal_vdd_voltage() - Finds optimal voltage for the supply
+ * @dev: device for which we need to find info
+ * @data: data specific to the device
+ * @reference_uv: reference voltage (OPP voltage) for which we need value
+ *
+ * Return: if a match is found, return optimized voltage, else return
+ * reference_uv, also return reference_uv if no optimization is needed.
+ */
+static int _get_optimal_vdd_voltage(struct device *dev,
+ struct ti_opp_supply_data *data,
+ int reference_uv)
+{
+ int i;
+ struct ti_opp_supply_optimum_voltage_table *table;
+
+ if (!data->num_vdd_table)
+ return reference_uv;
+
+ table = data->vdd_table;
+ if (!table)
+ return -EINVAL;
+
+ /* Find a exact match - this list is usually very small */
+ for (i = 0; i < data->num_vdd_table; i++, table++)
+ if (table->reference_uv == reference_uv)
+ return table->optimized_uv;
+
+ /* IF things are screwed up, we'd make a mess on console.. ratelimit */
+ dev_err_ratelimited(dev, "%s: Failed optimized voltage match for %d\n",
+ __func__, reference_uv);
+ return reference_uv;
+}
+
+static int _opp_set_voltage(struct device *dev,
+ struct dev_pm_opp_supply *supply,
+ int new_target_uv, struct regulator *reg,
+ char *reg_name)
+{
+ int ret;
+ unsigned long vdd_uv, uv_max;
+
+ if (new_target_uv)
+ vdd_uv = new_target_uv;
+ else
+ vdd_uv = supply->u_volt;
+
+ /*
+ * If we do have an absolute max voltage specified, then we should
+ * use that voltage instead to allow for cases where the voltage rails
+ * are ganged (example if we set the max for an opp as 1.12v, and
+ * the absolute max is 1.5v, for another rail to get 1.25v, it cannot
+ * be achieved if the regulator is constrainted to max of 1.12v, even
+ * if it can function at 1.25v
+ */
+ if (opp_data.vdd_absolute_max_voltage_uv)
+ uv_max = opp_data.vdd_absolute_max_voltage_uv;
+ else
+ uv_max = supply->u_volt_max;
+
+ if (vdd_uv > uv_max ||
+ vdd_uv < supply->u_volt_min ||
+ supply->u_volt_min > uv_max) {
+ dev_warn(dev,
+ "Invalid range voltages [Min:%lu target:%lu Max:%lu]\n",
+ supply->u_volt_min, vdd_uv, uv_max);
+ return -EINVAL;
+ }
+
+ dev_dbg(dev, "%s scaling to %luuV[min %luuV max %luuV]\n", reg_name,
+ vdd_uv, supply->u_volt_min,
+ uv_max);
+
+ ret = regulator_set_voltage_triplet(reg,
+ supply->u_volt_min,
+ vdd_uv,
+ uv_max);
+ if (ret) {
+ dev_err(dev, "%s failed for %luuV[min %luuV max %luuV]\n",
+ reg_name, vdd_uv, supply->u_volt_min,
+ uv_max);
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * ti_opp_supply_set_opp() - do the opp supply transition
+ * @data: information on regulators and new and old opps provided by
+ * opp core to use in transition
+ *
+ * Return: If successful, 0, else appropriate error value.
+ */
+int ti_opp_supply_set_opp(struct dev_pm_set_opp_data *data)
+{
+ struct dev_pm_opp_supply *old_supply_vdd = &data->old_opp.supplies[0];
+ struct dev_pm_opp_supply *old_supply_vbb = &data->old_opp.supplies[1];
+ struct dev_pm_opp_supply *new_supply_vdd = &data->new_opp.supplies[0];
+ struct dev_pm_opp_supply *new_supply_vbb = &data->new_opp.supplies[1];
+ struct device *dev = data->dev;
+ unsigned long old_freq = data->old_opp.rate, freq = data->new_opp.rate;
+ struct clk *clk = data->clk;
+ struct regulator *vdd_reg = data->regulators[0];
+ struct regulator *vbb_reg = data->regulators[1];
+ int vdd_uv;
+ int ret;
+
+ vdd_uv = _get_optimal_vdd_voltage(dev, &opp_data,
+ new_supply_vbb->u_volt);
+
+ /* Scaling up? Scale voltage before frequency */
+ if (freq > old_freq) {
+ ret = _opp_set_voltage(dev, new_supply_vdd, vdd_uv, vdd_reg,
+ "vdd");
+ if (ret)
+ goto restore_voltage;
+
+ ret = _opp_set_voltage(dev, new_supply_vbb, 0, vbb_reg, "vbb");
+ if (ret)
+ goto restore_voltage;
+ }
+
+ /* Change frequency */
+ dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n",
+ __func__, old_freq, freq);
+
+ ret = clk_set_rate(clk, freq);
+ if (ret) {
+ dev_err(dev, "%s: failed to set clock rate: %d\n", __func__,
+ ret);
+ goto restore_voltage;
+ }
+
+ /* Scaling down? Scale voltage after frequency */
+ if (freq < old_freq) {
+ ret = _opp_set_voltage(dev, new_supply_vbb, 0, vbb_reg, "vbb");
+ if (ret)
+ goto restore_freq;
+
+ ret = _opp_set_voltage(dev, new_supply_vdd, vdd_uv, vdd_reg,
+ "vdd");
+ if (ret)
+ goto restore_freq;
+ }
+
+ return 0;
+
+restore_freq:
+ ret = clk_set_rate(clk, old_freq);
+ if (ret)
+ dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n",
+ __func__, old_freq);
+restore_voltage:
+ /* This shouldn't harm even if the voltages weren't updated earlier */
+ if (old_supply_vdd->u_volt) {
+ ret = _opp_set_voltage(dev, old_supply_vbb, 0, vbb_reg, "vbb");
+ if (ret)
+ return ret;
+
+ ret = _opp_set_voltage(dev, old_supply_vdd, 0, vdd_reg,
+ "vdd");
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+static const struct ti_opp_supply_of_data omap_generic_of_data = {
+};
+
+static const struct ti_opp_supply_of_data omap_omap5_of_data = {
+ .flags = OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE,
+ .efuse_voltage_mask = 0xFFF,
+ .efuse_voltage_uv = false,
+};
+
+static const struct ti_opp_supply_of_data omap_omap5core_of_data = {
+ .flags = OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE | OPPDM_HAS_NO_ABB,
+ .efuse_voltage_mask = 0xFFF,
+ .efuse_voltage_uv = false,
+};
+
+static const struct of_device_id ti_opp_supply_of_match[] = {
+ {.compatible = "ti,omap-opp-supply", .data = &omap_generic_of_data},
+ {.compatible = "ti,omap5-opp-supply", .data = &omap_omap5_of_data},
+ {.compatible = "ti,omap5-core-opp-supply",
+ .data = &omap_omap5core_of_data},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ti_opp_supply_of_match);
+
+static int ti_opp_supply_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *cpu_dev = get_cpu_device(0);
+ const struct of_device_id *match;
+ const struct ti_opp_supply_of_data *of_data;
+ int ret = 0;
+
+ match = of_match_device(ti_opp_supply_of_match, dev);
+ if (!match) {
+ /* We do not expect this to happen */
+ dev_err(dev, "%s: Unable to match device\n", __func__);
+ return -ENODEV;
+ }
+ if (!match->data) {
+ /* Again, unlikely.. but mistakes do happen */
+ dev_err(dev, "%s: Bad data in match\n", __func__);
+ return -EINVAL;
+ }
+ of_data = match->data;
+
+ dev_set_drvdata(dev, (void *)of_data);
+
+ /* If we need optimized voltage */
+ if (of_data->flags & OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE) {
+ ret = _store_optimized_voltages(dev, &opp_data);
+ if (ret)
+ return ret;
+ }
+
+ ret = PTR_ERR_OR_ZERO(dev_pm_opp_register_set_opp_helper(cpu_dev,
+ ti_opp_supply_set_opp));
+ if (ret)
+ _free_optimized_voltages(dev, &opp_data);
+
+ return ret;
+}
+
+static struct platform_driver ti_opp_supply_driver = {
+ .probe = ti_opp_supply_probe,
+ .driver = {
+ .name = "ti_opp_supply",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ti_opp_supply_of_match),
+ },
+};
+module_platform_driver(ti_opp_supply_driver);
+
+MODULE_DESCRIPTION("Texas Instruments OMAP OPP Supply driver");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
--
2.15.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 3/4] dt-bindings: opp: Introduce ti-opp-supply bindings
From: Dave Gerlach @ 2017-12-15 4:25 UTC (permalink / raw)
To: Viresh Kumar, Rob Herring, Rafael J . Wysocki
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren, Nishanth Menon,
Dave Gerlach
In-Reply-To: <20171215042528.28715-1-d-gerlach-l0cyMroinI0@public.gmane.org>
Document the devicetree bindings that describe Texas Instruments
opp-supply which allow a platform to describe multiple regulators and
additional information, such as registers containing data needed to
program aforementioned regulators.
Signed-off-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
---
.../bindings/opp/ti-omap5-opp-supply.txt | 63 ++++++++++++++++++++++
1 file changed, 63 insertions(+)
create mode 100644 Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt
diff --git a/Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt b/Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt
new file mode 100644
index 000000000000..832346e489a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt
@@ -0,0 +1,63 @@
+Texas Instruments OMAP compatible OPP supply description
+
+OMAP5, DRA7, and AM57 family of SoCs have Class0 AVS eFuse registers which
+contain data that can be used to adjust voltages programmed for some of their
+supplies for more efficient operation. This binding provides the information
+needed to read these values and use them to program the main regulator during
+an OPP transitions.
+
+Also, some supplies may have an associated vbb-supply which is an Adaptive Body
+Bias regulator which much be transitioned in a specific sequence with regards
+to the vdd-supply and clk when making an OPP transition. By supplying two
+regulators to the device that will undergo OPP transitions we can make use
+of the multi regulator binding that is part of the OPP core described here [1]
+to describe both regulators needed by the platform.
+
+[1] Documentation/devicetree/bindings/opp/opp.txt
+
+Required Properties for Device Node:
+- vdd-supply: phandle to regulator controlling VDD supply
+- vbb-supply: phandle to regulator controlling Body Bias supply
+ (Usually Adaptive Body Bias regulator)
+
+Required Properties for opp-supply node:
+- compatible: Should be one of:
+ "ti,omap-opp-supply" - basic OPP supply controlling VDD and VBB
+ "ti,omap5-opp-supply" - OMAP5+ optimized voltages in efuse(class0)VDD
+ along with VBB
+ "ti,omap5-core-opp-supply" - OMAP5+ optimized voltages in efuse(class0) VDD
+ but no VBB.
+- reg: Address and length of the efuse register set for the device (mandatory
+ only for "ti,omap5-opp-supply")
+- ti,efuse-settings: An array of u32 tuple items providing information about
+ optimized efuse configuration. Each item consists of the following:
+ volt: voltage in uV - reference voltage (OPP voltage)
+ efuse_offseet: efuse offset from reg where the optimized voltage is stored.
+- ti,absolute-max-voltage-uv: absolute maximum voltage for the OPP supply.
+
+Example:
+
+/* Device Node (CPU) */
+cpus {
+ cpu0: cpu@0 {
+ device_type = "cpu";
+
+ ...
+
+ vdd-supply = <&vcc>;
+ vbb-supply = <&abb_mpu>;
+ };
+};
+
+/* OMAP OPP Supply with Class0 registers */
+opp_supply_mpu: opp_supply@4a003b20 {
+ compatible = "ti,omap5-opp-supply";
+ reg = <0x4a003b20 0x8>;
+ ti,efuse-settings = <
+ /* uV offset */
+ 1060000 0x0
+ 1160000 0x4
+ 1210000 0x8
+ >;
+ ti,absolute-max-voltage-uv = <1500000>;
+};
--
2.15.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 2/4] cpufreq: ti-cpufreq: Add support for multiple regulators
From: Dave Gerlach @ 2017-12-15 4:25 UTC (permalink / raw)
To: Viresh Kumar, Rob Herring, Rafael J . Wysocki
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren, Nishanth Menon,
Dave Gerlach
In-Reply-To: <20171215042528.28715-1-d-gerlach-l0cyMroinI0@public.gmane.org>
Some platforms, like those in the DRA7 and AM57 families, require the
scaling of multiple regulators in order to properly support higher OPPs.
Let the ti-cpufreq driver determine when this is required and pass the
appropriate regulator names to the OPP core so that they can be properly
managed.
Acked-by: Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
---
drivers/cpufreq/ti-cpufreq.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
index b1c230a1e2aa..a099b7bf74cd 100644
--- a/drivers/cpufreq/ti-cpufreq.c
+++ b/drivers/cpufreq/ti-cpufreq.c
@@ -51,6 +51,7 @@ struct ti_cpufreq_soc_data {
unsigned long efuse_mask;
unsigned long efuse_shift;
unsigned long rev_offset;
+ bool multi_regulator;
};
struct ti_cpufreq_data {
@@ -58,6 +59,7 @@ struct ti_cpufreq_data {
struct device_node *opp_node;
struct regmap *syscon;
const struct ti_cpufreq_soc_data *soc_data;
+ struct opp_table *opp_table;
};
static unsigned long amx3_efuse_xlate(struct ti_cpufreq_data *opp_data,
@@ -96,6 +98,7 @@ static struct ti_cpufreq_soc_data am3x_soc_data = {
.efuse_offset = 0x07fc,
.efuse_mask = 0x1fff,
.rev_offset = 0x600,
+ .multi_regulator = false,
};
static struct ti_cpufreq_soc_data am4x_soc_data = {
@@ -104,6 +107,7 @@ static struct ti_cpufreq_soc_data am4x_soc_data = {
.efuse_offset = 0x0610,
.efuse_mask = 0x3f,
.rev_offset = 0x600,
+ .multi_regulator = false,
};
static struct ti_cpufreq_soc_data dra7_soc_data = {
@@ -112,6 +116,7 @@ static struct ti_cpufreq_soc_data dra7_soc_data = {
.efuse_mask = 0xf80000,
.efuse_shift = 19,
.rev_offset = 0x204,
+ .multi_regulator = true,
};
/**
@@ -201,7 +206,9 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
u32 version[VERSION_COUNT];
struct device_node *np;
const struct of_device_id *match;
+ struct opp_table *ti_opp_table;
struct ti_cpufreq_data *opp_data;
+ const char * const reg_names[] = {"vdd", "vbb"};
int ret;
np = of_find_node_by_path("/");
@@ -248,16 +255,29 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
if (ret)
goto fail_put_node;
- ret = PTR_ERR_OR_ZERO(dev_pm_opp_set_supported_hw(opp_data->cpu_dev,
- version, VERSION_COUNT));
- if (ret) {
+ ti_opp_table = dev_pm_opp_set_supported_hw(opp_data->cpu_dev,
+ version, VERSION_COUNT);
+ if (IS_ERR(ti_opp_table)) {
dev_err(opp_data->cpu_dev,
"Failed to set supported hardware\n");
+ ret = PTR_ERR(ti_opp_table);
goto fail_put_node;
}
- of_node_put(opp_data->opp_node);
+ opp_data->opp_table = ti_opp_table;
+
+ if (opp_data->soc_data->multi_regulator) {
+ ti_opp_table = dev_pm_opp_set_regulators(opp_data->cpu_dev,
+ reg_names,
+ ARRAY_SIZE(reg_names));
+ if (IS_ERR(ti_opp_table)) {
+ dev_pm_opp_put_supported_hw(opp_data->opp_table);
+ ret = PTR_ERR(ti_opp_table);
+ goto fail_put_node;
+ }
+ }
+ of_node_put(opp_data->opp_node);
register_cpufreq_dt:
platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
--
2.15.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 1/4] cpufreq: ti-cpufreq: Convert to module_platform_driver
From: Dave Gerlach @ 2017-12-15 4:25 UTC (permalink / raw)
To: Viresh Kumar, Rob Herring, Rafael J . Wysocki
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren, Nishanth Menon,
Dave Gerlach
In-Reply-To: <20171215042528.28715-1-d-gerlach-l0cyMroinI0@public.gmane.org>
ti-cpufreq will be responsible for calling dev_pm_opp_set_regulators on
platforms that require AVS and ABB regulator support so we must be
able to defer probe if regulators are not yet available, so change
ti-cpufreq to be a module_platform_driver to allow for probe defer.
Acked-by: Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
---
drivers/cpufreq/ti-cpufreq.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
index 923317f03b4b..b1c230a1e2aa 100644
--- a/drivers/cpufreq/ti-cpufreq.c
+++ b/drivers/cpufreq/ti-cpufreq.c
@@ -17,6 +17,7 @@
#include <linux/cpu.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
+#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_platform.h>
@@ -195,7 +196,7 @@ static const struct of_device_id ti_cpufreq_of_match[] = {
{},
};
-static int ti_cpufreq_init(void)
+static int ti_cpufreq_probe(struct platform_device *pdev)
{
u32 version[VERSION_COUNT];
struct device_node *np;
@@ -269,4 +270,22 @@ static int ti_cpufreq_init(void)
return ret;
}
-device_initcall(ti_cpufreq_init);
+
+static int ti_cpufreq_init(void)
+{
+ platform_device_register_simple("ti-cpufreq", -1, NULL, 0);
+ return 0;
+}
+module_init(ti_cpufreq_init);
+
+static struct platform_driver ti_cpufreq_driver = {
+ .probe = ti_cpufreq_probe,
+ .driver = {
+ .name = "ti-cpufreq",
+ },
+};
+module_platform_driver(ti_cpufreq_driver);
+
+MODULE_DESCRIPTION("TI CPUFreq/OPP hw-supported driver");
+MODULE_AUTHOR("Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
--
2.15.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 0/4] PM / OPP: Introduce ti-opp-supply driver
From: Dave Gerlach @ 2017-12-15 4:25 UTC (permalink / raw)
To: Viresh Kumar, Rob Herring, Rafael J . Wysocki
Cc: Nishanth Menon, devicetree, linux-pm, Tony Lindgren, Dave Gerlach,
linux-omap, linux-arm-kernel
Hi,
This is v2 of the series to introduce the ti-opp-supply driver which makes
use of the OPP core to enable multiple regulator DVFS and AVS Class0 for
TI DRA7 and AM57 platforms. Version 1 of this series can be found here [1].
Very few changes since v1, just added Viresh's acks to patches 1 and 2 and
added SPDX license to the ti-opp-supply driver in patch 4.
Pushed updated branch here just in case [2].
Regards,
Dave
[1] https://www.spinics.net/lists/devicetree/msg205957.html
[2] https://github.com/dgerlach/linux-pm/tree/upstream/v4.15/ti-multireg-support-v2
Dave Gerlach (4):
cpufreq: ti-cpufreq: Convert to module_platform_driver
cpufreq: ti-cpufreq: Add support for multiple regulators
dt-bindings: opp: Introduce ti-opp-supply bindings
PM / OPP: Add ti-opp-supply driver
.../bindings/opp/ti-omap5-opp-supply.txt | 63 +++
drivers/cpufreq/ti-cpufreq.c | 51 ++-
drivers/opp/Makefile | 1 +
drivers/opp/ti-opp-supply.c | 425 +++++++++++++++++++++
4 files changed, 534 insertions(+), 6 deletions(-)
create mode 100644 Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt
create mode 100644 drivers/opp/ti-opp-supply.c
--
2.15.1
^ permalink raw reply
* Re: [PATCH] arm: dts: Remove leading 0x and 0s from bindings notation
From: Viresh Kumar @ 2017-12-15 4:00 UTC (permalink / raw)
To: Mathieu Malaterre
Cc: Rob Herring, Benoît Cousson, Tony Lindgren, Mark Rutland,
Russell King, Jesper Nilsson, Lars Persson, Niklas Cassel,
Nicolas Ferre, Alexandre Belloni, Ray Jui, Scott Branden,
Jon Mason, bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
Florian Fainelli, Sekhar Nori, Kevin Hilman, Kukjin Kim,
Krzysztof Kozlowski
In-Reply-To: <20171214165350.27850-1-malat-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>
On 14-12-17, 17:53, Mathieu Malaterre wrote:
> Improve the DTS files by removing all the leading "0x" and zeros to fix the
> following dtc warnings:
>
> Warning (unit_address_format): Node /XXX unit name should not have leading "0x"
>
> and
>
> Warning (unit_address_format): Node /XXX unit name should not have leading 0s
>
> Converted using the following command:
>
> find . -type f \( -iname *.dts -o -iname *.dtsi \) -exec sed -E -i -e "s/@0x([0-9a-fA-F\.]+)\s?\{/@\L\1 \{/g" -e "s/@0+([0-9a-fA-F\.]+)\s?\{/@\L\1 \{/g" {} +
>
> For simplicity, two sed expressions were used to solve each warnings separately.
>
> To make the regex expression more robust a few other issues were resolved,
> namely setting unit-address to lower case, and adding a whitespace before the
> the opening curly brace:
>
> https://elinux.org/Device_Tree_Linux#Linux_conventions
>
> This is a follow up to commit 4c9847b7375a ("dt-bindings: Remove leading 0x from bindings notation")
>
> Reported-by: David Daney <ddaney-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
> Suggested-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Mathieu Malaterre <malat-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>
> ---
> arch/arm/boot/dts/spear300.dtsi | 2 +-
> arch/arm/boot/dts/spear310.dtsi | 2 +-
> arch/arm/boot/dts/spear320.dtsi | 2 +-
Acked-by: Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
--
viresh
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] arm64: allwinner: a64: a64-olinuxino: add usb otg
From: kbuild test robot @ 2017-12-15 3:56 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, Maxime Ripard, Chen-Yu Tsai,
Icenowy Zheng, Rob Herring, Mark Rutland, Catalin Marinas,
Will Deacon, Michael Trimarchi,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Jagan Teki
In-Reply-To: <1513058169-25516-1-git-send-email-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1176 bytes --]
Hi Jagan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.15-rc3]
[cannot apply to next-20171214]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jagan-Teki/arm64-allwinner-a64-a64-olinuxino-add-usb-otg/20171215-084728
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm64-defconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64
All errors (new ones prefixed by >>):
>> Error: arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts:204.1-15 Label or path reg_drivevbus not found
>> FATAL ERROR: Syntax error parsing input tree
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 37312 bytes --]
^ permalink raw reply
* [PATCH] dt-bindings: fsl,imx-gpcv2: Fix the unit address
From: Fabio Estevam @ 2017-12-15 2:51 UTC (permalink / raw)
To: shawnguo-DgEjT+Ai2ygdnm+yROfE0A
Cc: andrew.smirnov-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
Fabio Estevam
From: Fabio Estevam <fabio.estevam-3arQi8VN3Tc@public.gmane.org>
In the provided example the unit address does not match the 'reg' value.
Fix the unit address.
Signed-off-by: Fabio Estevam <fabio.estevam-3arQi8VN3Tc@public.gmane.org>
---
Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt
index 02f45c6..19e1819 100644
--- a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt
+++ b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt
@@ -44,7 +44,7 @@ Example:
#address-cells = <1>;
#size-cells = <0>;
- pgc_pcie_phy: power-domain@3 {
+ pgc_pcie_phy: power-domain@IMX7_POWER_DOMAIN_PCIE_PHY {
#power-domain-cells = <0>;
reg = <IMX7_POWER_DOMAIN_PCIE_PHY>;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 2/2] ARM64: dts: meson-axg: enable ethernet for A113D S400 board
From: Yixun Lan @ 2017-12-15 2:10 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Kevin Hilman
Cc: Neil Armstrong, Jerome Brunet, Giuseppe Cavallaro,
Alexandre Torgue, Carlo Caione, Yixun Lan,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171215021014.231308-1-yixun.lan-LpR1jeaWuhtBDgjK7y7TUQ@public.gmane.org>
This is tested in the S400 dev board which use a RTL8211F PHY,
and the pins connect to the 'eth_rgmii_y_pins' group.
Reviewed-by: Neil Armstrong <narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
Signed-off-by: Yixun Lan <yixun.lan-LpR1jeaWuhtBDgjK7y7TUQ@public.gmane.org>
---
arch/arm64/boot/dts/amlogic/meson-axg-s400.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
index 70eca1f8736a..b8c4f1913d28 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
@@ -20,3 +20,10 @@
&uart_AO {
status = "okay";
};
+
+ðmac {
+ status = "okay";
+ phy-mode = "rgmii";
+ pinctrl-0 = <ð_rgmii_y_pins>;
+ pinctrl-names = "default";
+};
--
2.15.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 1/2] ARM64: dts: meson-axg: add ethernet mac controller
From: Yixun Lan @ 2017-12-15 2:10 UTC (permalink / raw)
To: devicetree, Kevin Hilman
Cc: Neil Armstrong, Jerome Brunet, Giuseppe Cavallaro,
Alexandre Torgue, Carlo Caione, Yixun Lan, linux-amlogic,
linux-arm-kernel, linux-kernel, netdev
In-Reply-To: <20171215021014.231308-1-yixun.lan@amlogic.com>
Add DT info for the stmmac ethernet MAC which found in
the Amlogic's Meson-AXG SoC, also describe the ethernet
pinctrl & clock information here.
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
---
arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 54 ++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index d356ce74ad89..94c4972222b7 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -7,6 +7,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/axg-clkc.h>
/ {
compatible = "amlogic,meson-axg";
@@ -148,6 +149,19 @@
#address-cells = <0>;
};
+ ethmac: ethernet@ff3f0000 {
+ compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac";
+ reg = <0x0 0xff3f0000 0x0 0x10000
+ 0x0 0xff634540 0x0 0x8>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "macirq";
+ clocks = <&clkc CLKID_ETH>,
+ <&clkc CLKID_FCLK_DIV2>,
+ <&clkc CLKID_MPLL2>;
+ clock-names = "stmmaceth", "clkin0", "clkin1";
+ status = "disabled";
+ };
+
hiubus: bus@ff63c000 {
compatible = "simple-bus";
reg = <0x0 0xff63c000 0x0 0x1c00>;
@@ -194,6 +208,46 @@
#gpio-cells = <2>;
gpio-ranges = <&pinctrl_periphs 0 0 86>;
};
+
+ eth_rgmii_x_pins: eth-x-rgmii {
+ mux {
+ groups = "eth_mdio_x",
+ "eth_mdc_x",
+ "eth_rgmii_rx_clk_x",
+ "eth_rx_dv_x",
+ "eth_rxd0_x",
+ "eth_rxd1_x",
+ "eth_rxd2_rgmii",
+ "eth_rxd3_rgmii",
+ "eth_rgmii_tx_clk",
+ "eth_txen_x",
+ "eth_txd0_x",
+ "eth_txd1_x",
+ "eth_txd2_rgmii",
+ "eth_txd3_rgmii";
+ function = "eth";
+ };
+ };
+
+ eth_rgmii_y_pins: eth-y-rgmii {
+ mux {
+ groups = "eth_mdio_y",
+ "eth_mdc_y",
+ "eth_rgmii_rx_clk_y",
+ "eth_rx_dv_y",
+ "eth_rxd0_y",
+ "eth_rxd1_y",
+ "eth_rxd2_rgmii",
+ "eth_rxd3_rgmii",
+ "eth_rgmii_tx_clk",
+ "eth_txen_y",
+ "eth_txd0_y",
+ "eth_txd1_y",
+ "eth_txd2_rgmii",
+ "eth_txd3_rgmii";
+ function = "eth";
+ };
+ };
};
};
--
2.15.1
^ permalink raw reply related
* [PATCH v3 0/2] Add ethernet support for Meson-AXG SoC
From: Yixun Lan @ 2017-12-15 2:10 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Kevin Hilman
Cc: Neil Armstrong, Jerome Brunet, Giuseppe Cavallaro,
Alexandre Torgue, Carlo Caione, Yixun Lan,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
This series try to add support for the ethernet MAC controller
found in Meson-AXG SoC, and also enable it in the S400 board.
Changes in v3 since [4]:
- put clock DT info in soc.dtsi
- separate DT for 'add support for the controller' vs 'enable in board'
Changes in v2 since [1]:
- rebase to kevin's v4.16/dt64 branch
- add Neil's Reviewed-by
- move clock info to board.dts instead of in soc.dtsi
- drop "meson-axg-dwmac" compatible string, since we didn't use this
we could re-add it later when we really need.
- note: to make ethernet work properly,it depend on clock & pinctrl[2],
to compile the DTS, the patch [3] is required.
the code part will be taken via clock & pinctrl subsystem tree.
[1]
http://lists.infradead.org/pipermail/linux-amlogic/2017-November/005301.html
[4]
http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005768.html
[2]
http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005735.html
http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005694.html
[3]
http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005738.html
Yixun Lan (2):
ARM64: dts: meson-axg: add ethernet mac controller
ARM64: dts: meson-axg: enable ethernet for A113D S400 board
arch/arm64/boot/dts/amlogic/meson-axg-s400.dts | 7 ++++
arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 54 ++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
--
2.15.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next] net: dsa: bcm_sf2: Update compatible string for 7278B0
From: Florian Fainelli @ 2017-12-15 1:59 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: Florian Fainelli, Rob Herring, Mark Rutland, Andrew Lunn,
Vivien Didelot, David S. Miller,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
Update the compatible string and Device Tree binding document for
7278B0.
Signed-off-by: Florian Fainelli <f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt | 5 ++++-
drivers/net/dsa/bcm_sf2.c | 3 +++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt b/Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt
index 9a734d808aa7..b7336b9d6a3c 100644
--- a/Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt
+++ b/Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt
@@ -2,7 +2,10 @@
Required properties:
-- compatible: should be "brcm,bcm7445-switch-v4.0" or "brcm,bcm7278-switch-v4.0"
+- compatible: should be one of
+ "brcm,bcm7445-switch-v4.0"
+ "brcm,bcm7278-switch-v4.0"
+ "brcm,bcm7278-switch-v4.8"
- reg: addresses and length of the register sets for the device, must be 6
pairs of register addresses and lengths
- interrupts: interrupts for the devices, must be two interrupts
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 8ea0cd494ea0..0378eded31f2 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -948,6 +948,9 @@ static const struct of_device_id bcm_sf2_of_match[] = {
{ .compatible = "brcm,bcm7278-switch-v4.0",
.data = &bcm_sf2_7278_data
},
+ { .compatible = "brcm,bcm7278-switch-v4.8",
+ .data = &bcm_sf2_7278_data
+ },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, bcm_sf2_of_match);
--
2.14.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v7 6/6] arm64: dts: meson-axg: switch uart_ao clock to CLK81
From: Yixun Lan @ 2017-12-15 1:49 UTC (permalink / raw)
To: Jerome Brunet, Neil Armstrong, Kevin Hilman
Cc: yixun.lan, Rob Herring, Mark Rutland, Michael Turquette,
Stephen Boyd, Carlo Caione, Qiufang Dai, Jian Hu, linux-amlogic,
devicetree, linux-clk, linux-arm-kernel, linux-kernel
In-Reply-To: <1513270051.2261.11.camel@baylibre.com>
On 12/15/17 00:47, Jerome Brunet wrote:
> On Mon, 2017-12-11 at 22:13 +0800, Yixun Lan wrote:
>> Switch the uart_ao pclk to CLK81 since the clock driver is ready.
>> Also move the clock info to the board.dts instead in the soc.dtsi.
>
> Same comment as for ethmac, is it really wise ?
> Isn't the clock setup the same for the axg family ?
>
HI Jerome:
yes, should be same for AXG family
HI Kevin:
could you take the patch [5/6]? then I just need to resend for this one
Yixun
^ permalink raw reply
* Re: [PATCH v2] ARM64: dts: meson-axg: add ethernet mac controller
From: Yixun Lan @ 2017-12-15 1:46 UTC (permalink / raw)
To: Jerome Brunet, devicetree-u79uwXL29TY76Z2rM5mHXA, Kevin Hilman
Cc: yixun.lan-LpR1jeaWuhtBDgjK7y7TUQ, Neil Armstrong,
Giuseppe Cavallaro, Alexandre Torgue, Carlo Caione,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1513269947.2261.9.camel-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
Hi Jerome:
On 12/15/17 00:45, Jerome Brunet wrote:
> On Thu, 2017-12-14 at 11:02 +0800, Yixun Lan wrote:
>> ---
>> Changes in v2 since [1]:
>> - rebase to kevin's v4.16/dt64 branch
>> - add Neil's Reviewed-by
>> - move clock info to board.dts instead of in soc.dtsi
>
> You got this comment regarding the pwm clock setup. the setup of the pwm clocks
> depends on the use case, so should defined depending on the requirement on the
> board
>
Yes, I thought it was a convention to put the clock into board.dts ..
I think it's more clear if you could have a three level hierarchy:
arch.dtsi. soc.dtsi, board.dts
most of clock and pinctrl could go to soc.dtsi
> This is not the case for the ethmac, the clock setup will be same for every
> board, unless I missed something. the clock bindings should be defined in
> meson-axg.dtsi, I think
>
yes, clock should be same
I will send another series to fix this
also will fold the DT separation (for soc.dtsi vs board.dts)
>> - drop "meson-axg-dwmac" compatible string, since we didn't use this
>> we could re-add it later when we really need.
>> - note: to make ethernet work properly,it depend on clock & pinctrl[2],
>> to compile the DTS, the patch [3] is required.
>> the code part will be taken via clock & pinctrl subsystem tree.
>
> .
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox