* Re: [PATCH v2] tpm_tis: Allow tpm_tis to be bound using DT
From: Jarkko Sakkinen @ 2016-11-04 6:57 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Mark Rutland, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20161104042658.oaqd5cvrejdd7azb-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
On Thu, Nov 03, 2016 at 10:26:58PM -0600, Jarkko Sakkinen wrote:
> On Wed, Oct 26, 2016 at 11:04:37AM -0600, Jason Gunthorpe wrote:
> > This provides an open firwmare driver binding for tpm_tis. OF
> > is useful on arches where ACPI/PNP is not used.
> >
> > The tcg,tpm-tis-mmio register map interface is specified by the TCG.
> >
> > Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
>
> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Oops. Didn't notice Robs comments. Would you mind rolling one more
version? Thanks and sorry.
/Jarkko
>
> /Jarkko
>
> > ---
> > .../bindings/security/tpm/tpm_tis_mmio.txt | 23 ++++++++++++++++++++++
> > drivers/char/tpm/Kconfig | 2 +-
> > drivers/char/tpm/tpm_tis.c | 11 +++++++++++
> > 3 files changed, 35 insertions(+), 1 deletion(-)
> > create mode 100644 Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
> >
> > v2 (from Mark)
> > - Change name to tpm-tis-mmio (and fix c&p spi)
> > - Include some valid chip names
> >
> > diff --git a/Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt b/Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
> > new file mode 100644
> > index 000000000000..f9a853165cd0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
> > @@ -0,0 +1,23 @@
> > +Trusted Computing Group MMIO Trusted Platform Module
> > +
> > +The TCG defines multi vendor standard for accessing a TPM chip, this
> > +is the standard protocol defined to access the TPM via MMIO. Typically
> > +this interface will be implemented over Intel's LPC bus.
> > +
> > +Refer to the 'TCG PC Client Specific TPM Interface Specification (TIS)' TCG
> > +publication for the specification.
> > +
> > +Required properties:
> > +
> > +- compatible: should contain a string below for the chip, followed by
> > + "tcg,tpm-tis-mmio". Valid chip strings are:
> > + * "atmel,at97sc3204"
> > +- reg: The location of the MMIO registers, should be at least 0x5000 bytes
> > +- interrupt: An optional interrupt indicating command completion.
> > +
> > +Example:
> > +
> > + tpm_tis@90000 {
> > + compatible = "atmel,at97sc3204", "tcg,tpm-tis-mmio";
> > + reg = <0x90000 0x5000>;
> > + };
> > diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> > index 9faa0b1e7766..277186d3b668 100644
> > --- a/drivers/char/tpm/Kconfig
> > +++ b/drivers/char/tpm/Kconfig
> > @@ -32,7 +32,7 @@ config TCG_TIS_CORE
> >
> > config TCG_TIS
> > tristate "TPM Interface Specification 1.2 Interface / TPM 2.0 FIFO Interface"
> > - depends on X86
> > + depends on X86 || OF
> > select TCG_TIS_CORE
> > ---help---
> > If you have a TPM security chip that is compliant with the
> > diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> > index eaf5730d79eb..0127af130cb1 100644
> > --- a/drivers/char/tpm/tpm_tis.c
> > +++ b/drivers/char/tpm/tpm_tis.c
> > @@ -28,6 +28,8 @@
> > #include <linux/wait.h>
> > #include <linux/acpi.h>
> > #include <linux/freezer.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > #include "tpm.h"
> > #include "tpm_tis_core.h"
> >
> > @@ -354,12 +356,21 @@ static int tpm_tis_plat_remove(struct platform_device *pdev)
> > return 0;
> > }
> >
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id tis_of_platform_match[] = {
> > + {.compatible = "tcg,tpm-tis-mmio"},
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(of, tis_of_platform_match);
> > +#endif
> > +
> > static struct platform_driver tis_drv = {
> > .probe = tpm_tis_plat_probe,
> > .remove = tpm_tis_plat_remove,
> > .driver = {
> > .name = "tpm_tis",
> > .pm = &tpm_tis_pm,
> > + .of_match_table = of_match_ptr(tis_of_platform_match),
> > },
> > };
> >
> > --
> > 2.1.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
* Re: [PATCH v6 6/7] net: ethernet: bgmac: add NS2 support
From: Rafal Milecki @ 2016-11-04 6:48 UTC (permalink / raw)
To: Jon Mason, David Miller, Rob Herring, Mark Rutland,
Florian Fainelli
Cc: netdev, bcm-kernel-feedback-list, linux-kernel, linux-arm-kernel,
devicetree
In-Reply-To: <1478236262-3351-7-git-send-email-jon.mason@broadcom.com>
On 11/04/2016 06:11 AM, Jon Mason wrote:
> Add support for the variant of amac hardware present in the Broadcom
> Northstar2 based SoCs. Northstar2 requires an additional register to be
> configured with the port speed/duplexity (NICPM). This can be added to
> the link callback to hide it from the instances that do not use this.
> Also, clearing of the pending interrupts on init is required due to
> observed issues on some platforms.
>
> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Checked for possible regressions on Northstar, looks OK.
Acked-by: Rafał Miłecki <rafal@milecki.pl>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v6 5/7] net: ethernet: bgmac: device tree phy enablement
From: Rafal Milecki @ 2016-11-04 6:43 UTC (permalink / raw)
To: Jon Mason, David Miller, Rob Herring, Mark Rutland,
Florian Fainelli
Cc: netdev, bcm-kernel-feedback-list, linux-kernel, linux-arm-kernel,
devicetree
In-Reply-To: <1478236262-3351-6-git-send-email-jon.mason@broadcom.com>
On 11/04/2016 06:11 AM, Jon Mason wrote:
> Change the bgmac driver to allow for phy's defined by the device tree
>
> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Checked for possible regressions on Northstar, looks OK.
Acked-by: Rafał Miłecki <rafal@milecki.pl>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3] clk: mediatek: Allow changing PLL rate when it is off
From: James Liao @ 2016-11-04 6:42 UTC (permalink / raw)
To: Matthias Brugger, Mike Turquette, Stephen Boyd
Cc: srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Daniel Kurtz, Sascha Hauer,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, James Liao
Some modules may need to change its clock rate before turn on it.
So changing PLL's rate when it is off should be allowed.
This patch removes PLL enabled check before set rate, so that
PLLs can set new frequency even if they are off.
On MT8173 for example, ARMPLL's enable bit can be controlled by
other HW. That means ARMPLL may be turned on even if we (CPU / SW)
set ARMPLL's enable bit as 0. In this case, SW may want and can
still change ARMPLL's rate by changing its pcw and postdiv settings.
But without this patch, new pcw setting will not be applied because
its enable bit is 0.
Signed-off-by: James Liao <jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Acked-by: Michael Turquette <mturuqette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
---
Please refer to previous comments in [1] and [2].
changes since v2:
- Rebase to v4.9-rc1.
changes since v1:
- Add more explanation in commit messages.
[1] https://patchwork.kernel.org/patch/7983221/
[2] https://patchwork.kernel.org/patch/7998891/
drivers/clk/mediatek/clk-pll.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 0c2deac..80f57b4 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -91,9 +91,6 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
int postdiv)
{
u32 con1, val;
- int pll_en;
-
- pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN;
/* set postdiv */
val = readl(pll->pd_addr);
@@ -114,15 +111,13 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
con1 = readl(pll->base_addr + REG_CON1);
- if (pll_en)
- con1 |= CON0_PCW_CHG;
+ con1 |= CON0_PCW_CHG;
writel(con1, pll->base_addr + REG_CON1);
if (pll->tuner_addr)
writel(con1 + 1, pll->tuner_addr);
- if (pll_en)
- udelay(20);
+ udelay(20);
}
/*
--
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
* RE: [PATCH v5] drm/fsl-dcu: Implement gamma_lut atomic crtc properties
From: Meng Yi @ 2016-11-04 6:42 UTC (permalink / raw)
To: Stefan Agner
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org,
dri-devel@lists.freedesktop.org, robh+dt@kernel.org
In-Reply-To: <2e4a55f00c57b094e376a743d7b056f7@agner.ch>
Hi Stefan,
>
> How did you actually test that? I have a hard time to get anything useable with
> this code.
>
> The display looks completely borked (colors are way off, and at random either
> too dark or too bright).
>
> I then also added Gamma 1.0 (and different values) to the Monitor section of
> xorg.conf, but still not really usable.
>
I just did few more test using libdrm which had been modified for testing gamma.
And I find you are right. It's my negligence that just tested one case for gamma using all 0xff;
.....
> > drm_crtc_send_vblank_event(crtc, event);
> > spin_unlock_irq(&crtc->dev->event_lock);
> > }
> > +
> > + if (crtc->state->color_mgmt_changed && crtc->state->gamma_lut)
> > + fsl_crtc_gamma_set(crtc, (struct drm_color_lut *)
> > + crtc->state->gamma_lut->data, 256);
>
> So this is called while the CRTC is enabled. Others do it there too, but I think in
> our case we should not. The reference manual says:
>
> "The gamma table can only be read or written when the 2D-ACE is not enabled
> or during the vertical blanking period."
>
Yes, now gamma correction function behavior weird.
When setting gamma table within crtc enable during initializing, it works correctly. And not right during runtime so far.
Thanks,
Meng
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH 1/4] pinctrl: Introduce generic #pinctrl-cells and pinctrl_parse_index_with_args
From: kbuild test robot @ 2016-11-04 6:03 UTC (permalink / raw)
To: Tony Lindgren
Cc: kbuild-all, Linus Walleij, Jon Hunter, Mark Rutland, Rob Herring,
Grygorii Strashko, Nishanth Menon, linux-gpio, devicetree,
linux-kernel, linux-omap
In-Reply-To: <20161103163550.27330-2-tony@atomide.com>
[-- Attachment #1: Type: text/plain, Size: 2027 bytes --]
Hi Tony,
[auto build test WARNING on pinctrl/for-next]
[also build test WARNING on v4.9-rc3 next-20161028]
[cannot apply to robh/for-next]
[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/Tony-Lindgren/Generic-pinctrl-cells-and-and-pinctrl_parse_index_with_args/20161104-004449
base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git for-next
config: x86_64-randconfig-i0-201644 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
In file included from drivers/pinctrl/core.c:36:0:
>> drivers/pinctrl/devicetree.h:29:14: warning: 'struct of_phandle_args' declared inside parameter list
struct of_phandle_args *out_args);
^
>> drivers/pinctrl/devicetree.h:29:14: warning: its scope is only this definition or declaration, which is probably not what you want
vim +29 drivers/pinctrl/devicetree.h
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifdef CONFIG_OF
20
21 void pinctrl_dt_free_maps(struct pinctrl *p);
22 int pinctrl_dt_to_map(struct pinctrl *p);
23
24 int pinctrl_count_index_with_args(const struct device_node *np,
25 const char *list_name);
26
27 int pinctrl_parse_index_with_args(const struct device_node *np,
28 const char *list_name, int index,
> 29 struct of_phandle_args *out_args);
30
31 #else
32
33 static inline int pinctrl_dt_to_map(struct pinctrl *p)
34 {
35 return 0;
36 }
37
---
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: 24875 bytes --]
^ permalink raw reply
* Re: [PATCH] of: base: Export symbol of __of_find_all_nodes()
From: Laxman Dewangan @ 2016-11-04 5:32 UTC (permalink / raw)
To: Rob Herring
Cc: Frank Rowand, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAL_JsqLMfKNUxgYLSePAD7msW+nVdze3LgNrUMXMY1BfYkzs0A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Thursday 03 November 2016 07:46 PM, Rob Herring wrote:
> On Thu, Nov 3, 2016 at 12:24 AM, Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
>> On Thursday 03 November 2016 09:09 AM, Rob Herring wrote:
>>> On Fri, Oct 28, 2016 at 6:28 AM, Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>>> wrote:
>>>> The function __of_find_all_nodes() is used in the public header
>>>> linux/of.h and if any driver developed using this API then
>>>> it reports error as unknown symbol if compiled as module.
>>>>
>>>> Export this APIs using EXPORT_SYMBOL() so that it can be used
>>>> from driver compiled as module.
>>> What driver needs this? This isn't really a function I'd expect drivers to
>>> use.
>>>
>> I am using the for loop for each node using the macro
>> for_each_of_allnodes_from() which is define as
>>
>> #define for_each_of_allnodes_from(from, dn) \
>> for (dn = __of_find_all_nodes(from); dn; dn =
>> __of_find_all_nodes(dn))
>>
>> and this is using the above APIs.
> And then what driver is using this define?
We are developing the utils/testcase on OF interface echo system. In one
of the testcase, we want to limit the node and property name length to
32 (max) as per ePAPR specs. This is needed to reuse the DT in multi-OS
environment and so want to maintain ePAPR compliance here.
We are using the above macro for iterating over each node.
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information. Any unauthorized review, use, disclosure or distribution
is prohibited. If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
--
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 5/6] arm64: dts: msm8994 SoC and Huawei Angler (Nexus 6P) support
From: Jeremy McNicoll @ 2016-11-04 5:18 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Stephen Boyd, Andy Gross, Jeremy McNicoll,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, robh-DgEjT+Ai2ygdnm+yROfE0A,
arnd-r2nGTMty4D4, mark.rutland-5wv7dgnIgG8,
michael.scott-QSEj5FYQhm4dnm+yROfE0A, Bastian K?cher
In-Reply-To: <20161104015713.GX25787@tuxbot>
On 2016-11-03 7:57 PM, Bjorn Andersson wrote:
> On Thu 03 Nov 17:20 PDT 2016, Jeremy McNicoll wrote:
>
>> On Thu, Nov 03, 2016 at 04:04:29PM -0700, Bjorn Andersson wrote:
>>> On Thu 03 Nov 15:42 PDT 2016, Stephen Boyd wrote:
>>>
>>>> On 11/03/2016 03:32 PM, Andy Gross wrote:
>>>>> On Thu, Oct 27, 2016 at 05:54:01PM -0700, Jeremy McNicoll wrote:
>>>>>> On 2016-10-27 5:06 PM, Stephen Boyd wrote:
>>>>>>> On 10/25, Jeremy McNicoll wrote:
>>>>>>>> diff --git a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
>>>>>>>> new file mode 100644
>>>>>>>> index 0000000..2fc68c4
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
>>>>>>>> @@ -0,0 +1,40 @@
>>>>>>>> +/* Copyright (c) 2015, Huawei Inc. All rights reserved.
>>>>>>>> + * Copyright (c) 2016, The Linux Foundation. All rights reserved.
>>>>>>>> + *
>>>>>>>> + * This program is free software; you can redistribute it and/or modify
>>>>>>>> + * it under the terms of the GNU General Public License version 2 and
>>>>>>>> + * only version 2 as published by the Free Software Foundation.
>>>>>>>> + *
>>>>>>>> + * This program is distributed in the hope that it will be useful,
>>>>>>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>>>>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>>>>>>> + * GNU General Public License for more details.
>>>>>>>> + */
>>>>>>>> +
>>>>>>>> +/dts-v1/;
>>>>>>>> +
>>>>>>>> +#include "msm8994-v2.0.dtsi"
>>>>>>>> +
>>>>>>>> +/ {
>>>>>>>> + model = "HUAWEI MSM8994 ANGLER rev-1.01";
>>>>>>>> + compatible = "qcom,msm8994";
>>>>>>> Please replace this with something more specific for the actual
>>>>>>> board. Preferably with the board manufacturer vendor prefix and
>>>>>>> some sort of string for the board.
>>>>> Something like?
>>>>>
>>>>> "huawei,nexus-6P", "qcom,msm8994"
>>>>
>>>> Sure, except completely remove qcom,msm8994 from there.
>>>
>>> Why? So far we have always used the form <device>, <platform> as
>>> compatible. This is even in line with ePAPR, what changed?
>>>
>>> Also, the compatible should be "huawei,angler" (if I read the internet
>>> correctly) and the model should contain the product name
>>> (Huawei Nexus 6P).
>>>
>>
>> What about
>>
>> model = "Huawei Nexus 6P";
>> compatible = "huawei, angler", "qcom,msm8994";
> ^
> |
> unwanted space
>
> Apart from that, I think it looks good and in line with how we've done
> the other boards.
>
... just for completeness sake. Here is what I plan on using for the 5X
model = "LG Nexus 5X";
compatible = "lg,bullhead", "qcom,msm8992";
-jeremy
> Regards,
> Bjorn
>
--
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 v6 7/7] arm64: dts: NS2: add AMAC ethernet support
From: Jon Mason @ 2016-11-04 5:11 UTC (permalink / raw)
To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>
Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device
tree
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 +++++
arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 ++++++++++++
2 files changed, 17 insertions(+)
diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
index b09f3bc..c4d5442 100644
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@ -56,6 +56,10 @@
};
};
+&enet {
+ status = "ok";
+};
+
&pci_phy0 {
status = "ok";
};
@@ -174,6 +178,7 @@
&mdio_mux_iproc {
mdio@10 {
gphy0: eth-phy@10 {
+ enet-phy-lane-swap;
reg = <0x10>;
};
};
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index d95dc40..773ed59 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -191,6 +191,18 @@
#include "ns2-clock.dtsi"
+ enet: ethernet@61000000 {
+ compatible = "brcm,ns2-amac";
+ reg = <0x61000000 0x1000>,
+ <0x61090000 0x1000>,
+ <0x61030000 0x100>;
+ reg-names = "amac_base", "idm_base", "nicpm_base";
+ interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+ phy-handle = <&gphy0>;
+ phy-mode = "rgmii";
+ status = "disabled";
+ };
+
dma0: dma@61360000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x61360000 0x1000>;
--
2.7.4
^ permalink raw reply related
* [PATCH v6 6/7] net: ethernet: bgmac: add NS2 support
From: Jon Mason @ 2016-11-04 5:11 UTC (permalink / raw)
To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
Cc: devicetree, netdev, linux-kernel, bcm-kernel-feedback-list, rafal,
linux-arm-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>
Add support for the variant of amac hardware present in the Broadcom
Northstar2 based SoCs. Northstar2 requires an additional register to be
configured with the port speed/duplexity (NICPM). This can be added to
the link callback to hide it from the instances that do not use this.
Also, clearing of the pending interrupts on init is required due to
observed issues on some platforms.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +++++++++++++++++++++++++-
drivers/net/ethernet/broadcom/bgmac.c | 3 ++
drivers/net/ethernet/broadcom/bgmac.h | 1 +
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c
index 4642940..6f736c1 100644
--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -14,12 +14,21 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bcma/bcma.h>
+#include <linux/brcmphy.h>
#include <linux/etherdevice.h>
#include <linux/of_address.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include "bgmac.h"
+#define NICPM_IOMUX_CTRL 0x00000008
+
+#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000
+#define NICPM_IOMUX_CTRL_SPD_SHIFT 10
+#define NICPM_IOMUX_CTRL_SPD_10M 0
+#define NICPM_IOMUX_CTRL_SPD_100M 1
+#define NICPM_IOMUX_CTRL_SPD_1000M 2
+
static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset)
{
return readl(bgmac->plat.base + offset);
@@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
WARN_ON(1);
}
+static void bgmac_nicpm_speed_set(struct net_device *net_dev)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+ u32 val;
+
+ if (!bgmac->plat.nicpm_base)
+ return;
+
+ val = NICPM_IOMUX_CTRL_INIT_VAL;
+ switch (bgmac->net_dev->phydev->speed) {
+ default:
+ netdev_err(net_dev, "Unsupported speed. Defaulting to 1000Mb\n");
+ case SPEED_1000:
+ val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+ break;
+ case SPEED_100:
+ val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+ break;
+ case SPEED_10:
+ val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+ break;
+ }
+
+ writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL);
+
+ bgmac_adjust_link(bgmac->net_dev);
+}
+
static int platform_phy_connect(struct bgmac *bgmac)
{
struct phy_device *phy_dev;
- phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
- bgmac_adjust_link);
+ if (bgmac->plat.nicpm_base)
+ phy_dev = of_phy_get_and_connect(bgmac->net_dev,
+ bgmac->dev->of_node,
+ bgmac_nicpm_speed_set);
+ else
+ phy_dev = of_phy_get_and_connect(bgmac->net_dev,
+ bgmac->dev->of_node,
+ bgmac_adjust_link);
if (!phy_dev) {
dev_err(bgmac->dev, "PHY connection failed\n");
return -ENODEV;
@@ -156,6 +199,14 @@ static int bgmac_probe(struct platform_device *pdev)
if (IS_ERR(bgmac->plat.idm_base))
return PTR_ERR(bgmac->plat.idm_base);
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
+ if (regs) {
+ bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
+ regs);
+ if (IS_ERR(bgmac->plat.nicpm_base))
+ return PTR_ERR(bgmac->plat.nicpm_base);
+ }
+
bgmac->read = platform_bgmac_read;
bgmac->write = platform_bgmac_write;
bgmac->idm_read = platform_bgmac_idm_read;
@@ -187,6 +238,7 @@ static int bgmac_remove(struct platform_device *pdev)
static const struct of_device_id bgmac_of_enet_match[] = {
{.compatible = "brcm,amac",},
{.compatible = "brcm,nsp-amac",},
+ {.compatible = "brcm,ns2-amac",},
{},
};
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 7f66ea7..a29787f 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac)
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
static void bgmac_chip_init(struct bgmac *bgmac)
{
+ /* Clear any erroneously pending interrupts */
+ bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
+
/* 1 interrupt per received frame */
bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
index bfd9f40..71f493f 100644
--- a/drivers/net/ethernet/broadcom/bgmac.h
+++ b/drivers/net/ethernet/broadcom/bgmac.h
@@ -463,6 +463,7 @@ struct bgmac {
struct {
void *base;
void *idm_base;
+ void *nicpm_base;
} plat;
struct {
struct bcma_device *core;
--
2.7.4
^ permalink raw reply related
* [PATCH v6 5/7] net: ethernet: bgmac: device tree phy enablement
From: Jon Mason @ 2016-11-04 5:11 UTC (permalink / raw)
To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>
Change the bgmac driver to allow for phy's defined by the device tree
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
drivers/net/ethernet/broadcom/bgmac-bcma.c | 22 +++++++++++++++++++
drivers/net/ethernet/broadcom/bgmac-platform.c | 22 ++++++++++++++++++-
drivers/net/ethernet/broadcom/bgmac.c | 29 +++++---------------------
drivers/net/ethernet/broadcom/bgmac.h | 8 +++++++
4 files changed, 56 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c
index c16ec3a..4a4ffc0 100644
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
@@ -80,6 +80,24 @@ static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask,
bcma_maskset32(bgmac->bcma.cmn, offset, mask, set);
}
+static int bcma_phy_connect(struct bgmac *bgmac)
+{
+ struct phy_device *phy_dev;
+ char bus_id[MII_BUS_ID_SIZE + 3];
+
+ /* Connect to the PHY */
+ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
+ bgmac->phyaddr);
+ phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
+ PHY_INTERFACE_MODE_MII);
+ if (IS_ERR(phy_dev)) {
+ dev_err(bgmac->dev, "PHY connection failed\n");
+ return PTR_ERR(phy_dev);
+ }
+
+ return 0;
+}
+
static const struct bcma_device_id bgmac_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT,
BCMA_ANY_REV, BCMA_ANY_CLASS),
@@ -275,6 +293,10 @@ static int bgmac_probe(struct bcma_device *core)
bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset;
bgmac->get_bus_clock = bcma_bgmac_get_bus_clock;
bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32;
+ if (bgmac->mii_bus)
+ bgmac->phy_connect = bcma_phy_connect;
+ else
+ bgmac->phy_connect = bgmac_phy_connect_direct;
err = bgmac_enet_probe(bgmac);
if (err)
diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c
index be52f27..4642940 100644
--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -16,6 +16,7 @@
#include <linux/bcma/bcma.h>
#include <linux/etherdevice.h>
#include <linux/of_address.h>
+#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include "bgmac.h"
@@ -86,6 +87,20 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
WARN_ON(1);
}
+static int platform_phy_connect(struct bgmac *bgmac)
+{
+ struct phy_device *phy_dev;
+
+ phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
+ bgmac_adjust_link);
+ if (!phy_dev) {
+ dev_err(bgmac->dev, "PHY connection failed\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int bgmac_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -102,7 +117,6 @@ static int bgmac_probe(struct platform_device *pdev)
/* Set the features of the 4707 family */
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
- bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4;
bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP;
bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP;
@@ -151,6 +165,12 @@ static int bgmac_probe(struct platform_device *pdev)
bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset;
bgmac->get_bus_clock = platform_bgmac_get_bus_clock;
bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32;
+ if (of_parse_phandle(np, "phy-handle", 0)) {
+ bgmac->phy_connect = platform_phy_connect;
+ } else {
+ bgmac->phy_connect = bgmac_phy_connect_direct;
+ bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
+ }
return bgmac_enet_probe(bgmac);
}
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 31ca204..7f66ea7 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1388,7 +1388,7 @@ static const struct ethtool_ops bgmac_ethtool_ops = {
* MII
**************************************************/
-static void bgmac_adjust_link(struct net_device *net_dev)
+void bgmac_adjust_link(struct net_device *net_dev)
{
struct bgmac *bgmac = netdev_priv(net_dev);
struct phy_device *phy_dev = net_dev->phydev;
@@ -1411,8 +1411,9 @@ static void bgmac_adjust_link(struct net_device *net_dev)
phy_print_status(phy_dev);
}
}
+EXPORT_SYMBOL_GPL(bgmac_adjust_link);
-static int bgmac_phy_connect_direct(struct bgmac *bgmac)
+int bgmac_phy_connect_direct(struct bgmac *bgmac)
{
struct fixed_phy_status fphy_status = {
.link = 1,
@@ -1437,24 +1438,7 @@ static int bgmac_phy_connect_direct(struct bgmac *bgmac)
return err;
}
-
-static int bgmac_phy_connect(struct bgmac *bgmac)
-{
- struct phy_device *phy_dev;
- char bus_id[MII_BUS_ID_SIZE + 3];
-
- /* Connect to the PHY */
- snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
- bgmac->phyaddr);
- phy_dev = phy_connect(bgmac->net_dev, bus_id, &bgmac_adjust_link,
- PHY_INTERFACE_MODE_MII);
- if (IS_ERR(phy_dev)) {
- dev_err(bgmac->dev, "PHY connection failed\n");
- return PTR_ERR(phy_dev);
- }
-
- return 0;
-}
+EXPORT_SYMBOL_GPL(bgmac_phy_connect_direct);
int bgmac_enet_probe(struct bgmac *info)
{
@@ -1507,10 +1491,7 @@ int bgmac_enet_probe(struct bgmac *info)
netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT);
- if (!bgmac->mii_bus)
- err = bgmac_phy_connect_direct(bgmac);
- else
- err = bgmac_phy_connect(bgmac);
+ err = bgmac_phy_connect(bgmac);
if (err) {
dev_err(bgmac->dev, "Cannot connect to phy\n");
goto err_dma_free;
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
index 80836b4..bfd9f40 100644
--- a/drivers/net/ethernet/broadcom/bgmac.h
+++ b/drivers/net/ethernet/broadcom/bgmac.h
@@ -513,10 +513,13 @@ struct bgmac {
u32 (*get_bus_clock)(struct bgmac *bgmac);
void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
u32 set);
+ int (*phy_connect)(struct bgmac *bgmac);
};
int bgmac_enet_probe(struct bgmac *info);
void bgmac_enet_remove(struct bgmac *bgmac);
+void bgmac_adjust_link(struct net_device *net_dev);
+int bgmac_phy_connect_direct(struct bgmac *bgmac);
struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr);
void bcma_mdio_mii_unregister(struct mii_bus *mii_bus);
@@ -583,4 +586,9 @@ static inline void bgmac_set(struct bgmac *bgmac, u16 offset, u32 set)
{
bgmac_maskset(bgmac, offset, ~0, set);
}
+
+static inline int bgmac_phy_connect(struct bgmac *bgmac)
+{
+ return bgmac->phy_connect(bgmac);
+}
#endif /* _BGMAC_H */
--
2.7.4
^ permalink raw reply related
* [PATCH v6 4/7] Documentation: devicetree: net: add NS2 bindings to amac
From: Jon Mason @ 2016-11-04 5:10 UTC (permalink / raw)
To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
Cc: devicetree, netdev, linux-kernel, bcm-kernel-feedback-list, rafal,
linux-arm-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>
Clean-up the documentation to the bgmac-amac driver, per suggestion by
Rob Herring, and add details for NS2 support.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
Documentation/devicetree/bindings/net/brcm,amac.txt | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt
index ba5ecc1..2fefa1a 100644
--- a/Documentation/devicetree/bindings/net/brcm,amac.txt
+++ b/Documentation/devicetree/bindings/net/brcm,amac.txt
@@ -2,11 +2,17 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings
-------------------------------------------------------------
Required properties:
- - compatible: "brcm,amac" or "brcm,nsp-amac"
- - reg: Address and length of the GMAC registers,
- Address and length of the GMAC IDM registers
- - reg-names: Names of the registers. Must have both "amac_base" and
- "idm_base"
+ - compatible: "brcm,amac"
+ "brcm,nsp-amac"
+ "brcm,ns2-amac"
+ - reg: Address and length of the register set for the device. It
+ contains the information of registers in the same order as
+ described by reg-names
+ - reg-names: Names of the registers.
+ "amac_base": Address and length of the GMAC registers
+ "idm_base": Address and length of the GMAC IDM registers
+ "nicpm_base": Address and length of the NIC Port Manager
+ registers (required for Northstar2)
- interrupts: Interrupt number
Optional properties:
--
2.7.4
^ permalink raw reply related
* [PATCH v6 3/7] net: phy: broadcom: Add BCM54810 PHY entry
From: Jon Mason @ 2016-11-04 5:10 UTC (permalink / raw)
To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
Cc: devicetree, netdev, linux-kernel, bcm-kernel-feedback-list, rafal,
linux-arm-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>
The BCM54810 PHY requires some semi-unique configuration, which results
in some additional configuration in addition to the standard config.
Also, some users of the BCM54810 require the PHY lanes to be swapped.
Since there is no way to detect this, add a device tree query to see if
it is applicable.
Inspired-by: Vikas Soni <vsoni@broadcom.com>
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/phy/Kconfig | 2 +-
drivers/net/phy/broadcom.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
include/linux/brcmphy.h | 9 +++++++
3 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index ff31c10..d3fcfd2 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -217,7 +217,7 @@ config BROADCOM_PHY
select BCM_NET_PHYLIB
---help---
Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464,
- BCM5481 and BCM5482 PHYs.
+ BCM5481, BCM54810 and BCM5482 PHYs.
config CICADA_PHY
tristate "Cicada PHYs"
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 3a64b3d..b1e32e9 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -18,7 +18,7 @@
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/brcmphy.h>
-
+#include <linux/of.h>
#define BRCM_PHY_MODEL(phydev) \
((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
@@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
}
+static int bcm54810_config(struct phy_device *phydev)
+{
+ int rc, val;
+
+ val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
+ val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
+ rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
+ val);
+ if (rc < 0)
+ return rc;
+
+ val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
+ val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
+ val |= MII_BCM54XX_AUXCTL_MISC_WREN;
+ rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
+ val);
+ if (rc < 0)
+ return rc;
+
+ val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
+ val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
+ rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
/* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
static int bcm50610_a0_workaround(struct phy_device *phydev)
{
@@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev)
(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
bcm54xx_adjust_rxrefclk(phydev);
+ if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
+ err = bcm54810_config(phydev);
+ if (err)
+ return err;
+ }
+
bcm54xx_phydsp_config(phydev);
return 0;
@@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev)
static int bcm5481_config_aneg(struct phy_device *phydev)
{
+ struct device_node *np = phydev->mdio.dev.of_node;
int ret;
/* Aneg firsly. */
@@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
phy_write(phydev, 0x18, reg);
}
+ if (of_property_read_bool(np, "enet-phy-lane-swap")) {
+ /* Lane Swap - Undocumented register...magic! */
+ ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
+ 0x11B);
+ if (ret < 0)
+ return ret;
+ }
+
return ret;
}
@@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = {
.ack_interrupt = bcm_phy_ack_intr,
.config_intr = bcm_phy_config_intr,
}, {
+ .phy_id = PHY_ID_BCM54810,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Broadcom BCM54810",
+ .features = PHY_GBIT_FEATURES |
+ SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+ .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+ .config_init = bcm54xx_config_init,
+ .config_aneg = bcm5481_config_aneg,
+ .read_status = genphy_read_status,
+ .ack_interrupt = bcm_phy_ack_intr,
+ .config_intr = bcm_phy_config_intr,
+}, {
.phy_id = PHY_ID_BCM5482,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5482",
@@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
{ PHY_ID_BCM54616S, 0xfffffff0 },
{ PHY_ID_BCM5464, 0xfffffff0 },
{ PHY_ID_BCM5481, 0xfffffff0 },
+ { PHY_ID_BCM54810, 0xfffffff0 },
{ PHY_ID_BCM5482, 0xfffffff0 },
{ PHY_ID_BCM50610, 0xfffffff0 },
{ PHY_ID_BCM50610M, 0xfffffff0 },
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 0ed6691..848dc50 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -13,6 +13,7 @@
#define PHY_ID_BCM5241 0x0143bc30
#define PHY_ID_BCMAC131 0x0143bc70
#define PHY_ID_BCM5481 0x0143bca0
+#define PHY_ID_BCM54810 0x03625d00
#define PHY_ID_BCM5482 0x0143bcb0
#define PHY_ID_BCM5411 0x00206070
#define PHY_ID_BCM5421 0x002060e0
@@ -56,6 +57,7 @@
#define PHY_BRCM_EXT_IBND_TX_ENABLE 0x00002000
#define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000
#define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000
+
/* Broadcom BCM7xxx specific workarounds */
#define PHY_BRCM_7XXX_REV(x) (((x) >> 8) & 0xff)
#define PHY_BRCM_7XXX_PATCH(x) ((x) & 0xff)
@@ -111,6 +113,7 @@
#define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000
#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007
#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
+#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN (1 << 8)
#define MII_BCM54XX_AUXCTL_SHDWSEL_MASK 0x0007
@@ -192,6 +195,12 @@
#define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */
#define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */
+/* BCM54810 Registers */
+#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL (MII_BCM54XX_EXP_SEL_ER + 0x90)
+#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN (1 << 0)
+#define BCM54810_SHD_CLK_CTL 0x3
+#define BCM54810_SHD_CLK_CTL_GTXCLK_EN (1 << 9)
+
/*****************************************************************************/
/* Fast Ethernet Transceiver definitions. */
--
2.7.4
^ permalink raw reply related
* [PATCH v6 2/7] Documentation: devicetree: add PHY lane swap binding
From: Jon Mason @ 2016-11-04 5:10 UTC (permalink / raw)
To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
Cc: devicetree, netdev, linux-kernel, bcm-kernel-feedback-list, rafal,
linux-arm-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>
Add the documentation for PHY lane swapping. This is a boolean entry to
notify the phy device drivers that the TX/RX lanes need to be swapped.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
Documentation/devicetree/bindings/net/phy.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt
index bc1c3c8..4627da3 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -35,6 +35,10 @@ Optional Properties:
- broken-turn-around: If set, indicates the PHY device does not correctly
release the turn around line low at the end of a MDIO transaction.
+- enet-phy-lane-swap: If set, indicates the PHY will swap the TX/RX lanes to
+ compensate for the board being designed with the lanes swapped.
+
+
Example:
ethernet-phy@0 {
--
2.7.4
^ permalink raw reply related
* [PATCH v6 1/7] net: phy: broadcom: add bcm54xx_auxctl_read
From: Jon Mason @ 2016-11-04 5:10 UTC (permalink / raw)
To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>
Add a helper function to read the AUXCTL register for the BCM54xx. This
mirrors the bcm54xx_auxctl_write function already present in the code.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/broadcom.c | 10 ++++++++++
include/linux/brcmphy.h | 1 +
2 files changed, 11 insertions(+)
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 583ef8a..3a64b3d 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver");
MODULE_AUTHOR("Maciej W. Rozycki");
MODULE_LICENSE("GPL");
+static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
+{
+ /* The register must be written to both the Shadow Register Select and
+ * the Shadow Read Register Selector
+ */
+ phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum |
+ regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT);
+ return phy_read(phydev, MII_BCM54XX_AUX_CTL);
+}
+
static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
{
return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 60def78..0ed6691 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -110,6 +110,7 @@
#define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX 0x0200
#define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000
#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007
+#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
#define MII_BCM54XX_AUXCTL_SHDWSEL_MASK 0x0007
--
2.7.4
^ permalink raw reply related
* [PATCH v6 0/7] add NS2 support to bgmac
From: Jon Mason @ 2016-11-04 5:10 UTC (permalink / raw)
To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
Cc: rafal-g1n6cQUeyibVItvQsEIGlw,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Changes in v6:
* Use a common bgmac_phy_connect_direct (per Rafal Milecki)
* Rebased on latest net-next
* Added Reviewed-by to the relevant patches
Changes in v5:
* Change a pr_err to netdev_err (per Scott Branden)
* Reword the lane swap binding documentation (per Andrew Lunn)
Changes in v4:
* Actually send out the lane swap binding doc patch (Per Scott Branden)
* Remove unused #define (Per Andrew Lunn)
Changes in v3:
* Clean-up the bgmac DT binding doc (per Rob Herring)
* Document the lane swap binding and make it generic (Per Andrew Lunn)
Changes in v2:
* Remove the PHY power-on (per Andrew Lunn)
* Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn)
This results on none of the original PHY code from Vikas being
present. So, I'm removing him as an author and giving him
"Inspired-by" credit.
* Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian
Fainelli)
* Remove bgmac sleep (per Florian Fainelli)
* Re-add bgmac chip reset (per Florian Fainelli and Ray Jui)
* Rebased on latest net-next
* Added patch for bcm54xx_auxctl_read, which is used in the BCM54810
Jon Mason (7):
net: phy: broadcom: add bcm54xx_auxctl_read
Documentation: devicetree: add PHY lane swap binding
net: phy: broadcom: Add BCM54810 PHY entry
Documentation: devicetree: net: add NS2 bindings to amac
net: ethernet: bgmac: device tree phy enablement
net: ethernet: bgmac: add NS2 support
arm64: dts: NS2: add AMAC ethernet support
.../devicetree/bindings/net/brcm,amac.txt | 16 +++--
Documentation/devicetree/bindings/net/phy.txt | 4 ++
arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 ++
arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 ++++
drivers/net/ethernet/broadcom/bgmac-bcma.c | 22 +++++++
drivers/net/ethernet/broadcom/bgmac-platform.c | 74 +++++++++++++++++++++-
drivers/net/ethernet/broadcom/bgmac.c | 32 +++-------
drivers/net/ethernet/broadcom/bgmac.h | 9 +++
drivers/net/phy/Kconfig | 2 +-
drivers/net/phy/broadcom.c | 68 +++++++++++++++++++-
include/linux/brcmphy.h | 10 +++
11 files changed, 222 insertions(+), 32 deletions(-)
--
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
* 回覆: [PATCH v2 2/3] irqchip: mtk-cirq: Add mediatek mtk-cirq implement
From: Chieh-Jay Liu (劉志傑) @ 2016-11-04 5:07 UTC (permalink / raw)
To: Youlin Pei (裴友林), Marc Zyngier
Cc: Rob Herring, Matthias Brugger, Thomas Gleixner, Jason Cooper,
Mark Rutland, Russell King, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org, srv_heupstream,
Hongkun Cao (曹洪坤),
Yong Wu (吴勇), Erin Lo (羅雅齡),
Mars Cheng (鄭森友)
In-Reply-To: <1478234577.7975.29.camel@mtksdaap41>
[-- Attachment #1.1: Type: text/html, Size: 23432 bytes --]
[-- Attachment #1.2: Type: text/plain, Size: 12748 bytes --]
+mars cheng
-----原始郵件-----
寄件者: Youlin Pei [mailto:youlin.pei@mediatek.com]
寄件日期: Friday, November 04, 2016 12:43 PM
收件者: Marc Zyngier
副本: Rob Herring; Matthias Brugger; Thomas Gleixner; Jason Cooper; Mark
Rutland; Russell King; linux-kernel@vger.kernel.org;
devicetree@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
linux-mediatek@lists.infradead.org; srv_heupstream; Hongkun Cao
(曹洪坤); Yong Wu (吴勇); Erin Lo (羅雅齡); Chieh-Jay Liu
(劉志傑)
主旨: Re: [PATCH v2 2/3] irqchip: mtk-cirq: Add mediatek mtk-cirq
implement
On Tue, 2016-11-01 at 20:49 +0000, Marc Zyngier wrote:
> On Tue, Nov 01 2016 at 11:52:01 AM, Youlin Pei <youlin.pei@mediatek.com>
wrote:
> > In Mediatek SOCs, the CIRQ is a low power interrupt controller
> > designed to works outside MCUSYS which comprises with Cortex-Ax
> > cores,CCI and GIC.
> >
> > The CIRQ controller is integrated in between MCUSYS( include
> > Cortex-Ax, CCI and GIC ) and interrupt sources as the second level
> > interrupt controller. The external interrupts which outside MCUSYS
> > will feed through CIRQ then bypass to GIC. CIRQ can monitors all
> > edge trigger interupts. When an edge interrupt is triggered, CIRQ
> > can record the status and generate a pulse signal to GIC when flush
> > command executed.
> >
> > When system enters sleep mode, MCUSYS will be turned off to improve
> > power consumption, also GIC is power down. The edge trigger
> > interrupts will be lost in this scenario without CIRQ.
> >
> > This commit provides the CIRQ irqchip implement.
> >
> > Signed-off-by: Youlin Pei <youlin.pei@mediatek.com>
> > ---
> > drivers/irqchip/Makefile | 2 +-
> > drivers/irqchip/irq-mtk-cirq.c | 262
> > ++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 263 insertions(+), 1 deletion(-) create mode
> > 100644 drivers/irqchip/irq-mtk-cirq.c
> >
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index e4dbfc8..8f33580 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -60,7 +60,7 @@ obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o
> > obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
> > obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o
> > obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o
> > -obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o irq-mtk-cirq.o
> > obj-$(CONFIG_ARCH_DIGICOLOR) += irq-digicolor.o
> > obj-$(CONFIG_RENESAS_H8300H_INTC) += irq-renesas-h8300h.o
> > obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o
> > diff --git a/drivers/irqchip/irq-mtk-cirq.c
> > b/drivers/irqchip/irq-mtk-cirq.c new file mode 100644 index
> > 0000000..fc43ef3
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-mtk-cirq.c
> > @@ -0,0 +1,262 @@
> > +/*
> > + * Copyright (c) 2016 MediaTek Inc.
> > + * Author: Youlin.Pei <youlin.pei@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or
> > +modify
> > + * it under the terms of the GNU General Public License version 2
> > +as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/irq.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +#include <linux/io.h>
> > +#include <linux/slab.h>
> > +#include <linux/syscore_ops.h>
> > +
> > +#define CIRQ_ACK 0x40
> > +#define CIRQ_MASK_SET 0xc0
> > +#define CIRQ_MASK_CLR 0x100
> > +#define CIRQ_SENS_SET 0x180
> > +#define CIRQ_SENS_CLR 0x1c0
> > +#define CIRQ_POL_SET 0x240
> > +#define CIRQ_POL_CLR 0x280
> > +#define CIRQ_CONTROL 0x300
> > +
> > +#define CIRQ_EN 0x1
> > +#define CIRQ_EDGE 0x2
> > +#define CIRQ_FLUSH 0x4
> > +
> > +#define CIRQ_IRQ_NUM 0x200
> > +
> > +struct mtk_cirq_chip_data {
> > + void __iomem *base;
> > + unsigned int ext_irq_start;
> > +};
> > +
> > +static struct mtk_cirq_chip_data *cirq_data;
>
> Are you guaranteed that you'll only ever have a single CIRQ in any
> system?
In Mediatek's SOC, only hace a single CIRQ.
>
> > +
> > +static void mtk_cirq_write_mask(struct irq_data *data, unsigned int
> > +offset) {
> > + struct mtk_cirq_chip_data *chip_data = data->chip_data;
> > + unsigned int cirq_num = data->hwirq;
> > + u32 mask = 1 << (cirq_num % 32);
> > +
> > + writel(mask, chip_data->base + offset + (cirq_num / 32) * 4);
>
> Why can't you use the relaxed accessors?
It seems that i use wrong function, i will change the writel to
writel_relaxed in next version.
>
> > +}
> > +
> > +static void mtk_cirq_mask(struct irq_data *data) {
> > + mtk_cirq_write_mask(data, CIRQ_MASK_SET);
> > + irq_chip_mask_parent(data);
> > +}
> > +
> > +static void mtk_cirq_unmask(struct irq_data *data) {
> > + mtk_cirq_write_mask(data, CIRQ_MASK_CLR);
> > + irq_chip_unmask_parent(data);
> > +}
> > +
> > +static void mtk_cirq_eoi(struct irq_data *data) {
> > + mtk_cirq_write_mask(data, CIRQ_ACK);
>
> EOI and ACK have very different semantics. What is this write actually
> doing? Also, you're now doing an additional MMIO write on each
> interrupt EOI, doubling its cost. Do you really need to do actually
> signal the HW that we've EOIed an interrupt? I would have hoped that
> you'd be able to put it in "bypass" mode as long as you're not
suspending...
>
When external interrupt happened, CIRQ status register record the status
even CIRQ is not enabled. when execute the flush command, CIRQ will resend
the signals according to the status. So if don't clear the status, CIRQ
will resend the wrong signals. the ACK write operation will clear the
status.
> > + irq_chip_eoi_parent(data);
> > +}
> > +
> > +static int mtk_cirq_set_type(struct irq_data *data, unsigned int
> > +type) {
> > + int ret;
> > +
> > + switch (type & IRQ_TYPE_SENSE_MASK) {
> > + case IRQ_TYPE_EDGE_FALLING:
> > + mtk_cirq_write_mask(data, CIRQ_POL_CLR);
> > + mtk_cirq_write_mask(data, CIRQ_SENS_CLR);
> > + break;
> > + case IRQ_TYPE_EDGE_RISING:
> > + mtk_cirq_write_mask(data, CIRQ_POL_SET);
> > + mtk_cirq_write_mask(data, CIRQ_SENS_CLR);
> > + break;
> > + case IRQ_TYPE_LEVEL_LOW:
> > + mtk_cirq_write_mask(data, CIRQ_POL_CLR);
> > + mtk_cirq_write_mask(data, CIRQ_SENS_SET);
> > + break;
> > + case IRQ_TYPE_LEVEL_HIGH:
> > + mtk_cirq_write_mask(data, CIRQ_POL_SET);
> > + mtk_cirq_write_mask(data, CIRQ_SENS_SET);
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + data = data->parent_data;
> > + ret = data->chip->irq_set_type(data, type);
> > + return ret;
> > +}
> > +
> > +static struct irq_chip mtk_cirq_chip = {
> > + .name = "MT_CIRQ",
> > + .irq_mask = mtk_cirq_mask,
> > + .irq_unmask = mtk_cirq_unmask,
> > + .irq_eoi = mtk_cirq_eoi,
> > + .irq_set_type = mtk_cirq_set_type,
> > + .irq_retrigger = irq_chip_retrigger_hierarchy,
> > +#ifdef CONFIG_SMP
> > + .irq_set_affinity = irq_chip_set_affinity_parent,
> > +#endif
> > +};
> > +
> > +static int mtk_cirq_domain_translate(struct irq_domain *d,
> > + struct irq_fwspec *fwspec,
> > + unsigned long *hwirq,
> > + unsigned int *type)
> > +{
> > + if (is_of_node(fwspec->fwnode)) {
> > + if (fwspec->param_count != 3)
> > + return -EINVAL;
> > +
> > + /* No PPI should point to this domain */
> > + if (fwspec->param[0] != 0)
> > + return -EINVAL;
> > +
> > + /* cirq support irq number check */
> > + if (fwspec->param[1] < cirq_data->ext_irq_start)
> > + return -EINVAL;
> > +
> > + *hwirq = fwspec->param[1] - cirq_data->ext_irq_start;
>
> What if the result is > CIRQ_IRQ_NUM?
will add CIRQ supported irq range in DT, and do range check here in next
version.
>
> > + *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
> > + return 0;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
> > +static int mtk_cirq_domain_alloc(struct irq_domain *domain, unsigned
int virq,
> > + unsigned int nr_irqs, void *arg) {
> > + int i;
> > + irq_hw_number_t hwirq;
> > + struct irq_fwspec *fwspec = arg;
> > + struct irq_fwspec parent_fwspec = *fwspec;
> > +
> > + if (fwspec->param_count != 3)
> > + return -EINVAL;
> > +
> > + /* cirq doesn't support PPI */
> > + if (fwspec->param[0])
> > + return -EINVAL;
> > +
> > + if (fwspec->param[1] < cirq_data->ext_irq_start)
> > + return -EINVAL;
> > +
> > + hwirq = fwspec->param[1] - cirq_data->ext_irq_start;
>
> All this is a pure copy of mtk_cirq_domain_translate(). Please use it.
will fix in next version.
> > + for (i = 0; i < nr_irqs; i++)
> > + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
> > + &mtk_cirq_chip,
> > + domain->host_data);
>
> This is a bit silly. This loop only exists for the benefit of MSI
> support, which we're not dealing with here. So please stick a
>
> if (WARN_ON(nr_irqs != 1))
> return -EINVAL;
>
> and drop the loop.
will fix in next version.
>
> > +
> > + parent_fwspec.fwnode = domain->parent->fwnode;
> > + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
> > + &parent_fwspec);
> > +}
> > +
> > +static const struct irq_domain_ops cirq_domain_ops = {
> > + .translate = mtk_cirq_domain_translate,
> > + .alloc = mtk_cirq_domain_alloc,
> > + .free = irq_domain_free_irqs_common,
> > +};
> > +
> > +#ifdef CONFIG_PM_SLEEP
> > +static int mtk_cirq_suspend(void)
> > +{
> > + u32 value;
> > +
> > + /* set edge_only mode, record edge-triggerd interrupts */
> > + /* enable cirq */
> > + value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > + value |= (CIRQ_EDGE | CIRQ_EN);
> > + writel(value, cirq_data->base + CIRQ_CONTROL);
>
> You're mixing relaxed and non-relaxed accessors. Why?
will change writel to writel_relaxed in next version.
>
> > + return 0;
> > +}
> > +
> > +static void mtk_cirq_resume(void)
> > +{
> > + u32 value;
> > +
> > + /* flush recored interrupts, will send signals to parent controller */
> > + value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > + writel(value | CIRQ_FLUSH, cirq_data->base + CIRQ_CONTROL);
>
> Same remark.
will change writel to writel_relaxed in next version.
>
> > +
> > + /* disable cirq */
> > + value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > + value &= ~(CIRQ_EDGE | CIRQ_EN);
> > + writel(value, cirq_data->base + CIRQ_CONTROL);
>
> So from this, I infer that CIRQ is not enabled when the kernel is
> running (not suspended). It really makes me wonder why you need to do
> anything in the EOI callback.
>
> > +}
> > +
> > +static struct syscore_ops mtk_cirq_syscore_ops = {
> > + .suspend = mtk_cirq_suspend,
> > + .resume = mtk_cirq_resume,
> > +};
> > +
> > +static void mtk_cirq_syscore_init(void) {
> > + register_syscore_ops(&mtk_cirq_syscore_ops);
> > +}
> > +#else
> > +static inline void mtk_cirq_syscore_init(void) {} #endif
> > +
> > +static int __init mtk_cirq_of_init(struct device_node *node,
> > + struct device_node *parent)
> > +{
> > + struct irq_domain *domain, *domain_parent;
> > + int ret;
> > +
> > + domain_parent = irq_find_host(parent);
> > + if (!domain_parent) {
> > + pr_err("mtk_cirq: interrupt-parent not found\n");
> > + return -EINVAL;
> > + }
> > +
> > + cirq_data = kzalloc(sizeof(*cirq_data), GFP_KERNEL);
> > + if (!cirq_data)
> > + return -ENOMEM;
> > +
> > + cirq_data->base = of_iomap(node, 0);
> > + if (!cirq_data->base) {
> > + pr_err("mtk_cirq: unable to map cirq register\n");
> > + ret = -ENXIO;
> > + goto out_free;
> > + }
> > +
> > + ret = of_property_read_u32(node, "mediatek,ext-irq-start",
> > + &cirq_data->ext_irq_start);
> > + if (ret)
> > + goto out_unmap;
> > +
> > + domain = irq_domain_add_hierarchy(domain_parent, 0, CIRQ_IRQ_NUM,
node,
> > + &cirq_domain_ops, cirq_data);
>
> So you support at most 512 interrupts, and yet the GIC supports up to
> 987 SPIs. What happens for interrupt lines that out of the CIRQ range?
> Maybe having an explicit range in DT would be a good thing. That also
> brings back the question of having a single CIRQ in the system...
>
In next version, i will add an explicit CIRQ supported range in DT.
Thanks a lot!
> > + if (!domain) {
> > + ret = -ENOMEM;
> > + goto out_unmap;
> > + }
> > +
> > + mtk_cirq_syscore_init();
> > +
> > + return 0;
> > +
> > +out_unmap:
> > + iounmap(cirq_data->base);
> > +out_free:
> > + kfree(cirq_data);
> > + return ret;
> > +}
> > +
> > +IRQCHIP_DECLARE(mtk_cirq, "mediatek,mtk-cirq", mtk_cirq_of_init);
>
> Thanks,
>
> M.
^ permalink raw reply
* [PATCH v7 3/3] fpga: Add support for Lattice iCE40 FPGAs
From: Joel Holdsworth @ 2016-11-04 5:06 UTC (permalink / raw)
To: atull-yzvPICuk2ABMcg4IHK0kFoH6Mc4MB0Vx,
moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w,
geert-Td1EMuHUCqxL1ZNQvxDV9g, robh-DgEjT+Ai2ygdnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA, marex-mMYRjVVXLP4
Cc: Joel Holdsworth
In-Reply-To: <1478236004-7852-1-git-send-email-joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org>
The Lattice iCE40 is a family of FPGAs with a minimalistic architecture
and very regular structure, designed for low-cost, high-volume consumer
and system applications.
This patch adds support to the FPGA manager for configuring the SRAM of
iCE40LM, iCE40LP, iCE40HX, iCE40 Ultra, iCE40 UltraLite and iCE40
UltraPlus devices, through slave SPI.
The iCE40 family is notable because it is the first FPGA family to have
complete reverse engineered bit-stream documentation for the iCE40LP and
iCE40HX devices. Furthermore, there is now a Free Software Verilog
synthesis tool-chain: the "IceStorm" tool-chain.
This project is the work of Clifford Wolf, who is the maintainer of
Yosys Verilog RTL synthesis framework, and Mathias Lasser, with notable
contributions from "Cotton Seed", the main author of "arachne-pnr"; a
place-and-route tool for iCE40 FPGAs.
Having a Free Software synthesis tool-chain offers interesting
opportunities for embedded devices that are able reconfigure themselves
with open firmware that is generated on the device itself. For example
a mobile device might have an application processor with an iCE40 FPGA
attached, which implements slave devices, or through which the processor
communicates with other devices through the FPGA fabric.
A kernel driver for the iCE40 is useful, because in some cases, the FPGA
may need to be configured before other devices can be accessed.
An example of such a device is the icoBoard; a RaspberryPI HAT which
features an iCE40HX8K with a 1 or 8 MBit SRAM and ports for
Digilent-compatible PMOD modules. A PMOD module may contain a device
with which the kernel communicates, via the FPGA.
---
drivers/fpga/Kconfig | 6 ++
drivers/fpga/Makefile | 1 +
drivers/fpga/ice40-spi.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 205 insertions(+)
create mode 100644 drivers/fpga/ice40-spi.c
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index d614102..85ff429 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -13,6 +13,12 @@ config FPGA
if FPGA
+config FPGA_MGR_ICE40_SPI
+ tristate "Lattice iCE40 SPI"
+ depends on SPI
+ help
+ FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
+
config FPGA_MGR_SOCFPGA
tristate "Altera SOCFPGA FPGA Manager"
depends on ARCH_SOCFPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8d83fc6..adb5811 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -6,5 +6,6 @@
obj-$(CONFIG_FPGA) += fpga-mgr.o
# FPGA Manager Drivers
+obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o
obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o
diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c
new file mode 100644
index 0000000..a977f19
--- /dev/null
+++ b/drivers/fpga/ice40-spi.c
@@ -0,0 +1,198 @@
+/*
+ * FPGA Manager Driver for Lattice iCE40.
+ *
+ * Copyright (c) 2016 Joel Holdsworth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This driver adds support to the FPGA manager for configuring the SRAM of
+ * Lattice iCE40 FPGAs through slave SPI.
+ */
+
+#include <linux/fpga/fpga-mgr.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_gpio.h>
+#include <linux/spi/spi.h>
+
+#define ICE40_SPI_FPGAMGR_RESET_DELAY 1 /* us (>200ns) */
+#define ICE40_SPI_FPGAMGR_HOUSEKEEPING_DELAY 1200 /* us */
+
+#define ICE40_SPI_FPGAMGR_NUM_ACTIVATION_BITS 49 /* bits */
+
+struct ice40_fpga_priv {
+ struct spi_device *dev;
+ struct gpio_desc *reset;
+ struct gpio_desc *cdone;
+};
+
+static enum fpga_mgr_states ice40_fpga_ops_state(struct fpga_manager *mgr)
+{
+ struct ice40_fpga_priv *priv = mgr->priv;
+
+ return gpiod_get_value(priv->cdone) ? FPGA_MGR_STATE_OPERATING :
+ FPGA_MGR_STATE_UNKNOWN;
+}
+
+static int ice40_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
+ const char *buf, size_t count)
+{
+ struct ice40_fpga_priv *priv = mgr->priv;
+ struct spi_device *dev = priv->dev;
+ struct spi_message message;
+ int ret;
+
+ if ((flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ dev_err(&dev->dev,
+ "Partial reconfiguration is not supported\n");
+ return -ENOTSUPP;
+ }
+
+ /* Lock the bus, assert CRESET_B and SS_B and delay >200ns */
+ spi_bus_lock(dev->master);
+
+ gpiod_set_value(priv->reset, 1);
+
+ spi_message_init(&message);
+ spi_message_add_tail(&(struct spi_transfer){.cs_change = 1,
+ .delay_usecs = ICE40_SPI_FPGAMGR_RESET_DELAY}, &message);
+ ret = spi_sync_locked(dev, &message);
+ if (ret) {
+ spi_bus_unlock(dev->master);
+ return ret;
+ }
+
+ /* Come out of reset */
+ gpiod_set_value(priv->reset, 0);
+
+ /* Check CDONE is de-asserted i.e. the FPGA is reset */
+ if (gpiod_get_value(priv->cdone)) {
+ dev_err(&dev->dev, "Device reset failed, CDONE is asserted\n");
+ spi_bus_unlock(dev->master);
+ return -EIO;
+ }
+
+ /* Wait for the housekeeping to complete, and release SS_B */
+ spi_message_init(&message);
+ spi_message_add_tail(&(struct spi_transfer){
+ .delay_usecs = ICE40_SPI_FPGAMGR_HOUSEKEEPING_DELAY}, &message);
+ ret = spi_sync_locked(dev, &message);
+
+ spi_bus_unlock(dev->master);
+
+ return ret;
+}
+
+static int ice40_fpga_ops_write(struct fpga_manager *mgr,
+ const char *buf, size_t count)
+{
+ return spi_write(((struct ice40_fpga_priv *)mgr->priv)->dev,
+ buf, count);
+}
+
+static int ice40_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags)
+{
+ struct ice40_fpga_priv *priv = mgr->priv;
+ struct spi_device *dev = priv->dev;
+
+ /* Check CDONE is asserted */
+ if (!gpiod_get_value(priv->cdone)) {
+ dev_err(&dev->dev,
+ "CDONE was not asserted after firmware transfer\n");
+ return -EIO;
+ }
+
+ /* Send of zero-padding to activate the firmware */
+ return spi_write(dev, NULL, (ICE40_SPI_FPGAMGR_NUM_ACTIVATION_BITS +
+ dev->bits_per_word - 1) / dev->bits_per_word);
+}
+
+static const struct fpga_manager_ops ice40_fpga_ops = {
+ .state = ice40_fpga_ops_state,
+ .write_init = ice40_fpga_ops_write_init,
+ .write = ice40_fpga_ops_write,
+ .write_complete = ice40_fpga_ops_write_complete,
+};
+
+static int ice40_fpga_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct device_node *np = spi->dev.of_node;
+ struct ice40_fpga_priv *priv;
+ int ret;
+
+ if (!np) {
+ dev_err(dev, "No Device Tree entry\n");
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = spi;
+
+ /* Check board setup data. */
+ if (spi->max_speed_hz > 25000000) {
+ dev_err(dev, "Speed is too high\n");
+ return -EINVAL;
+ } else if (spi->mode & SPI_CPHA) {
+ dev_err(dev, "Bad mode\n");
+ return -EINVAL;
+ }
+
+ /* Set up the GPIOs */
+ priv->cdone = devm_gpiod_get(dev, "cdone", GPIOD_IN);
+ if (IS_ERR(priv->cdone)) {
+ dev_err(dev, "Failed to get CDONE GPIO: %ld\n",
+ PTR_ERR(priv->cdone));
+ return ret;
+ }
+
+ priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->reset)) {
+ dev_err(dev, "Failed to get CRESET_B GPIO: %ld\n",
+ PTR_ERR(priv->reset));
+ return ret;
+ }
+
+ /* Register with the FPGA manager */
+ ret = fpga_mgr_register(dev, "Lattice iCE40 FPGA Manager",
+ &ice40_fpga_ops, priv);
+ if (ret) {
+ dev_err(dev, "unable to register FPGA manager");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ice40_fpga_remove(struct spi_device *spi)
+{
+ fpga_mgr_unregister(&spi->dev);
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ice40_fpga_of_match[] = {
+ { .compatible = "lattice,ice40-fpga-mgr", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ice40_fpga_of_match);
+#endif
+
+static struct spi_driver ice40_fpga_driver = {
+ .probe = ice40_fpga_probe,
+ .remove = ice40_fpga_remove,
+ .driver = {
+ .name = "ice40spi",
+ .of_match_table = of_match_ptr(ice40_fpga_of_match),
+ },
+};
+
+module_spi_driver(ice40_fpga_driver);
+
+MODULE_AUTHOR("Joel Holdsworth <joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org>");
+MODULE_DESCRIPTION("Lattice iCE40 FPGA Manager");
+MODULE_LICENSE("GPL v2");
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" 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 v7 2/3] Documentation: Add binding document for Lattice iCE40 FPGA manager
From: Joel Holdsworth @ 2016-11-04 5:06 UTC (permalink / raw)
To: atull-yzvPICuk2ABMcg4IHK0kFoH6Mc4MB0Vx,
moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w,
geert-Td1EMuHUCqxL1ZNQvxDV9g, robh-DgEjT+Ai2ygdnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA, marex-mMYRjVVXLP4
Cc: Joel Holdsworth
In-Reply-To: <1478236004-7852-1-git-send-email-joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org>
---
.../bindings/fpga/lattice-ice40-fpga-mgr.txt | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
diff --git a/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
new file mode 100644
index 0000000..cb64184
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
@@ -0,0 +1,21 @@
+Lattice iCE40 FPGA Manager
+
+Required properties:
+- compatible: Should contain "lattice,ice40-fpga-mgr"
+- reg: SPI chip select
+- spi-max-frequency: Maximum SPI frequency (>=1000000, <=25000000)
+- cdone-gpios: GPIO input connected to CDONE pin
+- reset-gpios: Active-low GPIO output connected to CRESET_B pin. Note
+ that unless the GPIO is held low during startup, the
+ FPGA will enter Master SPI mode and drive SCK with a
+ clock signal, potentially jamming other devices on the
+ bus until the firmware is loaded.
+
+Example:
+ ice40: ice40@0 {
+ compatible = "lattice,ice40-fpga-mgr";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ cdone-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
+ creset_b-gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+ };
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" 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 v7 1/3] of: Add vendor prefix for Lattice Semiconductor
From: Joel Holdsworth @ 2016-11-04 5:06 UTC (permalink / raw)
To: atull-yzvPICuk2ABMcg4IHK0kFoH6Mc4MB0Vx,
moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w,
geert-Td1EMuHUCqxL1ZNQvxDV9g, robh-DgEjT+Ai2ygdnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA, marex-mMYRjVVXLP4
Cc: Joel Holdsworth
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 1992aa9..d64a835 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -146,6 +146,7 @@ kosagi Sutajio Ko-Usagi PTE Ltd.
kyo Kyocera Corporation
lacie LaCie
lantiq Lantiq Semiconductor
+lattice Lattice Semiconductor
lenovo Lenovo Group Ltd.
lg LG Corporation
linux Linux-specific binding
--
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
* Re: [RESEND PATCH v1 05/11] dt-bindings: perf: hisi: Add Devicetree bindings for Hisilicon SoC PMU
From: Anurup M @ 2016-11-04 5:06 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-doc-u79uwXL29TY76Z2rM5mHXA, mark.rutland-5wv7dgnIgG8,
will.deacon-5wv7dgnIgG8, corbet-T1hC0tSOHrs,
catalin.marinas-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
arnd-r2nGTMty4D4, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ,
anurup.m-hv44wF8Li93QT0dZR+AlfA,
zhangshaokun-C8/M+/jPZTeaMJb+Lgu22Q,
tanxiaojun-hv44wF8Li93QT0dZR+AlfA, xuwei5-C8/M+/jPZTeaMJb+Lgu22Q,
sanil.kumar-C8/M+/jPZTeaMJb+Lgu22Q,
john.garry-hv44wF8Li93QT0dZR+AlfA,
gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA,
shiju.jose-hv44wF8Li93QT0dZR+AlfA,
wangkefeng.wang-hv44wF8Li93QT0dZR+AlfA,
guohanjun-hv44wF8Li93QT0dZR+AlfA, shyju.pv-hv44wF8Li93QT0dZR+AlfA,
linuxarm-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <20161103182609.GA11071@kozik-lap>
On Thursday 03 November 2016 11:56 PM, Krzysztof Kozlowski wrote:
> On Thu, Nov 03, 2016 at 01:42:01AM -0400, Anurup M wrote:
>> 1) Device tree bindings for Hisilicon SoC PMU.
>> 2) Add example for Hisilicon L3 cache, MN and DDRC PMU.
> Get rid of this weird indentation in all patches.
Thanks. I shall remove the TAB from the commit message in all patches.
>
>> Signed-off-by: Anurup M <anurup.m-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> Signed-off-by: Shaokun Zhang <zhangshaokun-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
>> ---
>> .../devicetree/bindings/arm/hisilicon/pmu.txt | 127 +++++++++++++++++++++
>> 1 file changed, 127 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>>
>> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>> new file mode 100644
>> index 0000000..e7b35e0
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>> @@ -0,0 +1,127 @@
>> +Hisilicon SoC hip05/06/07 ARMv8 PMU
>> +===================================
>> +
>> +The Hisilicon SoC chips like hip05/06/07 etc. consist of varous independent
>> +system device PMU's such as L3 cache (L3C), Miscellaneous Nodes(MN) and DDR
>> +comtroller. These PMU devices are independent and have hardware logic to
>> +gather statistics and performance information.
>> +
>> +HiSilicon SoC chip is encapsulated by multiple CPU and IO die's. The CPU die
>> +is called as Super CPU cluster (SCCL) which includes 16 cpu-cores. Every SCCL
>> +is further grouped as CPU clusters (CCL) which includes 4 cpu-cores each.
>> +e.g. In the case of hip05/06/07, each SCCL has 1 L3 cache and 1 MN PMU device.
>> +
>> +The Hisilicon SoC PMU DT node bindigs for uncore PMU devices are as below.
>> +For PMU devices like L3 cache. MN etc. which are accessed using the djtag,
>> +the parent node will be the djtag node of the corresponding CPU die(SCCL).
>> +
>> +For uncore PMU devices there are some common required properties as detailed
>> +below.
>> +
>> +Required properties:
>> + - compatible : This field contain two values. The first value is
>> + always "hisilicon" and second value is the Module type as shown
>> + in below examples:
> Over-complicated sentence. Just:
>
> - compatible : One of:
> "hisilicon,hisi-pmu-l3c-v1" for Hisilicon SoC L3C PMU
> device (Version 1)
> ...
> ...
Thanks. Shall refine it in next version.
> BTW, No need of CC-ing me. I am not a maintainer of relevant subsystems.
Sure.
Thanks,
Anurup
> Best regards,
> Krzysztof
--
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 v2 2/3] irqchip: mtk-cirq: Add mediatek mtk-cirq implement
From: Youlin Pei @ 2016-11-04 4:42 UTC (permalink / raw)
To: Marc Zyngier
Cc: Rob Herring, Matthias Brugger, Thomas Gleixner, Jason Cooper,
Mark Rutland, Russell King, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
hongkun.cao-NuS5LvNUpcJWk0Htik3J/w,
yong.wu-NuS5LvNUpcJWk0Htik3J/w, erin.lo-NuS5LvNUpcJWk0Htik3J/w,
chieh-jay.liu-NuS5LvNUpcJWk0Htik3J/w
In-Reply-To: <86twbrj586.fsf-5wv7dgnIgG8@public.gmane.org>
On Tue, 2016-11-01 at 20:49 +0000, Marc Zyngier wrote:
> On Tue, Nov 01 2016 at 11:52:01 AM, Youlin Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org> wrote:
> > In Mediatek SOCs, the CIRQ is a low power interrupt controller
> > designed to works outside MCUSYS which comprises with Cortex-Ax
> > cores,CCI and GIC.
> >
> > The CIRQ controller is integrated in between MCUSYS( include
> > Cortex-Ax, CCI and GIC ) and interrupt sources as the second
> > level interrupt controller. The external interrupts which outside
> > MCUSYS will feed through CIRQ then bypass to GIC. CIRQ can monitors
> > all edge trigger interupts. When an edge interrupt is triggered,
> > CIRQ can record the status and generate a pulse signal to GIC when
> > flush command executed.
> >
> > When system enters sleep mode, MCUSYS will be turned off to improve
> > power consumption, also GIC is power down. The edge trigger interrupts
> > will be lost in this scenario without CIRQ.
> >
> > This commit provides the CIRQ irqchip implement.
> >
> > Signed-off-by: Youlin Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> > drivers/irqchip/Makefile | 2 +-
> > drivers/irqchip/irq-mtk-cirq.c | 262 ++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 263 insertions(+), 1 deletion(-)
> > create mode 100644 drivers/irqchip/irq-mtk-cirq.c
> >
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index e4dbfc8..8f33580 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -60,7 +60,7 @@ obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o
> > obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
> > obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o
> > obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o
> > -obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o
> > +obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o irq-mtk-cirq.o
> > obj-$(CONFIG_ARCH_DIGICOLOR) += irq-digicolor.o
> > obj-$(CONFIG_RENESAS_H8300H_INTC) += irq-renesas-h8300h.o
> > obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o
> > diff --git a/drivers/irqchip/irq-mtk-cirq.c b/drivers/irqchip/irq-mtk-cirq.c
> > new file mode 100644
> > index 0000000..fc43ef3
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-mtk-cirq.c
> > @@ -0,0 +1,262 @@
> > +/*
> > + * Copyright (c) 2016 MediaTek Inc.
> > + * Author: Youlin.Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/irq.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +#include <linux/io.h>
> > +#include <linux/slab.h>
> > +#include <linux/syscore_ops.h>
> > +
> > +#define CIRQ_ACK 0x40
> > +#define CIRQ_MASK_SET 0xc0
> > +#define CIRQ_MASK_CLR 0x100
> > +#define CIRQ_SENS_SET 0x180
> > +#define CIRQ_SENS_CLR 0x1c0
> > +#define CIRQ_POL_SET 0x240
> > +#define CIRQ_POL_CLR 0x280
> > +#define CIRQ_CONTROL 0x300
> > +
> > +#define CIRQ_EN 0x1
> > +#define CIRQ_EDGE 0x2
> > +#define CIRQ_FLUSH 0x4
> > +
> > +#define CIRQ_IRQ_NUM 0x200
> > +
> > +struct mtk_cirq_chip_data {
> > + void __iomem *base;
> > + unsigned int ext_irq_start;
> > +};
> > +
> > +static struct mtk_cirq_chip_data *cirq_data;
>
> Are you guaranteed that you'll only ever have a single CIRQ in any
> system?
In Mediatek's SOC, only hace a single CIRQ.
>
> > +
> > +static void mtk_cirq_write_mask(struct irq_data *data, unsigned int offset)
> > +{
> > + struct mtk_cirq_chip_data *chip_data = data->chip_data;
> > + unsigned int cirq_num = data->hwirq;
> > + u32 mask = 1 << (cirq_num % 32);
> > +
> > + writel(mask, chip_data->base + offset + (cirq_num / 32) * 4);
>
> Why can't you use the relaxed accessors?
It seems that i use wrong function, i will change the writel to
writel_relaxed in next version.
>
> > +}
> > +
> > +static void mtk_cirq_mask(struct irq_data *data)
> > +{
> > + mtk_cirq_write_mask(data, CIRQ_MASK_SET);
> > + irq_chip_mask_parent(data);
> > +}
> > +
> > +static void mtk_cirq_unmask(struct irq_data *data)
> > +{
> > + mtk_cirq_write_mask(data, CIRQ_MASK_CLR);
> > + irq_chip_unmask_parent(data);
> > +}
> > +
> > +static void mtk_cirq_eoi(struct irq_data *data)
> > +{
> > + mtk_cirq_write_mask(data, CIRQ_ACK);
>
> EOI and ACK have very different semantics. What is this write actually
> doing? Also, you're now doing an additional MMIO write on each interrupt
> EOI, doubling its cost. Do you really need to do actually signal the HW
> that we've EOIed an interrupt? I would have hoped that you'd be able to
> put it in "bypass" mode as long as you're not suspending...
>
When external interrupt happened, CIRQ status register record the status
even CIRQ is not enabled. when execute the flush command, CIRQ will
resend the signals according to the status. So if don't clear the
status, CIRQ will resend the wrong signals. the ACK write operation will
clear the status.
> > + irq_chip_eoi_parent(data);
> > +}
> > +
> > +static int mtk_cirq_set_type(struct irq_data *data, unsigned int type)
> > +{
> > + int ret;
> > +
> > + switch (type & IRQ_TYPE_SENSE_MASK) {
> > + case IRQ_TYPE_EDGE_FALLING:
> > + mtk_cirq_write_mask(data, CIRQ_POL_CLR);
> > + mtk_cirq_write_mask(data, CIRQ_SENS_CLR);
> > + break;
> > + case IRQ_TYPE_EDGE_RISING:
> > + mtk_cirq_write_mask(data, CIRQ_POL_SET);
> > + mtk_cirq_write_mask(data, CIRQ_SENS_CLR);
> > + break;
> > + case IRQ_TYPE_LEVEL_LOW:
> > + mtk_cirq_write_mask(data, CIRQ_POL_CLR);
> > + mtk_cirq_write_mask(data, CIRQ_SENS_SET);
> > + break;
> > + case IRQ_TYPE_LEVEL_HIGH:
> > + mtk_cirq_write_mask(data, CIRQ_POL_SET);
> > + mtk_cirq_write_mask(data, CIRQ_SENS_SET);
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + data = data->parent_data;
> > + ret = data->chip->irq_set_type(data, type);
> > + return ret;
> > +}
> > +
> > +static struct irq_chip mtk_cirq_chip = {
> > + .name = "MT_CIRQ",
> > + .irq_mask = mtk_cirq_mask,
> > + .irq_unmask = mtk_cirq_unmask,
> > + .irq_eoi = mtk_cirq_eoi,
> > + .irq_set_type = mtk_cirq_set_type,
> > + .irq_retrigger = irq_chip_retrigger_hierarchy,
> > +#ifdef CONFIG_SMP
> > + .irq_set_affinity = irq_chip_set_affinity_parent,
> > +#endif
> > +};
> > +
> > +static int mtk_cirq_domain_translate(struct irq_domain *d,
> > + struct irq_fwspec *fwspec,
> > + unsigned long *hwirq,
> > + unsigned int *type)
> > +{
> > + if (is_of_node(fwspec->fwnode)) {
> > + if (fwspec->param_count != 3)
> > + return -EINVAL;
> > +
> > + /* No PPI should point to this domain */
> > + if (fwspec->param[0] != 0)
> > + return -EINVAL;
> > +
> > + /* cirq support irq number check */
> > + if (fwspec->param[1] < cirq_data->ext_irq_start)
> > + return -EINVAL;
> > +
> > + *hwirq = fwspec->param[1] - cirq_data->ext_irq_start;
>
> What if the result is > CIRQ_IRQ_NUM?
will add CIRQ supported irq range in DT, and do range check here in next
version.
>
> > + *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
> > + return 0;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
> > +static int mtk_cirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> > + unsigned int nr_irqs, void *arg)
> > +{
> > + int i;
> > + irq_hw_number_t hwirq;
> > + struct irq_fwspec *fwspec = arg;
> > + struct irq_fwspec parent_fwspec = *fwspec;
> > +
> > + if (fwspec->param_count != 3)
> > + return -EINVAL;
> > +
> > + /* cirq doesn't support PPI */
> > + if (fwspec->param[0])
> > + return -EINVAL;
> > +
> > + if (fwspec->param[1] < cirq_data->ext_irq_start)
> > + return -EINVAL;
> > +
> > + hwirq = fwspec->param[1] - cirq_data->ext_irq_start;
>
> All this is a pure copy of mtk_cirq_domain_translate(). Please use it.
will fix in next version.
> > + for (i = 0; i < nr_irqs; i++)
> > + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
> > + &mtk_cirq_chip,
> > + domain->host_data);
>
> This is a bit silly. This loop only exists for the benefit of MSI
> support, which we're not dealing with here. So please stick a
>
> if (WARN_ON(nr_irqs != 1))
> return -EINVAL;
>
> and drop the loop.
will fix in next version.
>
> > +
> > + parent_fwspec.fwnode = domain->parent->fwnode;
> > + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
> > + &parent_fwspec);
> > +}
> > +
> > +static const struct irq_domain_ops cirq_domain_ops = {
> > + .translate = mtk_cirq_domain_translate,
> > + .alloc = mtk_cirq_domain_alloc,
> > + .free = irq_domain_free_irqs_common,
> > +};
> > +
> > +#ifdef CONFIG_PM_SLEEP
> > +static int mtk_cirq_suspend(void)
> > +{
> > + u32 value;
> > +
> > + /* set edge_only mode, record edge-triggerd interrupts */
> > + /* enable cirq */
> > + value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > + value |= (CIRQ_EDGE | CIRQ_EN);
> > + writel(value, cirq_data->base + CIRQ_CONTROL);
>
> You're mixing relaxed and non-relaxed accessors. Why?
will change writel to writel_relaxed in next version.
>
> > + return 0;
> > +}
> > +
> > +static void mtk_cirq_resume(void)
> > +{
> > + u32 value;
> > +
> > + /* flush recored interrupts, will send signals to parent controller */
> > + value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > + writel(value | CIRQ_FLUSH, cirq_data->base + CIRQ_CONTROL);
>
> Same remark.
will change writel to writel_relaxed in next version.
>
> > +
> > + /* disable cirq */
> > + value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > + value &= ~(CIRQ_EDGE | CIRQ_EN);
> > + writel(value, cirq_data->base + CIRQ_CONTROL);
>
> So from this, I infer that CIRQ is not enabled when the kernel is
> running (not suspended). It really makes me wonder why you need to do
> anything in the EOI callback.
>
> > +}
> > +
> > +static struct syscore_ops mtk_cirq_syscore_ops = {
> > + .suspend = mtk_cirq_suspend,
> > + .resume = mtk_cirq_resume,
> > +};
> > +
> > +static void mtk_cirq_syscore_init(void)
> > +{
> > + register_syscore_ops(&mtk_cirq_syscore_ops);
> > +}
> > +#else
> > +static inline void mtk_cirq_syscore_init(void) {}
> > +#endif
> > +
> > +static int __init mtk_cirq_of_init(struct device_node *node,
> > + struct device_node *parent)
> > +{
> > + struct irq_domain *domain, *domain_parent;
> > + int ret;
> > +
> > + domain_parent = irq_find_host(parent);
> > + if (!domain_parent) {
> > + pr_err("mtk_cirq: interrupt-parent not found\n");
> > + return -EINVAL;
> > + }
> > +
> > + cirq_data = kzalloc(sizeof(*cirq_data), GFP_KERNEL);
> > + if (!cirq_data)
> > + return -ENOMEM;
> > +
> > + cirq_data->base = of_iomap(node, 0);
> > + if (!cirq_data->base) {
> > + pr_err("mtk_cirq: unable to map cirq register\n");
> > + ret = -ENXIO;
> > + goto out_free;
> > + }
> > +
> > + ret = of_property_read_u32(node, "mediatek,ext-irq-start",
> > + &cirq_data->ext_irq_start);
> > + if (ret)
> > + goto out_unmap;
> > +
> > + domain = irq_domain_add_hierarchy(domain_parent, 0, CIRQ_IRQ_NUM, node,
> > + &cirq_domain_ops, cirq_data);
>
> So you support at most 512 interrupts, and yet the GIC supports up to
> 987 SPIs. What happens for interrupt lines that out of the CIRQ range?
> Maybe having an explicit range in DT would be a good thing. That also
> brings back the question of having a single CIRQ in the system...
>
In next version, i will add an explicit CIRQ supported range in DT.
Thanks a lot!
> > + if (!domain) {
> > + ret = -ENOMEM;
> > + goto out_unmap;
> > + }
> > +
> > + mtk_cirq_syscore_init();
> > +
> > + return 0;
> > +
> > +out_unmap:
> > + iounmap(cirq_data->base);
> > +out_free:
> > + kfree(cirq_data);
> > + return ret;
> > +}
> > +
> > +IRQCHIP_DECLARE(mtk_cirq, "mediatek,mtk-cirq", mtk_cirq_of_init);
>
> Thanks,
>
> M.
--
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 v3 5/6] Documentation: bindings: add documentation for ir-spi device driver
From: Andi Shyti @ 2016-11-04 4:28 UTC (permalink / raw)
To: Jacek Anaszewski
Cc: Mauro Carvalho Chehab, Sean Young, Rob Herring, Mark Rutland,
Richard Purdie, linux-media, devicetree, linux-leds, linux-kernel
In-Reply-To: <70e31ed5-e1ec-cac3-3c3d-02c75f1418bd@samsung.com>
Hi Jacek,
> > > Only DT bindings of LED class drivers should be placed in
> > > Documentation/devicetree/bindings/leds. Please move it to the
> > > media bindings.
> >
> > that's where I placed it first, but Rob asked me to put it in the
> > LED directory and Cc the LED mailining list.
> >
> > That's the discussion of the version 2:
> >
> > https://lkml.org/lkml/2016/9/12/380
> >
> > Rob, Jacek, could you please agree where I can put the binding?
>
> I'm not sure if this is a good approach. I've noticed also that
> backlight bindings have been moved to leds, whereas they don't look
> similarly.
>
> We have common.txt LED bindings, that all LED class drivers' bindings
> have to follow. Neither backlight bindings nor these ones do that,
> which introduces some mess.
>
> Eventually adding a sub-directory, e.g. remote_control could make it
> somehow logically justified, but still - shouldn't bindings be
> placed in the documentation directory related to the subsystem of the
> driver they are predestined to?
In principle I agree with you, also because I understood that the
led kind of bindings are for those LEDs which main function is to
emit light.
There is no need for a remote control directory, because there is
one already under bindings/media, where all the remote
controllers are placed.
Now this is a matter of interpretation, is this an IR LED used by
the driver as remote controller or is this a remote controller
with just an IR LED?
In any case, I will wait for you and Rob to agree where is best
to place the binding, then I will send a new version.
Thanks,
Andi
^ permalink raw reply
* Re: [PATCH v2] tpm_tis: Allow tpm_tis to be bound using DT
From: Jarkko Sakkinen @ 2016-11-04 4:26 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Mark Rutland, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20161026170437.GB13461-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
On Wed, Oct 26, 2016 at 11:04:37AM -0600, Jason Gunthorpe wrote:
> This provides an open firwmare driver binding for tpm_tis. OF
> is useful on arches where ACPI/PNP is not used.
>
> The tcg,tpm-tis-mmio register map interface is specified by the TCG.
>
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
/Jarkko
> ---
> .../bindings/security/tpm/tpm_tis_mmio.txt | 23 ++++++++++++++++++++++
> drivers/char/tpm/Kconfig | 2 +-
> drivers/char/tpm/tpm_tis.c | 11 +++++++++++
> 3 files changed, 35 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
>
> v2 (from Mark)
> - Change name to tpm-tis-mmio (and fix c&p spi)
> - Include some valid chip names
>
> diff --git a/Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt b/Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
> new file mode 100644
> index 000000000000..f9a853165cd0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
> @@ -0,0 +1,23 @@
> +Trusted Computing Group MMIO Trusted Platform Module
> +
> +The TCG defines multi vendor standard for accessing a TPM chip, this
> +is the standard protocol defined to access the TPM via MMIO. Typically
> +this interface will be implemented over Intel's LPC bus.
> +
> +Refer to the 'TCG PC Client Specific TPM Interface Specification (TIS)' TCG
> +publication for the specification.
> +
> +Required properties:
> +
> +- compatible: should contain a string below for the chip, followed by
> + "tcg,tpm-tis-mmio". Valid chip strings are:
> + * "atmel,at97sc3204"
> +- reg: The location of the MMIO registers, should be at least 0x5000 bytes
> +- interrupt: An optional interrupt indicating command completion.
> +
> +Example:
> +
> + tpm_tis@90000 {
> + compatible = "atmel,at97sc3204", "tcg,tpm-tis-mmio";
> + reg = <0x90000 0x5000>;
> + };
> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> index 9faa0b1e7766..277186d3b668 100644
> --- a/drivers/char/tpm/Kconfig
> +++ b/drivers/char/tpm/Kconfig
> @@ -32,7 +32,7 @@ config TCG_TIS_CORE
>
> config TCG_TIS
> tristate "TPM Interface Specification 1.2 Interface / TPM 2.0 FIFO Interface"
> - depends on X86
> + depends on X86 || OF
> select TCG_TIS_CORE
> ---help---
> If you have a TPM security chip that is compliant with the
> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index eaf5730d79eb..0127af130cb1 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -28,6 +28,8 @@
> #include <linux/wait.h>
> #include <linux/acpi.h>
> #include <linux/freezer.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> #include "tpm.h"
> #include "tpm_tis_core.h"
>
> @@ -354,12 +356,21 @@ static int tpm_tis_plat_remove(struct platform_device *pdev)
> return 0;
> }
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id tis_of_platform_match[] = {
> + {.compatible = "tcg,tpm-tis-mmio"},
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, tis_of_platform_match);
> +#endif
> +
> static struct platform_driver tis_drv = {
> .probe = tpm_tis_plat_probe,
> .remove = tpm_tis_plat_remove,
> .driver = {
> .name = "tpm_tis",
> .pm = &tpm_tis_pm,
> + .of_match_table = of_match_ptr(tis_of_platform_match),
> },
> };
>
> --
> 2.1.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
* Re: [PATCH v2 4/6] pinctrl: aspeed: Read and write bits in LPCHC and GFX controllers
From: Andrew Jeffery @ 2016-11-04 3:59 UTC (permalink / raw)
To: Joel Stanley
Cc: Lee Jones, Linus Walleij, Mark Rutland, Rob Herring, linux-gpio,
linux-arm-kernel, linux-kernel, devicetree
In-Reply-To: <CACPK8Xd1aisN4d2C01NXAYTZ1FW=C4b_hjvHce-RY9ReRq2cDw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 27669 bytes --]
On Fri, 2016-11-04 at 09:54 +1030, Joel Stanley wrote:
> On Thu, Nov 3, 2016 at 1:07 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> >
> > The System Control Unit IP block in the Aspeed SoCs is typically where
> > the pinmux configuration is found, but not always. A number of pins
> > depend on state in one of LPC Host Control (LPCHC) or SoC Display
> > Controller (GFX) IP blocks, so the Aspeed pinmux drivers should have the
> > means to adjust these as necessary.
> >
> > We use syscon to cast a regmap over the GFX and LPCHCR blocks, which is
> > used as an arbitration layer between the relevant driver and the pinctrl
> > subsystem. The regmaps are then exposed to the SoC-specific pinctrl
> > drivers by phandles in the devicetree, and are selected during a mux
> > request by querying a new 'ip' member in struct aspeed_sig_desc.
> >
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> I like this a lot more than the first go. Good work.
>
> Some minor comments below.
>
> >
> > ---
> > Since v1:
> >
> > The change is now proactive: instead of reporting that we need to flip bits in
> > controllers we can't access, the patch provides access via regmaps for the
> > relevant controllers. The implementation also splits out the IP block ID into
> > its own variable rather than packing the value into the upper bits of the reg
> > member of struct aspeed_sig_desc. This drives some churn in the diff, but I've
> > tried to minimise it.
> >
> > .../devicetree/bindings/pinctrl/pinctrl-aspeed.txt | 50 +++++++++++++---
> > drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c | 18 +++---
> > drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 39 ++++++++++---
> > drivers/pinctrl/aspeed/pinctrl-aspeed.c | 66 +++++++++++++---------
> > drivers/pinctrl/aspeed/pinctrl-aspeed.h | 32 ++++++++---
> > 5 files changed, 144 insertions(+), 61 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> > index 2ad18c4ea55c..115b0cce6c1c 100644
> > --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> > @@ -4,12 +4,19 @@ Aspeed Pin Controllers
> > The Aspeed SoCs vary in functionality inside a generation but have a common mux
> > device register layout.
> >
> > -Required properties:
> > -- compatible : Should be any one of the following:
> > - "aspeed,ast2400-pinctrl"
> > - "aspeed,g4-pinctrl"
> > - "aspeed,ast2500-pinctrl"
> > - "aspeed,g5-pinctrl"
> > +Required properties for g4:
> > +- compatible : Should be any one of the following:
> > + "aspeed,ast2400-pinctrl"
> > + "aspeed,g4-pinctrl"
> > +
> > +Required properties for g5:
> > +- compatible : Should be any one of the following:
> > + "aspeed,ast2500-pinctrl"
> > + "aspeed,g5-pinctrl"
> > +
> > +- aspeed,external-nodes: A cell of phandles to external controller nodes:
> > + 0: compatible with "aspeed,ast2500-gfx", "syscon"
> > + 1: compatible with "aspeed,ast2500-lpchc", "syscon"
> >
> > The pin controller node should be a child of a syscon node with the required
> > property:
> > @@ -47,7 +54,7 @@ RGMII1 RGMII2 RMII1 RMII2 SD1 SPI1 SPI1DEBUG SPI1PASSTHRU TIMER4 TIMER5 TIMER6
> > TIMER7 TIMER8 VGABIOSROM
> >
> >
> > -Examples:
> > +g4 Example:
> >
> > syscon: scu@1e6e2000 {
> > compatible = "syscon", "simple-mfd";
> > @@ -63,5 +70,34 @@ syscon: scu@1e6e2000 {
> > };
> > };
> >
> > +g5 Example:
> > +
> > +apb {
> > + gfx: display@1e6e6000 {
> > + compatible = "aspeed,ast2500-gfx", "syscon";
> > + reg = <0x1e6e6000 0x1000>;
> > + };
> > +
> > + lpchc: lpchc@1e7890a0 {
> > + compatible = "aspeed,ast2500-lpchc", "syscon";
> > + reg = <0x1e7890a0 0xc4>;
> > + };
> > +
> > + syscon: scu@1e6e2000 {
> > + compatible = "syscon", "simple-mfd";
> > + reg = <0x1e6e2000 0x1a8>;
> > +
> > + pinctrl: pinctrl {
> > + compatible = "aspeed,g5-pinctrl";
> > + aspeed,external-nodes = <&gfx, &lpchc>;
> > +
> > + pinctrl_i2c3_default: i2c3_default {
> > + function = "I2C3";
> > + groups = "I2C3";
> > + };
> > + };
> > + };
> > +};
> > +
> > Please refer to pinctrl-bindings.txt in this directory for details of the
> > common pinctrl bindings used by client devices.
> > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> > index a21b071ff290..558bd102416c 100644
> > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> > @@ -292,7 +292,7 @@ SSSF_PIN_DECL(U18, GPIOG7, FLWP, SIG_DESC_SET(SCU84, 7));
> > #define UART6_DESC SIG_DESC_SET(SCU90, 7)
> > #define ROM16_DESC SIG_DESC_SET(SCU90, 6)
> > #define FLASH_WIDE SIG_DESC_SET(HW_STRAP1, 4)
> > -#define BOOT_SRC_NOR { HW_STRAP1, GENMASK(1, 0), 0, 0 }
> > +#define BOOT_SRC_NOR { ASPEED_IP_SCU, HW_STRAP1, GENMASK(1, 0), 0, 0 }
> >
> > #define A8 56
> > SIG_EXPR_DECL(ROMD8, ROM16, ROM16_DESC);
> > @@ -418,9 +418,9 @@ FUNC_GROUP_DECL(I2C8, G5, F3);
> > #define U1 88
> > SSSF_PIN_DECL(U1, GPIOL0, NCTS1, SIG_DESC_SET(SCU84, 16));
> >
> > -#define VPI18_DESC { SCU90, GENMASK(5, 4), 1, 0 }
> > -#define VPI24_DESC { SCU90, GENMASK(5, 4), 2, 0 }
> > -#define VPI30_DESC { SCU90, GENMASK(5, 4), 3, 0 }
> > +#define VPI18_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 1, 0 }
> > +#define VPI24_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 2, 0 }
> > +#define VPI30_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 3, 0 }
> >
> > #define T5 89
> > #define T5_DESC SIG_DESC_SET(SCU84, 17)
> > @@ -641,11 +641,11 @@ SSSF_PIN_DECL(Y22, GPIOR2, ROMCS3, SIG_DESC_SET(SCU88, 26));
> > #define U19 139
> > SSSF_PIN_DECL(U19, GPIOR3, ROMCS4, SIG_DESC_SET(SCU88, 27));
> >
> > -#define VPOOFF0_DESC { SCU94, GENMASK(1, 0), 0, 0 }
> > -#define VPO12_DESC { SCU94, GENMASK(1, 0), 1, 0 }
> > -#define VPO24_DESC { SCU94, GENMASK(1, 0), 2, 0 }
> > -#define VPOOFF1_DESC { SCU94, GENMASK(1, 0), 3, 0 }
> > -#define VPO_OFF_12 { SCU94, 0x2, 0, 0 }
> > +#define VPOOFF0_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 0, 0 }
> > +#define VPO12_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 1, 0 }
> > +#define VPO24_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 2, 0 }
> > +#define VPOOFF1_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 3, 0 }
> > +#define VPO_OFF_12 { ASPEED_IP_SCU, SCU94, 0x2, 0, 0 }
> > #define VPO_24_OFF SIG_DESC_SET(SCU94, 1)
> >
> > #define V21 140
> > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> > index 87b46390b695..99c4fa9bf861 100644
> > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> > @@ -10,6 +10,7 @@
> > #include
> > #include
> > #include
> > +#include
> > #include
> > #include
> > #include
> > @@ -26,8 +27,8 @@
> >
> > #define ASPEED_G5_NR_PINS 228
> >
> > -#define COND1 { SCU90, BIT(6), 0, 0 }
> > -#define COND2 { SCU94, GENMASK(1, 0), 0, 0 }
> > +#define COND1 { ASPEED_IP_SCU, SCU90, BIT(6), 0, 0 }
> > +#define COND2 { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 0, 0 }
> >
> > #define B14 0
> > SSSF_PIN_DECL(B14, GPIOA0, MAC1LINK, SIG_DESC_SET(SCU80, 0));
> > @@ -186,9 +187,12 @@ MS_PIN_DECL(C20, GPIOE1, NDCD3, GPIE0OUT);
> >
> > FUNC_GROUP_DECL(GPIE0, B20, C20);
> >
> > -#define SPI1_DESC { HW_STRAP1, GENMASK(13, 12), 1, 0 }
> > -#define SPI1DEBUG_DESC { HW_STRAP1, GENMASK(13, 12), 2, 0 }
> > -#define SPI1PASSTHRU_DESC { HW_STRAP1, GENMASK(13, 12), 3, 0 }
> > +#define SPI1_DESC \
> > + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 1, 0 }
> > +#define SPI1DEBUG_DESC \
> > + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 2, 0 }
> > +#define SPI1PASSTHRU_DESC \
> > + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 3, 0 }
> >
> > #define C18 64
> > SIG_EXPR_DECL(SYSCS, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> > @@ -325,10 +329,11 @@ SS_PIN_DECL(R1, GPIOK7, SDA8);
> >
> > FUNC_GROUP_DECL(I2C8, P2, R1);
> >
> > -#define VPIOFF0_DESC { SCU90, GENMASK(5, 4), 0, 0 }
> > -#define VPIOFF1_DESC { SCU90, GENMASK(5, 4), 1, 0 }
> > -#define VPI24_DESC { SCU90, GENMASK(5, 4), 2, 0 }
> > -#define VPIRSVD_DESC { SCU90, GENMASK(5, 4), 3, 0 }
> > +#define VPIOFF0_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 0, 0 }
> > +#define VPIOFF1_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 1, 0 }
> > +#define VPI24_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 2, 0 }
> > +#define VPIRSVD_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 3, 0 }
> > +
> >
> > #define V2 104
> > #define V2_DESC SIG_DESC_SET(SCU88, 0)
> > @@ -848,10 +853,26 @@ static struct pinctrl_desc aspeed_g5_pinctrl_desc = {
> > static int aspeed_g5_pinctrl_probe(struct platform_device *pdev)
> > {
> > int i;
> > + struct regmap **map;
> > + struct device_node *node;
> >
> > for (i = 0; i < ARRAY_SIZE(aspeed_g5_pins); i++)
> > aspeed_g5_pins[i].number = i;
> >
> > + map = &aspeed_g5_pinctrl_data.maps[ASPEED_IP_GFX];
> > + node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 0);
> > + *map = syscon_node_to_regmap(node);
> I think you can use syscon_regmap_lookup_by_phandle to replace both of
> these lines.
Good call, will do.
>
> >
> > + of_node_put(node);
> > + if (IS_ERR(*map))
> > + return PTR_ERR(*map);
> Do we want to fail, or warn and continue?
We would need to add further checks to defend against null dereferences
if we were to continue. I think the broken devicetree should be fixed.
>
> The sequence is a bit messy. How about:
>
> struct regmap *map;
>
> map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> "aspeed,external-nodes");
> if (IS_ERR(map))
> return PTR_ERR(map);
>
> aspeed_g5_pinctrl_data.maps[ASPEED_IP_GFX] = map;
That looks neater, I will switch.
>
>
> >
> > +
> > + map = &aspeed_g5_pinctrl_data.maps[ASPEED_IP_LPCHC];
> > + node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 1);
> > + *map = syscon_node_to_regmap(node);
> > + of_node_put(node);
> > + if (IS_ERR(*map))
> > + return PTR_ERR(*map);
> > +
> Same comments as above.
Ack.
>
> >
> > return aspeed_pinctrl_probe(pdev, &aspeed_g5_pinctrl_desc,
> > &aspeed_g5_pinctrl_data);
> > }
> > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> > index 49aeba912531..23586aac7a5a 100644
> > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> > @@ -14,6 +14,12 @@
> > #include "../core.h"
> > #include "pinctrl-aspeed.h"
> >
> > +static const char *const aspeed_pinmux_ips[] = {
> > + [ASPEED_IP_SCU] = "SCU",
> > + [ASPEED_IP_GFX] = "GFX",
> > + [ASPEED_IP_LPCHC] = "LHCR",
> We've got both LPCHC and LHCR here. As I said when commenting on the
> regmap bindings, I like LHC(R) better.
>
> >
> > +};
> > +
> > int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
> > {
> > struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
> > @@ -78,7 +84,8 @@ int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
> > static inline void aspeed_sig_desc_print_val(
> > const struct aspeed_sig_desc *desc, bool enable, u32 rv)
> What's a rv? Perhaps "reg" or "value"?
>
> >
> > {
> > - pr_debug("SCU%x[0x%08x]=0x%x, got 0x%x from 0x%08x\n", desc->reg,
> > + pr_debug("Want %s%X[0x%08X]=0x%X, got 0x%X from 0x%08X\n",
> > + aspeed_pinmux_ips[desc->ip], desc->reg,
> > desc->mask, enable ? desc->enable : desc->disable,
> > (rv & desc->mask) >> __ffs(desc->mask), rv);
> > }
> > @@ -88,7 +95,7 @@ static inline void aspeed_sig_desc_print_val(
> > *
> > * @desc: The signal descriptor of interest
> > * @enabled: True to query the enabled state, false to query disabled state
> > - * @regmap: The SCU regmap instance
> > + * @regmap: The IP block's regmap instance
> > *
> > * @return True if the descriptor's bitfield is configured to the state
> > * selected by @enabled, false otherwise
> > @@ -119,7 +126,7 @@ static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
> > *
> > * @expr: An expression controlling the signal for a mux function on a pin
> > * @enabled: True to query the enabled state, false to query disabled state
> > - * @regmap: The SCU regmap instance
> > + * @maps: The list of regmap instances
> > *
> > * @return True if the expression composed by @enabled evaluates true, false
> > * otherwise
> > @@ -136,15 +143,16 @@ static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
> > * either condition as required.
> > */
> > static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr,
> > - bool enabled, struct regmap *map)
> > + bool enabled, struct regmap * const *maps)
> > {
> > int i;
> >
> > for (i = 0; i < expr->ndescs; i++) {
> > const struct aspeed_sig_desc *desc = &expr->descs[i];
> >
> > - if (!aspeed_sig_desc_eval(desc, enabled, map))
> > + if (!aspeed_sig_desc_eval(desc, enabled, maps[desc->ip]))
> > return false;
> > +
> > }
> >
> > return true;
> > @@ -158,12 +166,12 @@ static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr,
> > * configured
> > * @enable: true to enable an function's signal through a pin's signal
> > * expression, false to disable the function's signal
> > - * @map: The SCU's regmap instance for pinmux register access.
> > + * @maps: The list of regmap instances for pinmux register access.
> > *
> > * @return true if the expression is configured as requested, false otherwise
> > */
> > static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> > - bool enable, struct regmap *map)
> > + bool enable, struct regmap * const *maps)
> > {
> > int i;
> >
> > @@ -171,6 +179,7 @@ static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> > bool ret;
> > const struct aspeed_sig_desc *desc = &expr->descs[i];
> > u32 pattern = enable ? desc->enable : desc->disable;
> > + u32 val = (pattern << __ffs(desc->mask));
> >
> > /*
> > * Strap registers are configured in hardware or by early-boot
> > @@ -179,48 +188,49 @@ static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> > * deconfigured and is the reason we re-evaluate after writing
> > * all descriptor bits.
> > */
> > - if (desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2)
> > + if ((desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2) &&
> > + desc->ip == ASPEED_IP_SCU)
> > continue;
> >
> > - ret = regmap_update_bits(map, desc->reg, desc->mask,
> > - pattern << __ffs(desc->mask)) == 0;
> > + ret = regmap_update_bits(maps[desc->ip], desc->reg,
> > + desc->mask, val) == 0;
> >
> > if (!ret)
> > return ret;
> > }
> >
> > - return aspeed_sig_expr_eval(expr, enable, map);
> > + return aspeed_sig_expr_eval(expr, enable, maps);
> > }
> >
> > static bool aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr,
> > - struct regmap *map)
> > + struct regmap * const *maps)
> > {
> > - if (aspeed_sig_expr_eval(expr, true, map))
> > + if (aspeed_sig_expr_eval(expr, true, maps))
> > return true;
> >
> > - return aspeed_sig_expr_set(expr, true, map);
> > + return aspeed_sig_expr_set(expr, true, maps);
> > }
> >
> > static bool aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr,
> > - struct regmap *map)
> > + struct regmap * const *maps)
> > {
> > - if (!aspeed_sig_expr_eval(expr, true, map))
> > + if (!aspeed_sig_expr_eval(expr, true, maps))
> > return true;
> >
> > - return aspeed_sig_expr_set(expr, false, map);
> > + return aspeed_sig_expr_set(expr, false, maps);
> > }
> >
> > /**
> > * Disable a signal on a pin by disabling all provided signal expressions.
> > *
> > * @exprs: The list of signal expressions (from a priority level on a pin)
> > - * @map: The SCU's regmap instance for pinmux register access.
> > + * @maps: The list of regmap instances for pinmux register access.
> > *
> > * @return true if all expressions in the list are successfully disabled, false
> > * otherwise
> > */
> > static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs,
> > - struct regmap *map)
> > + struct regmap * const *maps)
> > {
> > bool disabled = true;
> >
> > @@ -230,7 +240,7 @@ static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs,
> > while (*exprs) {
> > bool ret;
> >
> > - ret = aspeed_sig_expr_disable(*exprs, map);
> > + ret = aspeed_sig_expr_disable(*exprs, maps);
> > disabled = disabled && ret;
> >
> > exprs++;
> > @@ -343,6 +353,8 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> > const struct aspeed_sig_expr **funcs;
> > const struct aspeed_sig_expr ***prios;
> >
> > + pr_debug("Muxing pin %d for %s\n", pin, pfunc->name);
> > +
> > if (!pdesc)
> > return -EINVAL;
> >
> > @@ -358,7 +370,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> > if (expr)
> > break;
> >
> > - if (!aspeed_disable_sig(funcs, pdata->map))
> > + if (!aspeed_disable_sig(funcs, pdata->maps))
> > return -EPERM;
> >
> > prios++;
> > @@ -377,7 +389,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> > return -ENXIO;
> > }
> >
> > - if (!aspeed_sig_expr_enable(expr, pdata->map))
> > + if (!aspeed_sig_expr_enable(expr, pdata->maps))
> > return -EPERM;
> > }
> >
> > @@ -432,7 +444,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
> > if (aspeed_gpio_in_exprs(funcs))
> > break;
> >
> > - if (!aspeed_disable_sig(funcs, pdata->map))
> > + if (!aspeed_disable_sig(funcs, pdata->maps))
> > return -EPERM;
> >
> > prios++;
> > @@ -462,7 +474,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
> > * If GPIO is not the lowest priority signal type, assume there is only
> > * one expression defined to enable the GPIO function
> > */
> > - if (!aspeed_sig_expr_enable(expr, pdata->map))
> > + if (!aspeed_sig_expr_enable(expr, pdata->maps))
> > return -EPERM;
> >
> > return 0;
> > @@ -481,10 +493,10 @@ int aspeed_pinctrl_probe(struct platform_device *pdev,
> > return -ENODEV;
> > }
> >
> > - pdata->map = syscon_node_to_regmap(parent->of_node);
> > - if (IS_ERR(pdata->map)) {
> > + pdata->maps[ASPEED_IP_SCU] = syscon_node_to_regmap(parent->of_node);
> > + if (IS_ERR(pdata->maps[ASPEED_IP_SCU])) {
> > dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
> > - return PTR_ERR(pdata->map);
> > + return PTR_ERR(pdata->maps[ASPEED_IP_SCU]);
> > }
> >
> > pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
> > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.h b/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> > index 3e72ef8c54bf..727728b86c07 100644
> > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> > @@ -232,6 +232,11 @@
> > * group.
> > */
> >
> > +#define ASPEED_IP_SCU 0
> > +#define ASPEED_IP_GFX 1
> > +#define ASPEED_IP_LPCHC 2
> > +#define ASPEED_NR_PINMUX_IPS 3
> > +
> > /*
> > * The "Multi-function Pins Mapping and Control" table in the SoC datasheet
> > * references registers by the device/offset mnemonic. The register macros
> > @@ -261,7 +266,9 @@
> > * A signal descriptor, which describes the register, bits and the
> > * enable/disable values that should be compared or written.
> > *
> > - * @reg: The register offset from base in bytes
> > + * @ip: The IP block identifier, used as an index into the regmap array in
> > + * struct aspeed_pinctrl_data
> > + * @reg: The register offset with respect to the base address of the IP block
> > * @mask: The mask to apply to the register. The lowest set bit of the mask is
> > * used to derive the shift value.
> > * @enable: The value that enables the function. Value should be in the LSBs,
> > @@ -270,6 +277,7 @@
> > * LSBs, not at the position of the mask.
> > */
> > struct aspeed_sig_desc {
> > + unsigned int ip;
> > unsigned int reg;
> > u32 mask;
> > u32 enable;
> > @@ -313,24 +321,30 @@ struct aspeed_pin_desc {
> >
> > /* Macro hell */
> >
> > +#define SIG_DESC_IP_BIT(ip, reg, idx, val) \
> > + { ip, reg, BIT_MASK(idx), val, (((val) + 1) & 1) }
> > +
> > /**
> > - * Short-hand macro for describing a configuration enabled by the state of one
> > - * bit. The disable value is derived.
> > + * Short-hand macro for describing an SCU descriptor enabled by the state of
> > + * one bit. The disable value is derived.
> > *
> > * @reg: The signal's associated register, offset from base
> > * @idx: The signal's bit index in the register
> > * @val: The value (0 or 1) that enables the function
> > */
> > #define SIG_DESC_BIT(reg, idx, val) \
> > - { reg, BIT_MASK(idx), val, (((val) + 1) & 1) }
> > + SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, val)
> > +
> > +#define SIG_DESC_IP_SET(ip, reg, idx) SIG_DESC_IP_BIT(ip, reg, idx, 1)
> >
> > /**
> > - * A further short-hand macro describing a configuration enabled with a set bit.
> > + * A further short-hand macro expanding to an SCU descriptor enabled by a set
> > + * bit.
> > *
> > - * @reg: The configuration's associated register, offset from base
> > - * @idx: The configuration's bit index in the register
> > + * @reg: The register, offset from base
> > + * @idx: The bit index in the register
> > */
> > -#define SIG_DESC_SET(reg, idx) SIG_DESC_BIT(reg, idx, 1)
> > +#define SIG_DESC_SET(reg, idx) SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, 1)
> >
> > #define SIG_DESC_LIST_SYM(sig, func) sig_descs_ ## sig ## _ ## func
> > #define SIG_DESC_LIST_DECL(sig, func, ...) \
> > @@ -500,7 +514,7 @@ struct aspeed_pin_desc {
> > MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(gpio))
> >
> > struct aspeed_pinctrl_data {
> > - struct regmap *map;
> > + struct regmap *maps[ASPEED_NR_PINMUX_IPS];
> >
> > const struct pinctrl_pin_desc *pins;
> > const unsigned int npins;
> > --
> > 2.7.4
> >
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ 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