* Re: [RFC PATCH v12 4/5] PCI / PM: Add support for the PCIe WAKE# signal for OF
From: Andy Shevchenko @ 2017-12-28 8:47 UTC (permalink / raw)
To: Rob Herring, JeffyChen
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Bjorn Helgaas, linux-pm-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
Shawn Lin, Brian Norris, Rafael J. Wysocki, Doug Anderson,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-pci-u79uwXL29TY76Z2rM5mHXA, Frank Rowand
In-Reply-To: <CAL_JsqJssPABjoRM-XAnuN_Xd2-sHoFifJNrRDdk_ruQ0DRw6A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, 2017-12-27 at 09:30 -0600, Rob Herring wrote:
> On Tue, Dec 26, 2017 at 7:32 PM, JeffyChen <jeffy.chen-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
> wrote:
> this new file does something similar to the pci-acpi.c and pci-mid.c..
> pci-acpi.c has similar things to pci/of.c. The naming is just not
> consistent.
> > and i am agree the naming is not clear, maybe we can rename both of
> > those
> > files to something like pci-pm-***.c?
>
> At least pci-acpi.c is more than just PM functions, so that doesn't
> make sense. Given that all the ACPI related functions are in 1 file,
> we should do the same for DT.
> > but i have no idea about pci-mid.c or would it possible to have more
> > platform pm ops in the future...maybe we should add some dependency
> > in the
> > Kconfig?
You may consider pci-mid.c as pci-sfi.c to some extend.
So, in that sense it more looks like pci-of.c would be the name for DT
case.
--
Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Intel Finland Oy
--
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 1/2] nvmem: add driver for JZ4780 efuse
From: Marcin Nowakowski @ 2017-12-28 8:05 UTC (permalink / raw)
To: Mathieu Malaterre
Cc: Zubair.Kakakhel-8NJIiSa5LzA, PrasannaKumar Muralidharan,
Srinivas Kandagatla, Rob Herring, Mark Rutland, Ralf Baechle,
David S. Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
Randy Dunlap, Thomas Gleixner, Paul Cercueil, Linus Walleij,
Harvey Hunt, James Hogan, Krzysztof Kozlowski,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mips-6z/3iImG2C8G8FEW9MqTrA
In-Reply-To: <CA+7wUsxM4Cq-K6ONSO-WzmYYvq8PmT92Jfrf7M-MqY-ntObi-g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Hi Mathieu,
On 28.12.2017 08:26, Mathieu Malaterre wrote:
> Hi Marcin,
>
> On Thu, Dec 28, 2017 at 8:13 AM, Marcin Nowakowski
> <marcin.nowakowski-8NJIiSa5LzA@public.gmane.org <mailto:marcin.nowakowski-8NJIiSa5LzA@public.gmane.org>> wrote:
> > Hi Mathieu, PrasannaKumar,
> >
> > On 27.12.2017 13:27, Mathieu Malaterre wrote:
> >>
> >> From: PrasannaKumar Muralidharan <prasannatsmkumar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
> <mailto:prasannatsmkumar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>>
> >>
> >> This patch brings support for the JZ4780 efuse. Currently it only expose
> >> a read only access to the entire 8K bits efuse memory.
> >>
> >> Tested-by: Mathieu Malaterre <malat-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org
> <mailto:malat-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>>
> >> Signed-off-by: PrasannaKumar Muralidharan
> <prasannatsmkumar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org <mailto:prasannatsmkumar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>>
> >> ---
> >
> >
> >> +
> >> +/* main entry point */
> >> +static int jz4780_efuse_read(void *context, unsigned int offset,
> >> + void *val, size_t bytes)
> >> +{
> >> + static const int nsegments = sizeof(segments) /
> sizeof(*segments);
> >> + struct jz4780_efuse *efuse = context;
> >> + char buf[32];
> >> + char *cur = val;
> >> + int i;
> >> + /* PM recommends read/write each segment separately */
> >> + for (i = 0; i < nsegments; ++i) {
> >> + unsigned int *segment = segments[i];
> >> + unsigned int lpos = segment[0];
> >> + unsigned int buflen = segment[1] / 8;
> >> + unsigned int ncount = buflen / 32;
> >> + unsigned int remain = buflen % 32;
> >> + int j;
> >
> >
> > This doesn't look right, as offset & bytes are completely ignored. This
> > means it will return data from an offset other than requested and may
> also
> > overrun the provided output buffer?
>
>
> Thanks for the review ! That was the part of nvmem framework I was not
> totally clear. Let say I want to expose only a portion of efuse space, eg:
Do you need to expose this to the userspace or to other drivers only?
For the second case have a look at the description of nvmem cell interface.
> diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi
> b/arch/mips/boot/dts/ingenic/jz4780.dtsi
> index 2f26922718559..44d97c06a6d15 100644
> --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi
> +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi
> @@ -299,6 +299,15 @@
> clocks = <&cgu JZ4780_CLK_AHB2>;
> clock-names = "bus_clk";
> +
> +#address-cells = <1>;
> +#size-cells = <1>;
> +
> +eth_mac: eth_mac@12 {
> +/* six byte/48bit MAC address stored as 8-bit integers */
> +reg = <0x12 0x6>;
> +};
> +
> };
> };
> What should I do to expose that chunk only in the user space ?
The nvmem interface's userspace interface (via /sys/.../nvmem) provides
access to the complete device raw memory so the only way to achieve that
would be to parse the devicetree description in your driver and only
register part of the memory with the nvmem driver - but that would be a
slight abuse of the interface.
The nvmem devicetree binding document shows clearly how to define the
cell interface that can later be used by any consumer - that way you
could have the ethernet driver access the cell directly. However, as the
dm9000 driver isn't designed to do that and this is a SoC-specific
extention, I don't know how it fits with the general eth driver design ...
Potentially a good and useful compromise would be to have all of the
cell regs exposed via /sys/.../nvmem-cellname file (or something
similar), but this is not currently supported and I don't know what the
view of nvmem maintainers on adding such extension would be.
> >
> >> + /* EFUSE can read or write maximum 256bit in each
> time */
> >> + for (j = 0; j < ncount ; ++j) {
> >> + jz4780_efuse_read_32bytes(efuse, buf, lpos);
> >> + memcpy(cur, buf, sizeof(buf));
> >> + cur += sizeof(buf);
> >> + lpos += sizeof(buf);
> >> + }
> >> + if (remain) {
> >> + jz4780_efuse_read_32bytes(efuse, buf, lpos);
> >> + memcpy(cur, buf, remain);
> >> + cur += remain;
> >> + }
> >> + }
> >> +
> >> + return 0;
> >> +}
Regardless of the choices above, you still always have to make sure in
your reg_read method that you only read from the offset specified in
method arguments and never return more than 'bytes' of data requested.
Marcin
--
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] arm64: dts: angler: add pstore-ramoops support
From: zhuoweizhang @ 2017-12-28 7:38 UTC (permalink / raw)
Cc: Mark Rutland, devicetree, linux-soc, Tony Luck, Kees Cook,
Catalin Marinas, linux-arm-msm, Anton Vorontsov, jeremymc,
linux-kernel, Will Deacon, David Brown, Rob Herring, Colin Cross,
Andy Gross, Zhuowei Zhang, linux-arm-kernel
From: Zhuowei Zhang <zhuoweizhang@yahoo.com>
Support pstore-ramoops for retrieving kernel oops and panics after reboot.
The address and configs are taken from the downstream kernel's device tree.
Signed-off-by: Zhuowei Zhang <zhuoweizhang@yahoo.com>
---
arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
index dfa08f5..9ce3a6e 100644
--- a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
+++ b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
@@ -37,4 +37,19 @@
pinctrl-1 = <&blsp1_uart2_sleep>;
};
};
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ramoops@1fe00000 {
+ compatible = "ramoops";
+ reg = <0 0x1fe00000 0 0x00200000>;
+ console-size = <0x100000>;
+ record-size = <0x10000>;
+ ftrace-size = <0x10000>;
+ pmsg-size = <0x80000>;
+ };
+ };
};
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 1/2] nvmem: add driver for JZ4780 efuse
From: Mathieu Malaterre @ 2017-12-28 7:26 UTC (permalink / raw)
To: Marcin Nowakowski
Cc: Zubair.Kakakhel, PrasannaKumar Muralidharan, Srinivas Kandagatla,
Rob Herring, Mark Rutland, Ralf Baechle, David S. Miller,
Mauro Carvalho Chehab, Greg Kroah-Hartman, Randy Dunlap,
Thomas Gleixner, Paul Cercueil, Linus Walleij, Harvey Hunt,
James Hogan, Krzysztof Kozlowski, linux-kernel, devicetree,
linux-mips
In-Reply-To: <bbc64846-e12e-aea8-c516-5e03f6253fed@mips.com>
[-- Attachment #1: Type: text/plain, Size: 2878 bytes --]
Hi Marcin,
On Thu, Dec 28, 2017 at 8:13 AM, Marcin Nowakowski <
marcin.nowakowski@mips.com> wrote:
> Hi Mathieu, PrasannaKumar,
>
> On 27.12.2017 13:27, Mathieu Malaterre wrote:
>>
>> From: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>
>>
>> This patch brings support for the JZ4780 efuse. Currently it only expose
>> a read only access to the entire 8K bits efuse memory.
>>
>> Tested-by: Mathieu Malaterre <malat@debian.org>
>> Signed-off-by: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>
>> ---
>
>
>> +
>> +/* main entry point */
>> +static int jz4780_efuse_read(void *context, unsigned int offset,
>> + void *val, size_t bytes)
>> +{
>> + static const int nsegments = sizeof(segments) /
sizeof(*segments);
>> + struct jz4780_efuse *efuse = context;
>> + char buf[32];
>> + char *cur = val;
>> + int i;
>> + /* PM recommends read/write each segment separately */
>> + for (i = 0; i < nsegments; ++i) {
>> + unsigned int *segment = segments[i];
>> + unsigned int lpos = segment[0];
>> + unsigned int buflen = segment[1] / 8;
>> + unsigned int ncount = buflen / 32;
>> + unsigned int remain = buflen % 32;
>> + int j;
>
>
> This doesn't look right, as offset & bytes are completely ignored. This
> means it will return data from an offset other than requested and may also
> overrun the provided output buffer?
Thanks for the review ! That was the part of nvmem framework I was not
totally clear. Let say I want to expose only a portion of efuse space, eg:
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi
b/arch/mips/boot/dts/ingenic/jz4780.dtsi
index 2f26922718559..44d97c06a6d15 100644
--- a/arch/mips/boot/dts/ingenic/jz4780.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi
@@ -299,6 +299,15 @@
clocks = <&cgu JZ4780_CLK_AHB2>;
clock-names = "bus_clk";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eth_mac: eth_mac@12 {
+ /* six byte/48bit MAC address stored as 8-bit integers */
+ reg = <0x12 0x6>;
+ };
+
};
};
What should I do to expose that chunk only in the user space ?
>
>> + /* EFUSE can read or write maximum 256bit in each time */
>> + for (j = 0; j < ncount ; ++j) {
>> + jz4780_efuse_read_32bytes(efuse, buf, lpos);
>> + memcpy(cur, buf, sizeof(buf));
>> + cur += sizeof(buf);
>> + lpos += sizeof(buf);
>> + }
>> + if (remain) {
>> + jz4780_efuse_read_32bytes(efuse, buf, lpos);
>> + memcpy(cur, buf, remain);
>> + cur += remain;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>
>
>
> Marcin
>
-M
[-- Attachment #2: Type: text/html, Size: 4501 bytes --]
^ permalink raw reply related
* Re: [PATCH 1/2] nvmem: add driver for JZ4780 efuse
From: Marcin Nowakowski @ 2017-12-28 7:13 UTC (permalink / raw)
To: Mathieu Malaterre, Zubair.Kakakhel
Cc: PrasannaKumar Muralidharan, Srinivas Kandagatla, Rob Herring,
Mark Rutland, Ralf Baechle, David S. Miller,
Mauro Carvalho Chehab, Greg Kroah-Hartman, Randy Dunlap,
Thomas Gleixner, Paul Cercueil, Linus Walleij, Harvey Hunt,
James Hogan, Krzysztof Kozlowski, linux-kernel, devicetree,
linux-mips
In-Reply-To: <20171227122722.5219-2-malat@debian.org>
Hi Mathieu, PrasannaKumar,
On 27.12.2017 13:27, Mathieu Malaterre wrote:
> From: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>
>
> This patch brings support for the JZ4780 efuse. Currently it only expose
> a read only access to the entire 8K bits efuse memory.
>
> Tested-by: Mathieu Malaterre <malat@debian.org>
> Signed-off-by: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>
> ---
> +
> +/* main entry point */
> +static int jz4780_efuse_read(void *context, unsigned int offset,
> + void *val, size_t bytes)
> +{
> + static const int nsegments = sizeof(segments) / sizeof(*segments);
> + struct jz4780_efuse *efuse = context;
> + char buf[32];
> + char *cur = val;
> + int i;
> + /* PM recommends read/write each segment separately */
> + for (i = 0; i < nsegments; ++i) {
> + unsigned int *segment = segments[i];
> + unsigned int lpos = segment[0];
> + unsigned int buflen = segment[1] / 8;
> + unsigned int ncount = buflen / 32;
> + unsigned int remain = buflen % 32;
> + int j;
This doesn't look right, as offset & bytes are completely ignored. This
means it will return data from an offset other than requested and may
also overrun the provided output buffer?
> + /* EFUSE can read or write maximum 256bit in each time */
> + for (j = 0; j < ncount ; ++j) {
> + jz4780_efuse_read_32bytes(efuse, buf, lpos);
> + memcpy(cur, buf, sizeof(buf));
> + cur += sizeof(buf);
> + lpos += sizeof(buf);
> + }
> + if (remain) {
> + jz4780_efuse_read_32bytes(efuse, buf, lpos);
> + memcpy(cur, buf, remain);
> + cur += remain;
> + }
> + }
> +
> + return 0;
> +}
Marcin
^ permalink raw reply
* [PATCH net-next v9 2/2] net: ethernet: socionext: add AVE ethernet driver
From: Kunihiko Hayashi @ 2017-12-28 6:58 UTC (permalink / raw)
To: David Miller, netdev
Cc: Andrew Lunn, Florian Fainelli, Rob Herring, Mark Rutland,
linux-arm-kernel, linux-kernel, devicetree, Masahiro Yamada,
Masami Hiramatsu, Jassi Brar, Kunihiko Hayashi
In-Reply-To: <1514444292-20643-1-git-send-email-hayashi.kunihiko@socionext.com>
The UniPhier platform from Socionext provides the AVE ethernet
controller that includes MAC and MDIO bus supporting RGMII/RMII
modes. The controller is named AVE.
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/socionext/Kconfig | 22 +
drivers/net/ethernet/socionext/Makefile | 5 +
drivers/net/ethernet/socionext/sni_ave.c | 1736 ++++++++++++++++++++++++++++++
5 files changed, 1765 insertions(+)
create mode 100644 drivers/net/ethernet/socionext/Kconfig
create mode 100644 drivers/net/ethernet/socionext/Makefile
create mode 100644 drivers/net/ethernet/socionext/sni_ave.c
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index c604213..d50519e 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -170,6 +170,7 @@ source "drivers/net/ethernet/sis/Kconfig"
source "drivers/net/ethernet/sfc/Kconfig"
source "drivers/net/ethernet/sgi/Kconfig"
source "drivers/net/ethernet/smsc/Kconfig"
+source "drivers/net/ethernet/socionext/Kconfig"
source "drivers/net/ethernet/stmicro/Kconfig"
source "drivers/net/ethernet/sun/Kconfig"
source "drivers/net/ethernet/tehuti/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 39f62733..6cf5ade 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_SFC) += sfc/
obj-$(CONFIG_SFC_FALCON) += sfc/falcon/
obj-$(CONFIG_NET_VENDOR_SGI) += sgi/
obj-$(CONFIG_NET_VENDOR_SMSC) += smsc/
+obj-$(CONFIG_NET_VENDOR_SOCIONEXT) += socionext/
obj-$(CONFIG_NET_VENDOR_STMICRO) += stmicro/
obj-$(CONFIG_NET_VENDOR_SUN) += sun/
obj-$(CONFIG_NET_VENDOR_TEHUTI) += tehuti/
diff --git a/drivers/net/ethernet/socionext/Kconfig b/drivers/net/ethernet/socionext/Kconfig
new file mode 100644
index 0000000..3a1829e
--- /dev/null
+++ b/drivers/net/ethernet/socionext/Kconfig
@@ -0,0 +1,22 @@
+config NET_VENDOR_SOCIONEXT
+ bool "Socionext ethernet drivers"
+ default y
+ ---help---
+ Option to select ethernet drivers for Socionext platforms.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Socionext devices. If you say Y, you will be asked
+ for your specific card in the following questions.
+
+if NET_VENDOR_SOCIONEXT
+
+config SNI_AVE
+ tristate "Socionext AVE ethernet support"
+ depends on (ARCH_UNIPHIER || COMPILE_TEST) && OF
+ select PHYLIB
+ ---help---
+ Driver for gigabit ethernet MACs, called AVE, in the
+ Socionext UniPhier family.
+
+endif #NET_VENDOR_SOCIONEXT
diff --git a/drivers/net/ethernet/socionext/Makefile b/drivers/net/ethernet/socionext/Makefile
new file mode 100644
index 0000000..ab83df6
--- /dev/null
+++ b/drivers/net/ethernet/socionext/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for all ethernet ip drivers on Socionext platforms
+#
+obj-$(CONFIG_SNI_AVE) += sni_ave.o
diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c
new file mode 100644
index 0000000..111e7ca
--- /dev/null
+++ b/drivers/net/ethernet/socionext/sni_ave.c
@@ -0,0 +1,1736 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * sni_ave.c - Socionext UniPhier AVE ethernet driver
+ * Copyright 2014 Panasonic Corporation
+ * Copyright 2015-2017 Socionext Inc.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/reset.h>
+#include <linux/types.h>
+#include <linux/u64_stats_sync.h>
+
+/* General Register Group */
+#define AVE_IDR 0x000 /* ID */
+#define AVE_VR 0x004 /* Version */
+#define AVE_GRR 0x008 /* Global Reset */
+#define AVE_CFGR 0x00c /* Configuration */
+
+/* Interrupt Register Group */
+#define AVE_GIMR 0x100 /* Global Interrupt Mask */
+#define AVE_GISR 0x104 /* Global Interrupt Status */
+
+/* MAC Register Group */
+#define AVE_TXCR 0x200 /* TX Setup */
+#define AVE_RXCR 0x204 /* RX Setup */
+#define AVE_RXMAC1R 0x208 /* MAC address (lower) */
+#define AVE_RXMAC2R 0x20c /* MAC address (upper) */
+#define AVE_MDIOCTR 0x214 /* MDIO Control */
+#define AVE_MDIOAR 0x218 /* MDIO Address */
+#define AVE_MDIOWDR 0x21c /* MDIO Data */
+#define AVE_MDIOSR 0x220 /* MDIO Status */
+#define AVE_MDIORDR 0x224 /* MDIO Rd Data */
+
+/* Descriptor Control Register Group */
+#define AVE_DESCC 0x300 /* Descriptor Control */
+#define AVE_TXDC 0x304 /* TX Descriptor Configuration */
+#define AVE_RXDC0 0x308 /* RX Descriptor Ring0 Configuration */
+#define AVE_IIRQC 0x34c /* Interval IRQ Control */
+
+/* Packet Filter Register Group */
+#define AVE_PKTF_BASE 0x800 /* PF Base Address */
+#define AVE_PFMBYTE_BASE 0xd00 /* PF Mask Byte Base Address */
+#define AVE_PFMBIT_BASE 0xe00 /* PF Mask Bit Base Address */
+#define AVE_PFSEL_BASE 0xf00 /* PF Selector Base Address */
+#define AVE_PFEN 0xffc /* Packet Filter Enable */
+#define AVE_PKTF(ent) (AVE_PKTF_BASE + (ent) * 0x40)
+#define AVE_PFMBYTE(ent) (AVE_PFMBYTE_BASE + (ent) * 8)
+#define AVE_PFMBIT(ent) (AVE_PFMBIT_BASE + (ent) * 4)
+#define AVE_PFSEL(ent) (AVE_PFSEL_BASE + (ent) * 4)
+
+/* 64bit descriptor memory */
+#define AVE_DESC_SIZE_64 12 /* Descriptor Size */
+
+#define AVE_TXDM_64 0x1000 /* Tx Descriptor Memory */
+#define AVE_RXDM_64 0x1c00 /* Rx Descriptor Memory */
+
+#define AVE_TXDM_SIZE_64 0x0ba0 /* Tx Descriptor Memory Size 3KB */
+#define AVE_RXDM_SIZE_64 0x6000 /* Rx Descriptor Memory Size 24KB */
+
+/* 32bit descriptor memory */
+#define AVE_DESC_SIZE_32 8 /* Descriptor Size */
+
+#define AVE_TXDM_32 0x1000 /* Tx Descriptor Memory */
+#define AVE_RXDM_32 0x1800 /* Rx Descriptor Memory */
+
+#define AVE_TXDM_SIZE_32 0x07c0 /* Tx Descriptor Memory Size 2KB */
+#define AVE_RXDM_SIZE_32 0x4000 /* Rx Descriptor Memory Size 16KB */
+
+/* RMII Bridge Register Group */
+#define AVE_RSTCTRL 0x8028 /* Reset control */
+#define AVE_RSTCTRL_RMIIRST BIT(16)
+#define AVE_LINKSEL 0x8034 /* Link speed setting */
+#define AVE_LINKSEL_100M BIT(0)
+
+/* AVE_GRR */
+#define AVE_GRR_RXFFR BIT(5) /* Reset RxFIFO */
+#define AVE_GRR_PHYRST BIT(4) /* Reset external PHY */
+#define AVE_GRR_GRST BIT(0) /* Reset all MAC */
+
+/* AVE_CFGR */
+#define AVE_CFGR_FLE BIT(31) /* Filter Function */
+#define AVE_CFGR_CHE BIT(30) /* Checksum Function */
+#define AVE_CFGR_MII BIT(27) /* Func mode (1:MII/RMII, 0:RGMII) */
+#define AVE_CFGR_IPFCEN BIT(24) /* IP fragment sum Enable */
+
+/* AVE_GISR (common with GIMR) */
+#define AVE_GI_PHY BIT(24) /* PHY interrupt */
+#define AVE_GI_TX BIT(16) /* Tx complete */
+#define AVE_GI_RXERR BIT(8) /* Receive frame more than max size */
+#define AVE_GI_RXOVF BIT(7) /* Overflow at the RxFIFO */
+#define AVE_GI_RXDROP BIT(6) /* Drop packet */
+#define AVE_GI_RXIINT BIT(5) /* Interval interrupt */
+
+/* AVE_TXCR */
+#define AVE_TXCR_FLOCTR BIT(18) /* Flow control */
+#define AVE_TXCR_TXSPD_1G BIT(17)
+#define AVE_TXCR_TXSPD_100 BIT(16)
+
+/* AVE_RXCR */
+#define AVE_RXCR_RXEN BIT(30) /* Rx enable */
+#define AVE_RXCR_FDUPEN BIT(22) /* Interface mode */
+#define AVE_RXCR_FLOCTR BIT(21) /* Flow control */
+#define AVE_RXCR_AFEN BIT(19) /* MAC address filter */
+#define AVE_RXCR_DRPEN BIT(18) /* Drop pause frame */
+#define AVE_RXCR_MPSIZ_MASK GENMASK(10, 0)
+
+/* AVE_MDIOCTR */
+#define AVE_MDIOCTR_RREQ BIT(3) /* Read request */
+#define AVE_MDIOCTR_WREQ BIT(2) /* Write request */
+
+/* AVE_MDIOSR */
+#define AVE_MDIOSR_STS BIT(0) /* access status */
+
+/* AVE_DESCC */
+#define AVE_DESCC_STATUS_MASK GENMASK(31, 16)
+#define AVE_DESCC_RD0 BIT(8) /* Enable Rx descriptor Ring0 */
+#define AVE_DESCC_RDSTP BIT(4) /* Pause Rx descriptor */
+#define AVE_DESCC_TD BIT(0) /* Enable Tx descriptor */
+
+/* AVE_TXDC */
+#define AVE_TXDC_SIZE GENMASK(27, 16) /* Size of Tx descriptor */
+#define AVE_TXDC_ADDR GENMASK(11, 0) /* Start address */
+#define AVE_TXDC_ADDR_START 0
+
+/* AVE_RXDC0 */
+#define AVE_RXDC0_SIZE GENMASK(30, 16) /* Size of Rx descriptor */
+#define AVE_RXDC0_ADDR GENMASK(14, 0) /* Start address */
+#define AVE_RXDC0_ADDR_START 0
+
+/* AVE_IIRQC */
+#define AVE_IIRQC_EN0 BIT(27) /* Enable interval interrupt Ring0 */
+#define AVE_IIRQC_BSCK GENMASK(15, 0) /* Interval count unit */
+
+/* Command status for descriptor */
+#define AVE_STS_OWN BIT(31) /* Descriptor ownership */
+#define AVE_STS_INTR BIT(29) /* Request for interrupt */
+#define AVE_STS_OK BIT(27) /* Normal transmit */
+/* TX */
+#define AVE_STS_NOCSUM BIT(28) /* No use HW checksum */
+#define AVE_STS_1ST BIT(26) /* Head of buffer chain */
+#define AVE_STS_LAST BIT(25) /* Tail of buffer chain */
+#define AVE_STS_OWC BIT(21) /* Out of window,Late Collision */
+#define AVE_STS_EC BIT(20) /* Excess collision occurred */
+#define AVE_STS_PKTLEN_TX_MASK GENMASK(15, 0)
+/* RX */
+#define AVE_STS_CSSV BIT(21) /* Checksum check performed */
+#define AVE_STS_CSER BIT(20) /* Checksum error detected */
+#define AVE_STS_PKTLEN_RX_MASK GENMASK(10, 0)
+
+/* Packet filter */
+#define AVE_PFMBYTE_MASK0 (GENMASK(31, 8) | GENMASK(5, 0))
+#define AVE_PFMBYTE_MASK1 GENMASK(25, 0)
+#define AVE_PFMBIT_MASK GENMASK(15, 0)
+
+#define AVE_PF_SIZE 17 /* Number of all packet filter */
+#define AVE_PF_MULTICAST_SIZE 7 /* Number of multicast filter */
+
+#define AVE_PFNUM_FILTER 0 /* No.0 */
+#define AVE_PFNUM_UNICAST 1 /* No.1 */
+#define AVE_PFNUM_BROADCAST 2 /* No.2 */
+#define AVE_PFNUM_MULTICAST 11 /* No.11-17 */
+
+/* NETIF Message control */
+#define AVE_DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | \
+ NETIF_MSG_PROBE | \
+ NETIF_MSG_LINK | \
+ NETIF_MSG_TIMER | \
+ NETIF_MSG_IFDOWN | \
+ NETIF_MSG_IFUP | \
+ NETIF_MSG_RX_ERR | \
+ NETIF_MSG_TX_ERR)
+
+/* Parameter for descriptor */
+#define AVE_NR_TXDESC 32 /* Tx descriptor */
+#define AVE_NR_RXDESC 64 /* Rx descriptor */
+
+#define AVE_DESC_OFS_CMDSTS 0
+#define AVE_DESC_OFS_ADDRL 4
+#define AVE_DESC_OFS_ADDRU 8
+
+/* Parameter for ethernet frame */
+#define AVE_MAX_ETHFRAME 1518
+
+/* Parameter for interrupt */
+#define AVE_INTM_COUNT 20
+#define AVE_FORCE_TXINTCNT 1
+
+#define IS_DESC_64BIT(p) ((p)->data->is_desc_64bit)
+
+enum desc_id {
+ AVE_DESCID_RX,
+ AVE_DESCID_TX,
+};
+
+enum desc_state {
+ AVE_DESC_RX_PERMIT,
+ AVE_DESC_RX_SUSPEND,
+ AVE_DESC_START,
+ AVE_DESC_STOP,
+};
+
+struct ave_desc {
+ struct sk_buff *skbs;
+ dma_addr_t skbs_dma;
+ size_t skbs_dmalen;
+};
+
+struct ave_desc_info {
+ u32 ndesc; /* number of descriptor */
+ u32 daddr; /* start address of descriptor */
+ u32 proc_idx; /* index of processing packet */
+ u32 done_idx; /* index of processed packet */
+ struct ave_desc *desc; /* skb info related descriptor */
+};
+
+struct ave_soc_data {
+ bool is_desc_64bit;
+};
+
+struct ave_stats {
+ struct u64_stats_sync syncp;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 dropped;
+ u64 collisions;
+ u64 fifo_errors;
+};
+
+struct ave_private {
+ void __iomem *base;
+ int irq;
+ int phy_id;
+ unsigned int desc_size;
+ u32 msg_enable;
+ struct clk *clk;
+ struct reset_control *rst;
+ phy_interface_t phy_mode;
+ struct phy_device *phydev;
+ struct mii_bus *mdio;
+
+ /* stats */
+ struct ave_stats stats_rx;
+ struct ave_stats stats_tx;
+
+ /* NAPI support */
+ struct net_device *ndev;
+ struct napi_struct napi_rx;
+ struct napi_struct napi_tx;
+
+ /* descriptor */
+ struct ave_desc_info rx;
+ struct ave_desc_info tx;
+
+ /* flow control */
+ int pause_auto;
+ int pause_rx;
+ int pause_tx;
+
+ const struct ave_soc_data *data;
+};
+
+static u32 ave_desc_read(struct net_device *ndev, enum desc_id id, int entry,
+ int offset)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 addr;
+
+ addr = ((id == AVE_DESCID_TX) ? priv->tx.daddr : priv->rx.daddr)
+ + entry * priv->desc_size + offset;
+
+ return readl(priv->base + addr);
+}
+
+static u32 ave_desc_read_cmdsts(struct net_device *ndev, enum desc_id id,
+ int entry)
+{
+ return ave_desc_read(ndev, id, entry, AVE_DESC_OFS_CMDSTS);
+}
+
+static void ave_desc_write(struct net_device *ndev, enum desc_id id,
+ int entry, int offset, u32 val)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 addr;
+
+ addr = ((id == AVE_DESCID_TX) ? priv->tx.daddr : priv->rx.daddr)
+ + entry * priv->desc_size + offset;
+
+ writel(val, priv->base + addr);
+}
+
+static void ave_desc_write_cmdsts(struct net_device *ndev, enum desc_id id,
+ int entry, u32 val)
+{
+ ave_desc_write(ndev, id, entry, AVE_DESC_OFS_CMDSTS, val);
+}
+
+static void ave_desc_write_addr(struct net_device *ndev, enum desc_id id,
+ int entry, dma_addr_t paddr)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ ave_desc_write(ndev, id, entry, AVE_DESC_OFS_ADDRL,
+ lower_32_bits(paddr));
+ if (IS_DESC_64BIT(priv))
+ ave_desc_write(ndev, id,
+ entry, AVE_DESC_OFS_ADDRU,
+ upper_32_bits(paddr));
+}
+
+static u32 ave_irq_disable_all(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 ret;
+
+ ret = readl(priv->base + AVE_GIMR);
+ writel(0, priv->base + AVE_GIMR);
+
+ return ret;
+}
+
+static void ave_irq_restore(struct net_device *ndev, u32 val)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ writel(val, priv->base + AVE_GIMR);
+}
+
+static void ave_irq_enable(struct net_device *ndev, u32 bitflag)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ writel(readl(priv->base + AVE_GIMR) | bitflag, priv->base + AVE_GIMR);
+ writel(bitflag, priv->base + AVE_GISR);
+}
+
+static void ave_hw_write_macaddr(struct net_device *ndev,
+ const unsigned char *mac_addr,
+ int reg1, int reg2)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ writel(mac_addr[0] | mac_addr[1] << 8 |
+ mac_addr[2] << 16 | mac_addr[3] << 24, priv->base + reg1);
+ writel(mac_addr[4] | mac_addr[5] << 8, priv->base + reg2);
+}
+
+static void ave_hw_read_version(struct net_device *ndev, char *buf, int len)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 major, minor, vr;
+
+ vr = readl(priv->base + AVE_VR);
+ major = (vr & GENMASK(15, 8)) >> 8;
+ minor = (vr & GENMASK(7, 0));
+ snprintf(buf, len, "v%u.%u", major, minor);
+}
+
+static void ave_ethtool_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ struct device *dev = ndev->dev.parent;
+
+ strlcpy(info->driver, dev->driver->name, sizeof(info->driver));
+ strlcpy(info->bus_info, dev_name(dev), sizeof(info->bus_info));
+ ave_hw_read_version(ndev, info->fw_version, sizeof(info->fw_version));
+}
+
+static u32 ave_ethtool_get_msglevel(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ return priv->msg_enable;
+}
+
+static void ave_ethtool_set_msglevel(struct net_device *ndev, u32 val)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ priv->msg_enable = val;
+}
+
+static void ave_ethtool_get_wol(struct net_device *ndev,
+ struct ethtool_wolinfo *wol)
+{
+ wol->supported = 0;
+ wol->wolopts = 0;
+
+ if (ndev->phydev)
+ phy_ethtool_get_wol(ndev->phydev, wol);
+}
+
+static int ave_ethtool_set_wol(struct net_device *ndev,
+ struct ethtool_wolinfo *wol)
+{
+ int ret;
+
+ if (!ndev->phydev ||
+ (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)))
+ return -EOPNOTSUPP;
+
+ ret = phy_ethtool_set_wol(ndev->phydev, wol);
+ if (!ret)
+ device_set_wakeup_enable(&ndev->dev, !!wol->wolopts);
+
+ return ret;
+}
+
+static void ave_ethtool_get_pauseparam(struct net_device *ndev,
+ struct ethtool_pauseparam *pause)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ pause->autoneg = priv->pause_auto;
+ pause->rx_pause = priv->pause_rx;
+ pause->tx_pause = priv->pause_tx;
+}
+
+static int ave_ethtool_set_pauseparam(struct net_device *ndev,
+ struct ethtool_pauseparam *pause)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ struct phy_device *phydev = ndev->phydev;
+
+ if (!phydev)
+ return -EINVAL;
+
+ priv->pause_auto = pause->autoneg;
+ priv->pause_rx = pause->rx_pause;
+ priv->pause_tx = pause->tx_pause;
+
+ phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
+ if (pause->rx_pause)
+ phydev->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
+ if (pause->tx_pause)
+ phydev->advertising ^= ADVERTISED_Asym_Pause;
+
+ if (pause->autoneg) {
+ if (netif_running(ndev))
+ phy_start_aneg(phydev);
+ }
+
+ return 0;
+}
+
+static const struct ethtool_ops ave_ethtool_ops = {
+ .get_link_ksettings = phy_ethtool_get_link_ksettings,
+ .set_link_ksettings = phy_ethtool_set_link_ksettings,
+ .get_drvinfo = ave_ethtool_get_drvinfo,
+ .nway_reset = phy_ethtool_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_msglevel = ave_ethtool_get_msglevel,
+ .set_msglevel = ave_ethtool_set_msglevel,
+ .get_wol = ave_ethtool_get_wol,
+ .set_wol = ave_ethtool_set_wol,
+ .get_pauseparam = ave_ethtool_get_pauseparam,
+ .set_pauseparam = ave_ethtool_set_pauseparam,
+};
+
+static int ave_mdiobus_read(struct mii_bus *bus, int phyid, int regnum)
+{
+ struct net_device *ndev = bus->priv;
+ struct ave_private *priv;
+ u32 mdioctl, mdiosr;
+ int ret;
+
+ priv = netdev_priv(ndev);
+
+ /* write address */
+ writel((phyid << 8) | regnum, priv->base + AVE_MDIOAR);
+
+ /* read request */
+ mdioctl = readl(priv->base + AVE_MDIOCTR);
+ writel((mdioctl | AVE_MDIOCTR_RREQ) & ~AVE_MDIOCTR_WREQ,
+ priv->base + AVE_MDIOCTR);
+
+ ret = readl_poll_timeout(priv->base + AVE_MDIOSR, mdiosr,
+ !(mdiosr & AVE_MDIOSR_STS), 20, 2000);
+ if (ret) {
+ netdev_err(ndev, "failed to read (phy:%d reg:%x)\n",
+ phyid, regnum);
+ return ret;
+ }
+
+ return readl(priv->base + AVE_MDIORDR) & GENMASK(15, 0);
+}
+
+static int ave_mdiobus_write(struct mii_bus *bus, int phyid, int regnum,
+ u16 val)
+{
+ struct net_device *ndev = bus->priv;
+ struct ave_private *priv;
+ u32 mdioctl, mdiosr;
+ int ret;
+
+ priv = netdev_priv(ndev);
+
+ /* write address */
+ writel((phyid << 8) | regnum, priv->base + AVE_MDIOAR);
+
+ /* write data */
+ writel(val, priv->base + AVE_MDIOWDR);
+
+ /* write request */
+ mdioctl = readl(priv->base + AVE_MDIOCTR);
+ writel((mdioctl | AVE_MDIOCTR_WREQ) & ~AVE_MDIOCTR_RREQ,
+ priv->base + AVE_MDIOCTR);
+
+ ret = readl_poll_timeout(priv->base + AVE_MDIOSR, mdiosr,
+ !(mdiosr & AVE_MDIOSR_STS), 20, 2000);
+ if (ret)
+ netdev_err(ndev, "failed to write (phy:%d reg:%x)\n",
+ phyid, regnum);
+
+ return ret;
+}
+
+static int ave_dma_map(struct net_device *ndev, struct ave_desc *desc,
+ void *ptr, size_t len, enum dma_data_direction dir,
+ dma_addr_t *paddr)
+{
+ dma_addr_t map_addr;
+
+ map_addr = dma_map_single(ndev->dev.parent, ptr, len, dir);
+ if (unlikely(dma_mapping_error(ndev->dev.parent, map_addr)))
+ return -ENOMEM;
+
+ desc->skbs_dma = map_addr;
+ desc->skbs_dmalen = len;
+ *paddr = map_addr;
+
+ return 0;
+}
+
+static void ave_dma_unmap(struct net_device *ndev, struct ave_desc *desc,
+ enum dma_data_direction dir)
+{
+ if (!desc->skbs_dma)
+ return;
+
+ dma_unmap_single(ndev->dev.parent,
+ desc->skbs_dma, desc->skbs_dmalen, dir);
+ desc->skbs_dma = 0;
+}
+
+/* Prepare Rx descriptor and memory */
+static int ave_rxdesc_prepare(struct net_device *ndev, int entry)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ struct sk_buff *skb;
+ dma_addr_t paddr;
+ int ret;
+
+ skb = priv->rx.desc[entry].skbs;
+ if (!skb) {
+ skb = netdev_alloc_skb_ip_align(ndev,
+ AVE_MAX_ETHFRAME);
+ if (!skb) {
+ netdev_err(ndev, "can't allocate skb for Rx\n");
+ return -ENOMEM;
+ }
+ }
+
+ /* set disable to cmdsts */
+ ave_desc_write_cmdsts(ndev, AVE_DESCID_RX, entry,
+ AVE_STS_INTR | AVE_STS_OWN);
+
+ /* map Rx buffer
+ * Rx buffer set to the Rx descriptor has two restrictions:
+ * - Rx buffer address is 4 byte aligned.
+ * - Rx buffer begins with 2 byte headroom, and data will be put from
+ * (buffer + 2).
+ * To satisfy this, specify the address to put back the buffer
+ * pointer advanced by NET_IP_ALIGN by netdev_alloc_skb_ip_align(),
+ * and expand the map size by NET_IP_ALIGN.
+ */
+ ret = ave_dma_map(ndev, &priv->rx.desc[entry],
+ skb->data - NET_IP_ALIGN,
+ AVE_MAX_ETHFRAME + NET_IP_ALIGN,
+ DMA_FROM_DEVICE, &paddr);
+ if (ret) {
+ netdev_err(ndev, "can't map skb for Rx\n");
+ dev_kfree_skb_any(skb);
+ return ret;
+ }
+ priv->rx.desc[entry].skbs = skb;
+
+ /* set buffer pointer */
+ ave_desc_write_addr(ndev, AVE_DESCID_RX, entry, paddr);
+
+ /* set enable to cmdsts */
+ ave_desc_write_cmdsts(ndev, AVE_DESCID_RX, entry,
+ AVE_STS_INTR | AVE_MAX_ETHFRAME);
+
+ return ret;
+}
+
+/* Switch state of descriptor */
+static int ave_desc_switch(struct net_device *ndev, enum desc_state state)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ int ret = 0;
+ u32 val;
+
+ switch (state) {
+ case AVE_DESC_START:
+ writel(AVE_DESCC_TD | AVE_DESCC_RD0, priv->base + AVE_DESCC);
+ break;
+
+ case AVE_DESC_STOP:
+ writel(0, priv->base + AVE_DESCC);
+ if (readl_poll_timeout(priv->base + AVE_DESCC, val, !val,
+ 150, 15000)) {
+ netdev_err(ndev, "can't stop descriptor\n");
+ ret = -EBUSY;
+ }
+ break;
+
+ case AVE_DESC_RX_SUSPEND:
+ val = readl(priv->base + AVE_DESCC);
+ val |= AVE_DESCC_RDSTP;
+ val &= ~AVE_DESCC_STATUS_MASK;
+ writel(val, priv->base + AVE_DESCC);
+ if (readl_poll_timeout(priv->base + AVE_DESCC, val,
+ val & (AVE_DESCC_RDSTP << 16),
+ 150, 150000)) {
+ netdev_err(ndev, "can't suspend descriptor\n");
+ ret = -EBUSY;
+ }
+ break;
+
+ case AVE_DESC_RX_PERMIT:
+ val = readl(priv->base + AVE_DESCC);
+ val &= ~AVE_DESCC_RDSTP;
+ val &= ~AVE_DESCC_STATUS_MASK;
+ writel(val, priv->base + AVE_DESCC);
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int ave_tx_complete(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 proc_idx, done_idx, ndesc, cmdsts;
+ unsigned int nr_freebuf = 0;
+ unsigned int tx_packets = 0;
+ unsigned int tx_bytes = 0;
+
+ proc_idx = priv->tx.proc_idx;
+ done_idx = priv->tx.done_idx;
+ ndesc = priv->tx.ndesc;
+
+ /* free pre-stored skb from done_idx to proc_idx */
+ while (proc_idx != done_idx) {
+ cmdsts = ave_desc_read_cmdsts(ndev, AVE_DESCID_TX, done_idx);
+
+ /* do nothing if owner is HW (==1 for Tx) */
+ if (cmdsts & AVE_STS_OWN)
+ break;
+
+ /* check Tx status and updates statistics */
+ if (cmdsts & AVE_STS_OK) {
+ tx_bytes += cmdsts & AVE_STS_PKTLEN_TX_MASK;
+ /* success */
+ if (cmdsts & AVE_STS_LAST)
+ tx_packets++;
+ } else {
+ /* error */
+ if (cmdsts & AVE_STS_LAST) {
+ priv->stats_tx.errors++;
+ if (cmdsts & (AVE_STS_OWC | AVE_STS_EC))
+ priv->stats_tx.collisions++;
+ }
+ }
+
+ /* release skb */
+ if (priv->tx.desc[done_idx].skbs) {
+ ave_dma_unmap(ndev, &priv->tx.desc[done_idx],
+ DMA_TO_DEVICE);
+ dev_consume_skb_any(priv->tx.desc[done_idx].skbs);
+ priv->tx.desc[done_idx].skbs = NULL;
+ nr_freebuf++;
+ }
+ done_idx = (done_idx + 1) % ndesc;
+ }
+
+ priv->tx.done_idx = done_idx;
+
+ /* update stats */
+ u64_stats_update_begin(&priv->stats_tx.syncp);
+ priv->stats_tx.packets += tx_packets;
+ priv->stats_tx.bytes += tx_bytes;
+ u64_stats_update_end(&priv->stats_tx.syncp);
+
+ /* wake queue for freeing buffer */
+ if (unlikely(netif_queue_stopped(ndev)) && nr_freebuf)
+ netif_wake_queue(ndev);
+
+ return nr_freebuf;
+}
+
+static int ave_rx_receive(struct net_device *ndev, int num)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ unsigned int rx_packets = 0;
+ unsigned int rx_bytes = 0;
+ u32 proc_idx, done_idx;
+ struct sk_buff *skb;
+ unsigned int pktlen;
+ int restpkt, npkts;
+ u32 ndesc, cmdsts;
+
+ proc_idx = priv->rx.proc_idx;
+ done_idx = priv->rx.done_idx;
+ ndesc = priv->rx.ndesc;
+ restpkt = ((proc_idx + ndesc - 1) - done_idx) % ndesc;
+
+ for (npkts = 0; npkts < num; npkts++) {
+ /* we can't receive more packet, so fill desc quickly */
+ if (--restpkt < 0)
+ break;
+
+ cmdsts = ave_desc_read_cmdsts(ndev, AVE_DESCID_RX, proc_idx);
+
+ /* do nothing if owner is HW (==0 for Rx) */
+ if (!(cmdsts & AVE_STS_OWN))
+ break;
+
+ if (!(cmdsts & AVE_STS_OK)) {
+ priv->stats_rx.errors++;
+ proc_idx = (proc_idx + 1) % ndesc;
+ continue;
+ }
+
+ pktlen = cmdsts & AVE_STS_PKTLEN_RX_MASK;
+
+ /* get skbuff for rx */
+ skb = priv->rx.desc[proc_idx].skbs;
+ priv->rx.desc[proc_idx].skbs = NULL;
+
+ ave_dma_unmap(ndev, &priv->rx.desc[proc_idx], DMA_FROM_DEVICE);
+
+ skb->dev = ndev;
+ skb_put(skb, pktlen);
+ skb->protocol = eth_type_trans(skb, ndev);
+
+ if ((cmdsts & AVE_STS_CSSV) && (!(cmdsts & AVE_STS_CSER)))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ rx_packets++;
+ rx_bytes += pktlen;
+
+ netif_receive_skb(skb);
+
+ proc_idx = (proc_idx + 1) % ndesc;
+ }
+
+ priv->rx.proc_idx = proc_idx;
+
+ /* update stats */
+ u64_stats_update_begin(&priv->stats_rx.syncp);
+ priv->stats_rx.packets += rx_packets;
+ priv->stats_rx.bytes += rx_bytes;
+ u64_stats_update_end(&priv->stats_rx.syncp);
+
+ /* refill the Rx buffers */
+ while (proc_idx != done_idx) {
+ if (ave_rxdesc_prepare(ndev, done_idx))
+ break;
+ done_idx = (done_idx + 1) % ndesc;
+ }
+
+ priv->rx.done_idx = done_idx;
+
+ return npkts;
+}
+
+static int ave_napi_poll_rx(struct napi_struct *napi, int budget)
+{
+ struct ave_private *priv;
+ struct net_device *ndev;
+ int num;
+
+ priv = container_of(napi, struct ave_private, napi_rx);
+ ndev = priv->ndev;
+
+ num = ave_rx_receive(ndev, budget);
+ if (num < budget) {
+ napi_complete_done(napi, num);
+
+ /* enable Rx interrupt when NAPI finishes */
+ ave_irq_enable(ndev, AVE_GI_RXIINT);
+ }
+
+ return num;
+}
+
+static int ave_napi_poll_tx(struct napi_struct *napi, int budget)
+{
+ struct ave_private *priv;
+ struct net_device *ndev;
+ int num;
+
+ priv = container_of(napi, struct ave_private, napi_tx);
+ ndev = priv->ndev;
+
+ num = ave_tx_complete(ndev);
+ napi_complete(napi);
+
+ /* enable Tx interrupt when NAPI finishes */
+ ave_irq_enable(ndev, AVE_GI_TX);
+
+ return num;
+}
+
+static void ave_global_reset(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 val;
+
+ /* set config register */
+ val = AVE_CFGR_FLE | AVE_CFGR_IPFCEN | AVE_CFGR_CHE;
+ if (!phy_interface_mode_is_rgmii(priv->phy_mode))
+ val |= AVE_CFGR_MII;
+ writel(val, priv->base + AVE_CFGR);
+
+ /* reset RMII register */
+ val = readl(priv->base + AVE_RSTCTRL);
+ val &= ~AVE_RSTCTRL_RMIIRST;
+ writel(val, priv->base + AVE_RSTCTRL);
+
+ /* assert reset */
+ writel(AVE_GRR_GRST | AVE_GRR_PHYRST, priv->base + AVE_GRR);
+ msleep(20);
+
+ /* 1st, negate PHY reset only */
+ writel(AVE_GRR_GRST, priv->base + AVE_GRR);
+ msleep(40);
+
+ /* negate reset */
+ writel(0, priv->base + AVE_GRR);
+ msleep(40);
+
+ /* negate RMII register */
+ val = readl(priv->base + AVE_RSTCTRL);
+ val |= AVE_RSTCTRL_RMIIRST;
+ writel(val, priv->base + AVE_RSTCTRL);
+
+ ave_irq_disable_all(ndev);
+}
+
+static void ave_rxfifo_reset(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 rxcr_org;
+
+ /* save and disable MAC receive op */
+ rxcr_org = readl(priv->base + AVE_RXCR);
+ writel(rxcr_org & (~AVE_RXCR_RXEN), priv->base + AVE_RXCR);
+
+ /* suspend Rx descriptor */
+ ave_desc_switch(ndev, AVE_DESC_RX_SUSPEND);
+
+ /* receive all packets before descriptor starts */
+ ave_rx_receive(ndev, priv->rx.ndesc);
+
+ /* assert reset */
+ writel(AVE_GRR_RXFFR, priv->base + AVE_GRR);
+ usleep_range(40, 50);
+
+ /* negate reset */
+ writel(0, priv->base + AVE_GRR);
+ usleep_range(10, 20);
+
+ /* negate interrupt status */
+ writel(AVE_GI_RXOVF, priv->base + AVE_GISR);
+
+ /* permit descriptor */
+ ave_desc_switch(ndev, AVE_DESC_RX_PERMIT);
+
+ /* restore MAC reccieve op */
+ writel(rxcr_org, priv->base + AVE_RXCR);
+}
+
+static irqreturn_t ave_irq_handler(int irq, void *netdev)
+{
+ struct net_device *ndev = (struct net_device *)netdev;
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 gimr_val, gisr_val;
+
+ gimr_val = ave_irq_disable_all(ndev);
+
+ /* get interrupt status */
+ gisr_val = readl(priv->base + AVE_GISR);
+
+ /* PHY */
+ if (gisr_val & AVE_GI_PHY)
+ writel(AVE_GI_PHY, priv->base + AVE_GISR);
+
+ /* check exceeding packet */
+ if (gisr_val & AVE_GI_RXERR) {
+ writel(AVE_GI_RXERR, priv->base + AVE_GISR);
+ netdev_err(ndev, "receive a packet exceeding frame buffer\n");
+ }
+
+ gisr_val &= gimr_val;
+ if (!gisr_val)
+ goto exit_isr;
+
+ /* RxFIFO overflow */
+ if (gisr_val & AVE_GI_RXOVF) {
+ priv->stats_rx.fifo_errors++;
+ ave_rxfifo_reset(ndev);
+ goto exit_isr;
+ }
+
+ /* Rx drop */
+ if (gisr_val & AVE_GI_RXDROP) {
+ priv->stats_rx.dropped++;
+ writel(AVE_GI_RXDROP, priv->base + AVE_GISR);
+ }
+
+ /* Rx interval */
+ if (gisr_val & AVE_GI_RXIINT) {
+ napi_schedule(&priv->napi_rx);
+ /* still force to disable Rx interrupt until NAPI finishes */
+ gimr_val &= ~AVE_GI_RXIINT;
+ }
+
+ /* Tx completed */
+ if (gisr_val & AVE_GI_TX) {
+ napi_schedule(&priv->napi_tx);
+ /* still force to disable Tx interrupt until NAPI finishes */
+ gimr_val &= ~AVE_GI_TX;
+ }
+
+exit_isr:
+ ave_irq_restore(ndev, gimr_val);
+
+ return IRQ_HANDLED;
+}
+
+static int ave_pfsel_start(struct net_device *ndev, unsigned int entry)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 val;
+
+ if (WARN_ON(entry > AVE_PF_SIZE))
+ return -EINVAL;
+
+ val = readl(priv->base + AVE_PFEN);
+ writel(val | BIT(entry), priv->base + AVE_PFEN);
+
+ return 0;
+}
+
+static int ave_pfsel_stop(struct net_device *ndev, unsigned int entry)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 val;
+
+ if (WARN_ON(entry > AVE_PF_SIZE))
+ return -EINVAL;
+
+ val = readl(priv->base + AVE_PFEN);
+ writel(val & ~BIT(entry), priv->base + AVE_PFEN);
+
+ return 0;
+}
+
+static int ave_pfsel_set_macaddr(struct net_device *ndev,
+ unsigned int entry,
+ const unsigned char *mac_addr,
+ unsigned int set_size)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ if (WARN_ON(entry > AVE_PF_SIZE))
+ return -EINVAL;
+ if (WARN_ON(set_size > 6))
+ return -EINVAL;
+
+ ave_pfsel_stop(ndev, entry);
+
+ /* set MAC address for the filter */
+ ave_hw_write_macaddr(ndev, mac_addr,
+ AVE_PKTF(entry), AVE_PKTF(entry) + 4);
+
+ /* set byte mask */
+ writel(GENMASK(31, set_size) & AVE_PFMBYTE_MASK0,
+ priv->base + AVE_PFMBYTE(entry));
+ writel(AVE_PFMBYTE_MASK1, priv->base + AVE_PFMBYTE(entry) + 4);
+
+ /* set bit mask filter */
+ writel(AVE_PFMBIT_MASK, priv->base + AVE_PFMBIT(entry));
+
+ /* set selector to ring 0 */
+ writel(0, priv->base + AVE_PFSEL(entry));
+
+ /* restart filter */
+ ave_pfsel_start(ndev, entry);
+
+ return 0;
+}
+
+static void ave_pfsel_set_promisc(struct net_device *ndev,
+ unsigned int entry, u32 rxring)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ if (WARN_ON(entry > AVE_PF_SIZE))
+ return;
+
+ ave_pfsel_stop(ndev, entry);
+
+ /* set byte mask */
+ writel(AVE_PFMBYTE_MASK0, priv->base + AVE_PFMBYTE(entry));
+ writel(AVE_PFMBYTE_MASK1, priv->base + AVE_PFMBYTE(entry) + 4);
+
+ /* set bit mask filter */
+ writel(AVE_PFMBIT_MASK, priv->base + AVE_PFMBIT(entry));
+
+ /* set selector to rxring */
+ writel(rxring, priv->base + AVE_PFSEL(entry));
+
+ ave_pfsel_start(ndev, entry);
+}
+
+static void ave_pfsel_init(struct net_device *ndev)
+{
+ unsigned char bcast_mac[ETH_ALEN];
+ int i;
+
+ eth_broadcast_addr(bcast_mac);
+
+ for (i = 0; i < AVE_PF_SIZE; i++)
+ ave_pfsel_stop(ndev, i);
+
+ /* promiscious entry, select ring 0 */
+ ave_pfsel_set_promisc(ndev, AVE_PFNUM_FILTER, 0);
+
+ /* unicast entry */
+ ave_pfsel_set_macaddr(ndev, AVE_PFNUM_UNICAST, ndev->dev_addr, 6);
+
+ /* broadcast entry */
+ ave_pfsel_set_macaddr(ndev, AVE_PFNUM_BROADCAST, bcast_mac, 6);
+}
+
+static void ave_phy_adjust_link(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ struct phy_device *phydev = ndev->phydev;
+ u32 val, txcr, rxcr, rxcr_org;
+ u16 rmt_adv = 0, lcl_adv = 0;
+ u8 cap;
+
+ /* set RGMII speed */
+ val = readl(priv->base + AVE_TXCR);
+ val &= ~(AVE_TXCR_TXSPD_100 | AVE_TXCR_TXSPD_1G);
+
+ if (phy_interface_is_rgmii(phydev) && phydev->speed == SPEED_1000)
+ val |= AVE_TXCR_TXSPD_1G;
+ else if (phydev->speed == SPEED_100)
+ val |= AVE_TXCR_TXSPD_100;
+
+ writel(val, priv->base + AVE_TXCR);
+
+ /* set RMII speed (100M/10M only) */
+ if (!phy_interface_is_rgmii(phydev)) {
+ val = readl(priv->base + AVE_LINKSEL);
+ if (phydev->speed == SPEED_10)
+ val &= ~AVE_LINKSEL_100M;
+ else
+ val |= AVE_LINKSEL_100M;
+ writel(val, priv->base + AVE_LINKSEL);
+ }
+
+ /* check current RXCR/TXCR */
+ rxcr = readl(priv->base + AVE_RXCR);
+ txcr = readl(priv->base + AVE_TXCR);
+ rxcr_org = rxcr;
+
+ if (phydev->duplex) {
+ rxcr |= AVE_RXCR_FDUPEN;
+
+ if (phydev->pause)
+ rmt_adv |= LPA_PAUSE_CAP;
+ if (phydev->asym_pause)
+ rmt_adv |= LPA_PAUSE_ASYM;
+ if (phydev->advertising & ADVERTISED_Pause)
+ lcl_adv |= ADVERTISE_PAUSE_CAP;
+ if (phydev->advertising & ADVERTISED_Asym_Pause)
+ lcl_adv |= ADVERTISE_PAUSE_ASYM;
+
+ cap = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+ if (cap & FLOW_CTRL_TX)
+ txcr |= AVE_TXCR_FLOCTR;
+ else
+ txcr &= ~AVE_TXCR_FLOCTR;
+ if (cap & FLOW_CTRL_RX)
+ rxcr |= AVE_RXCR_FLOCTR;
+ else
+ rxcr &= ~AVE_RXCR_FLOCTR;
+ } else {
+ rxcr &= ~AVE_RXCR_FDUPEN;
+ rxcr &= ~AVE_RXCR_FLOCTR;
+ txcr &= ~AVE_TXCR_FLOCTR;
+ }
+
+ if (rxcr_org != rxcr) {
+ /* disable Rx mac */
+ writel(rxcr & ~AVE_RXCR_RXEN, priv->base + AVE_RXCR);
+ /* change and enable TX/Rx mac */
+ writel(txcr, priv->base + AVE_TXCR);
+ writel(rxcr, priv->base + AVE_RXCR);
+ }
+
+ phy_print_status(phydev);
+}
+
+static void ave_macaddr_init(struct net_device *ndev)
+{
+ ave_hw_write_macaddr(ndev, ndev->dev_addr, AVE_RXMAC1R, AVE_RXMAC2R);
+
+ /* pfsel unicast entry */
+ ave_pfsel_set_macaddr(ndev, AVE_PFNUM_UNICAST, ndev->dev_addr, 6);
+}
+
+static int ave_init(struct net_device *ndev)
+{
+ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
+ struct ave_private *priv = netdev_priv(ndev);
+ struct device *dev = ndev->dev.parent;
+ struct device_node *np = dev->of_node;
+ struct device_node *mdio_np;
+ struct phy_device *phydev;
+ int ret;
+
+ /* enable clk because of hw access until ndo_open */
+ ret = clk_prepare_enable(priv->clk);
+ if (ret) {
+ dev_err(dev, "can't enable clock\n");
+ return ret;
+ }
+ ret = reset_control_deassert(priv->rst);
+ if (ret) {
+ dev_err(dev, "can't deassert reset\n");
+ goto out_clk_disable;
+ }
+
+ ave_global_reset(ndev);
+
+ mdio_np = of_get_child_by_name(np, "mdio");
+ if (!mdio_np) {
+ dev_err(dev, "mdio node not found\n");
+ ret = -EINVAL;
+ goto out_reset_assert;
+ }
+ ret = of_mdiobus_register(priv->mdio, mdio_np);
+ of_node_put(mdio_np);
+ if (ret) {
+ dev_err(dev, "failed to register mdiobus\n");
+ goto out_reset_assert;
+ }
+
+ phydev = of_phy_get_and_connect(ndev, np, ave_phy_adjust_link);
+ if (!phydev) {
+ dev_err(dev, "could not attach to PHY\n");
+ ret = -ENODEV;
+ goto out_mdio_unregister;
+ }
+
+ priv->phydev = phydev;
+
+ phy_ethtool_get_wol(phydev, &wol);
+ device_set_wakeup_capable(&ndev->dev, !!wol.supported);
+
+ if (!phy_interface_is_rgmii(phydev)) {
+ phydev->supported &= ~PHY_GBIT_FEATURES;
+ phydev->supported |= PHY_BASIC_FEATURES;
+ }
+ phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+
+ phy_attached_info(phydev);
+
+ return 0;
+
+out_mdio_unregister:
+ mdiobus_unregister(priv->mdio);
+out_reset_assert:
+ reset_control_assert(priv->rst);
+out_clk_disable:
+ clk_disable_unprepare(priv->clk);
+
+ return ret;
+}
+
+static void ave_uninit(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+
+ phy_disconnect(priv->phydev);
+ mdiobus_unregister(priv->mdio);
+
+ /* disable clk because of hw access after ndo_stop */
+ reset_control_assert(priv->rst);
+ clk_disable_unprepare(priv->clk);
+}
+
+static int ave_open(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ int entry;
+ int ret;
+ u32 val;
+
+ ret = request_irq(priv->irq, ave_irq_handler, IRQF_SHARED, ndev->name,
+ ndev);
+ if (ret)
+ return ret;
+
+ priv->tx.desc = kcalloc(priv->tx.ndesc, sizeof(*priv->tx.desc),
+ GFP_KERNEL);
+ if (!priv->tx.desc) {
+ ret = -ENOMEM;
+ goto out_free_irq;
+ }
+
+ priv->rx.desc = kcalloc(priv->rx.ndesc, sizeof(*priv->rx.desc),
+ GFP_KERNEL);
+ if (!priv->rx.desc) {
+ kfree(priv->tx.desc);
+ ret = -ENOMEM;
+ goto out_free_irq;
+ }
+
+ /* initialize Tx work and descriptor */
+ priv->tx.proc_idx = 0;
+ priv->tx.done_idx = 0;
+ for (entry = 0; entry < priv->tx.ndesc; entry++) {
+ ave_desc_write_cmdsts(ndev, AVE_DESCID_TX, entry, 0);
+ ave_desc_write_addr(ndev, AVE_DESCID_TX, entry, 0);
+ }
+ writel(AVE_TXDC_ADDR_START |
+ (((priv->tx.ndesc * priv->desc_size) << 16) & AVE_TXDC_SIZE),
+ priv->base + AVE_TXDC);
+
+ /* initialize Rx work and descriptor */
+ priv->rx.proc_idx = 0;
+ priv->rx.done_idx = 0;
+ for (entry = 0; entry < priv->rx.ndesc; entry++) {
+ if (ave_rxdesc_prepare(ndev, entry))
+ break;
+ }
+ writel(AVE_RXDC0_ADDR_START |
+ (((priv->rx.ndesc * priv->desc_size) << 16) & AVE_RXDC0_SIZE),
+ priv->base + AVE_RXDC0);
+
+ ave_desc_switch(ndev, AVE_DESC_START);
+
+ ave_pfsel_init(ndev);
+ ave_macaddr_init(ndev);
+
+ /* set Rx configuration */
+ /* full duplex, enable pause drop, enalbe flow control */
+ val = AVE_RXCR_RXEN | AVE_RXCR_FDUPEN | AVE_RXCR_DRPEN |
+ AVE_RXCR_FLOCTR | (AVE_MAX_ETHFRAME & AVE_RXCR_MPSIZ_MASK);
+ writel(val, priv->base + AVE_RXCR);
+
+ /* set Tx configuration */
+ /* enable flow control, disable loopback */
+ writel(AVE_TXCR_FLOCTR, priv->base + AVE_TXCR);
+
+ /* enable timer, clear EN,INTM, and mask interval unit(BSCK) */
+ val = readl(priv->base + AVE_IIRQC) & AVE_IIRQC_BSCK;
+ val |= AVE_IIRQC_EN0 | (AVE_INTM_COUNT << 16);
+ writel(val, priv->base + AVE_IIRQC);
+
+ val = AVE_GI_RXIINT | AVE_GI_RXOVF | AVE_GI_TX;
+ ave_irq_restore(ndev, val);
+
+ napi_enable(&priv->napi_rx);
+ napi_enable(&priv->napi_tx);
+
+ phy_start(ndev->phydev);
+ phy_start_aneg(ndev->phydev);
+ netif_start_queue(ndev);
+
+ return 0;
+
+out_free_irq:
+ disable_irq(priv->irq);
+ free_irq(priv->irq, ndev);
+
+ return ret;
+}
+
+static int ave_stop(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ int entry;
+
+ ave_irq_disable_all(ndev);
+ disable_irq(priv->irq);
+ free_irq(priv->irq, ndev);
+
+ netif_tx_disable(ndev);
+ phy_stop(ndev->phydev);
+ napi_disable(&priv->napi_tx);
+ napi_disable(&priv->napi_rx);
+
+ ave_desc_switch(ndev, AVE_DESC_STOP);
+
+ /* free Tx buffer */
+ for (entry = 0; entry < priv->tx.ndesc; entry++) {
+ if (!priv->tx.desc[entry].skbs)
+ continue;
+
+ ave_dma_unmap(ndev, &priv->tx.desc[entry], DMA_TO_DEVICE);
+ dev_kfree_skb_any(priv->tx.desc[entry].skbs);
+ priv->tx.desc[entry].skbs = NULL;
+ }
+ priv->tx.proc_idx = 0;
+ priv->tx.done_idx = 0;
+
+ /* free Rx buffer */
+ for (entry = 0; entry < priv->rx.ndesc; entry++) {
+ if (!priv->rx.desc[entry].skbs)
+ continue;
+
+ ave_dma_unmap(ndev, &priv->rx.desc[entry], DMA_FROM_DEVICE);
+ dev_kfree_skb_any(priv->rx.desc[entry].skbs);
+ priv->rx.desc[entry].skbs = NULL;
+ }
+ priv->rx.proc_idx = 0;
+ priv->rx.done_idx = 0;
+
+ kfree(priv->tx.desc);
+ kfree(priv->rx.desc);
+
+ return 0;
+}
+
+static int ave_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ u32 proc_idx, done_idx, ndesc, cmdsts;
+ int ret, freepkt;
+ dma_addr_t paddr;
+
+ proc_idx = priv->tx.proc_idx;
+ done_idx = priv->tx.done_idx;
+ ndesc = priv->tx.ndesc;
+ freepkt = ((done_idx + ndesc - 1) - proc_idx) % ndesc;
+
+ /* stop queue when not enough entry */
+ if (unlikely(freepkt < 1)) {
+ netif_stop_queue(ndev);
+ return NETDEV_TX_BUSY;
+ }
+
+ /* add padding for short packet */
+ if (skb_put_padto(skb, ETH_ZLEN)) {
+ priv->stats_tx.dropped++;
+ return NETDEV_TX_OK;
+ }
+
+ /* map Tx buffer
+ * Tx buffer set to the Tx descriptor doesn't have any restriction.
+ */
+ ret = ave_dma_map(ndev, &priv->tx.desc[proc_idx],
+ skb->data, skb->len, DMA_TO_DEVICE, &paddr);
+ if (ret) {
+ dev_kfree_skb_any(skb);
+ priv->stats_tx.dropped++;
+ return NETDEV_TX_OK;
+ }
+
+ priv->tx.desc[proc_idx].skbs = skb;
+
+ ave_desc_write_addr(ndev, AVE_DESCID_TX, proc_idx, paddr);
+
+ cmdsts = AVE_STS_OWN | AVE_STS_1ST | AVE_STS_LAST |
+ (skb->len & AVE_STS_PKTLEN_TX_MASK);
+
+ /* set interrupt per AVE_FORCE_TXINTCNT or when queue is stopped */
+ if (!(proc_idx % AVE_FORCE_TXINTCNT) || netif_queue_stopped(ndev))
+ cmdsts |= AVE_STS_INTR;
+
+ /* disable checksum calculation when skb doesn't calurate checksum */
+ if (skb->ip_summed == CHECKSUM_NONE ||
+ skb->ip_summed == CHECKSUM_UNNECESSARY)
+ cmdsts |= AVE_STS_NOCSUM;
+
+ ave_desc_write_cmdsts(ndev, AVE_DESCID_TX, proc_idx, cmdsts);
+
+ priv->tx.proc_idx = (proc_idx + 1) % ndesc;
+
+ return NETDEV_TX_OK;
+}
+
+static int ave_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
+{
+ return phy_mii_ioctl(ndev->phydev, ifr, cmd);
+}
+
+static const u8 v4multi_macadr[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 v6multi_macadr[] = { 0x33, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+static void ave_set_rx_mode(struct net_device *ndev)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ struct netdev_hw_addr *hw_adr;
+ int count, mc_cnt;
+ u32 val;
+
+ /* MAC addr filter enable for promiscious mode */
+ mc_cnt = netdev_mc_count(ndev);
+ val = readl(priv->base + AVE_RXCR);
+ if (ndev->flags & IFF_PROMISC || !mc_cnt)
+ val &= ~AVE_RXCR_AFEN;
+ else
+ val |= AVE_RXCR_AFEN;
+ writel(val, priv->base + AVE_RXCR);
+
+ /* set all multicast address */
+ if ((ndev->flags & IFF_ALLMULTI) || mc_cnt > AVE_PF_MULTICAST_SIZE) {
+ ave_pfsel_set_macaddr(ndev, AVE_PFNUM_MULTICAST,
+ v4multi_macadr, 1);
+ ave_pfsel_set_macaddr(ndev, AVE_PFNUM_MULTICAST + 1,
+ v6multi_macadr, 1);
+ } else {
+ /* stop all multicast filter */
+ for (count = 0; count < AVE_PF_MULTICAST_SIZE; count++)
+ ave_pfsel_stop(ndev, AVE_PFNUM_MULTICAST + count);
+
+ /* set multicast addresses */
+ count = 0;
+ netdev_for_each_mc_addr(hw_adr, ndev) {
+ if (count == mc_cnt)
+ break;
+ ave_pfsel_set_macaddr(ndev, AVE_PFNUM_MULTICAST + count,
+ hw_adr->addr, 6);
+ count++;
+ }
+ }
+}
+
+static void ave_get_stats64(struct net_device *ndev,
+ struct rtnl_link_stats64 *stats)
+{
+ struct ave_private *priv = netdev_priv(ndev);
+ unsigned int start;
+
+ do {
+ start = u64_stats_fetch_begin_irq(&priv->stats_rx.syncp);
+ stats->rx_packets = priv->stats_rx.packets;
+ stats->rx_bytes = priv->stats_rx.bytes;
+ } while (u64_stats_fetch_retry_irq(&priv->stats_rx.syncp, start));
+
+ do {
+ start = u64_stats_fetch_begin_irq(&priv->stats_tx.syncp);
+ stats->tx_packets = priv->stats_tx.packets;
+ stats->tx_bytes = priv->stats_tx.bytes;
+ } while (u64_stats_fetch_retry_irq(&priv->stats_tx.syncp, start));
+
+ stats->rx_errors = priv->stats_rx.errors;
+ stats->tx_errors = priv->stats_tx.errors;
+ stats->rx_dropped = priv->stats_rx.dropped;
+ stats->tx_dropped = priv->stats_tx.dropped;
+ stats->rx_fifo_errors = priv->stats_rx.fifo_errors;
+ stats->collisions = priv->stats_tx.collisions;
+}
+
+static int ave_set_mac_address(struct net_device *ndev, void *p)
+{
+ int ret = eth_mac_addr(ndev, p);
+
+ if (ret)
+ return ret;
+
+ ave_macaddr_init(ndev);
+
+ return 0;
+}
+
+static const struct net_device_ops ave_netdev_ops = {
+ .ndo_init = ave_init,
+ .ndo_uninit = ave_uninit,
+ .ndo_open = ave_open,
+ .ndo_stop = ave_stop,
+ .ndo_start_xmit = ave_start_xmit,
+ .ndo_do_ioctl = ave_ioctl,
+ .ndo_set_rx_mode = ave_set_rx_mode,
+ .ndo_get_stats64 = ave_get_stats64,
+ .ndo_set_mac_address = ave_set_mac_address,
+};
+
+static int ave_probe(struct platform_device *pdev)
+{
+ const struct ave_soc_data *data;
+ struct device *dev = &pdev->dev;
+ char buf[ETHTOOL_FWVERS_LEN];
+ phy_interface_t phy_mode;
+ struct ave_private *priv;
+ struct net_device *ndev;
+ struct device_node *np;
+ struct resource *res;
+ const void *mac_addr;
+ void __iomem *base;
+ u64 dma_mask;
+ int irq, ret;
+ u32 ave_id;
+
+ data = of_device_get_match_data(dev);
+ if (WARN_ON(!data))
+ return -EINVAL;
+
+ np = dev->of_node;
+ phy_mode = of_get_phy_mode(np);
+ if (phy_mode < 0) {
+ dev_err(dev, "phy-mode not found\n");
+ return -EINVAL;
+ }
+ if ((!phy_interface_mode_is_rgmii(phy_mode)) &&
+ phy_mode != PHY_INTERFACE_MODE_RMII &&
+ phy_mode != PHY_INTERFACE_MODE_MII) {
+ dev_err(dev, "phy-mode is invalid\n");
+ return -EINVAL;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "IRQ not found\n");
+ return irq;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ ndev = alloc_etherdev(sizeof(struct ave_private));
+ if (!ndev) {
+ dev_err(dev, "can't allocate ethernet device\n");
+ return -ENOMEM;
+ }
+
+ ndev->netdev_ops = &ave_netdev_ops;
+ ndev->ethtool_ops = &ave_ethtool_ops;
+ SET_NETDEV_DEV(ndev, dev);
+
+ ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_RXCSUM);
+ ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_RXCSUM);
+
+ ndev->max_mtu = AVE_MAX_ETHFRAME - (ETH_HLEN + ETH_FCS_LEN);
+
+ mac_addr = of_get_mac_address(np);
+ if (mac_addr)
+ ether_addr_copy(ndev->dev_addr, mac_addr);
+
+ /* if the mac address is invalid, use random mac address */
+ if (!is_valid_ether_addr(ndev->dev_addr)) {
+ eth_hw_addr_random(ndev);
+ dev_warn(dev, "Using random MAC address: %pM\n",
+ ndev->dev_addr);
+ }
+
+ priv = netdev_priv(ndev);
+ priv->base = base;
+ priv->irq = irq;
+ priv->ndev = ndev;
+ priv->msg_enable = netif_msg_init(-1, AVE_DEFAULT_MSG_ENABLE);
+ priv->phy_mode = phy_mode;
+ priv->data = data;
+
+ if (IS_DESC_64BIT(priv)) {
+ priv->desc_size = AVE_DESC_SIZE_64;
+ priv->tx.daddr = AVE_TXDM_64;
+ priv->rx.daddr = AVE_RXDM_64;
+ dma_mask = DMA_BIT_MASK(64);
+ } else {
+ priv->desc_size = AVE_DESC_SIZE_32;
+ priv->tx.daddr = AVE_TXDM_32;
+ priv->rx.daddr = AVE_RXDM_32;
+ dma_mask = DMA_BIT_MASK(32);
+ }
+ ret = dma_set_mask(dev, dma_mask);
+ if (ret)
+ goto out_free_netdev;
+
+ priv->tx.ndesc = AVE_NR_TXDESC;
+ priv->rx.ndesc = AVE_NR_RXDESC;
+
+ u64_stats_init(&priv->stats_tx.syncp);
+ u64_stats_init(&priv->stats_rx.syncp);
+
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ goto out_free_netdev;
+ }
+
+ priv->rst = devm_reset_control_get_optional_shared(dev, NULL);
+ if (IS_ERR(priv->rst)) {
+ ret = PTR_ERR(priv->rst);
+ goto out_free_netdev;
+ }
+
+ priv->mdio = devm_mdiobus_alloc(dev);
+ if (!priv->mdio) {
+ ret = -ENOMEM;
+ goto out_free_netdev;
+ }
+ priv->mdio->priv = ndev;
+ priv->mdio->parent = dev;
+ priv->mdio->read = ave_mdiobus_read;
+ priv->mdio->write = ave_mdiobus_write;
+ priv->mdio->name = "uniphier-mdio";
+ snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "%s-%x",
+ pdev->name, pdev->id);
+
+ /* Register as a NAPI supported driver */
+ netif_napi_add(ndev, &priv->napi_rx, ave_napi_poll_rx, priv->rx.ndesc);
+ netif_tx_napi_add(ndev, &priv->napi_tx, ave_napi_poll_tx,
+ priv->tx.ndesc);
+
+ platform_set_drvdata(pdev, ndev);
+
+ ret = register_netdev(ndev);
+ if (ret) {
+ dev_err(dev, "failed to register netdevice\n");
+ goto out_del_napi;
+ }
+
+ /* get ID and version */
+ ave_id = readl(priv->base + AVE_IDR);
+ ave_hw_read_version(ndev, buf, sizeof(buf));
+
+ dev_info(dev, "Socionext %c%c%c%c Ethernet IP %s (irq=%d, phy=%s)\n",
+ (ave_id >> 24) & 0xff, (ave_id >> 16) & 0xff,
+ (ave_id >> 8) & 0xff, (ave_id >> 0) & 0xff,
+ buf, priv->irq, phy_modes(phy_mode));
+
+ return 0;
+
+out_del_napi:
+ netif_napi_del(&priv->napi_rx);
+ netif_napi_del(&priv->napi_tx);
+out_free_netdev:
+ free_netdev(ndev);
+
+ return ret;
+}
+
+static int ave_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct ave_private *priv = netdev_priv(ndev);
+
+ unregister_netdev(ndev);
+ netif_napi_del(&priv->napi_rx);
+ netif_napi_del(&priv->napi_tx);
+ free_netdev(ndev);
+
+ return 0;
+}
+
+static const struct ave_soc_data ave_pro4_data = {
+ .is_desc_64bit = false,
+};
+
+static const struct ave_soc_data ave_pxs2_data = {
+ .is_desc_64bit = false,
+};
+
+static const struct ave_soc_data ave_ld11_data = {
+ .is_desc_64bit = false,
+};
+
+static const struct ave_soc_data ave_ld20_data = {
+ .is_desc_64bit = true,
+};
+
+static const struct of_device_id of_ave_match[] = {
+ {
+ .compatible = "socionext,uniphier-pro4-ave4",
+ .data = &ave_pro4_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pxs2-ave4",
+ .data = &ave_pxs2_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld11-ave4",
+ .data = &ave_ld11_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld20-ave4",
+ .data = &ave_ld20_data,
+ },
+ { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, of_ave_match);
+
+static struct platform_driver ave_driver = {
+ .probe = ave_probe,
+ .remove = ave_remove,
+ .driver = {
+ .name = "ave",
+ .of_match_table = of_ave_match,
+ },
+};
+module_platform_driver(ave_driver);
+
+MODULE_DESCRIPTION("Socionext UniPhier AVE ethernet driver");
+MODULE_LICENSE("GPL v2");
--
2.7.4
^ permalink raw reply related
* [PATCH net-next v9 1/2] dt-bindings: net: add DT bindings for Socionext UniPhier AVE
From: Kunihiko Hayashi @ 2017-12-28 6:58 UTC (permalink / raw)
To: David Miller, netdev
Cc: Mark Rutland, Andrew Lunn, Florian Fainelli, Kunihiko Hayashi,
Masami Hiramatsu, devicetree, linux-kernel, Masahiro Yamada,
Rob Herring, Jassi Brar, linux-arm-kernel
In-Reply-To: <1514444292-20643-1-git-send-email-hayashi.kunihiko@socionext.com>
DT bindings for the AVE ethernet controller found on Socionext's
UniPhier platforms.
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
.../bindings/net/socionext,uniphier-ave4.txt | 48 ++++++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
diff --git a/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
new file mode 100644
index 0000000..270ea4e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
@@ -0,0 +1,48 @@
+* Socionext AVE ethernet controller
+
+This describes the devicetree bindings for AVE ethernet controller
+implemented on Socionext UniPhier SoCs.
+
+Required properties:
+ - compatible: Should be
+ - "socionext,uniphier-pro4-ave4" : for Pro4 SoC
+ - "socionext,uniphier-pxs2-ave4" : for PXs2 SoC
+ - "socionext,uniphier-ld11-ave4" : for LD11 SoC
+ - "socionext,uniphier-ld20-ave4" : for LD20 SoC
+ - reg: Address where registers are mapped and size of region.
+ - interrupts: Should contain the MAC interrupt.
+ - phy-mode: See ethernet.txt in the same directory. Allow to choose
+ "rgmii", "rmii", or "mii" according to the PHY.
+ - phy-handle: Should point to the external phy device.
+ See ethernet.txt file in the same directory.
+ - clocks: A phandle to the clock for the MAC.
+
+Optional properties:
+ - resets: A phandle to the reset control for the MAC.
+ - local-mac-address: See ethernet.txt in the same directory.
+
+Required subnode:
+ - mdio: A container for child nodes representing phy nodes.
+ See phy.txt in the same directory.
+
+Example:
+
+ ether: ethernet@65000000 {
+ compatible = "socionext,uniphier-ld20-ave4";
+ reg = <0x65000000 0x8500>;
+ interrupts = <0 66 4>;
+ phy-mode = "rgmii";
+ phy-handle = <ðphy>;
+ clocks = <&sys_clk 6>;
+ resets = <&sys_rst 6>;
+ local-mac-address = [00 00 00 00 00 00];
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy: ethphy@1 {
+ reg = <1>;
+ };
+ };
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH net-next v9 0/2] add UniPhier AVE ethernet support
From: Kunihiko Hayashi @ 2017-12-28 6:58 UTC (permalink / raw)
To: David Miller, netdev-u79uwXL29TY76Z2rM5mHXA
Cc: Andrew Lunn, Florian Fainelli, Rob Herring, Mark Rutland,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Masahiro Yamada,
Masami Hiramatsu, Jassi Brar, Kunihiko Hayashi
This series adds support for Socionext AVE ethernet controller implemented
on UniPhier SoCs. This driver supports RGMII/RMII modes.
v8: https://www.spinics.net/lists/netdev/msg474374.html
The PHY patch included in v1 has already separated in:
http://www.spinics.net/lists/netdev/msg454595.html
Changes since v8:
- move operators at the beginning of the line to the end of the previous line
- dt-bindings: add blank lines before mdio and phy subnodes
Changes since v7:
- dt-bindings: fix mdio subnode description
Changes since v6:
- sort the order of local variables from longest to shortest line
- fix ave_probe() which calls register_netdev() at the end of initialization
- dt-bindings: remove phy node descriptions in mdio node
Changes since v5:
- replace license boilerplate with SPDX Identifier
- remove inline directives and an unused function
Changes since v4:
- fix larger integer warning on AVE_PFMBYTE_MASK0
Changes since v3:
- remove checking dma address and use dma_set_mask() to restirct address
- replace ave_mdio_busywait() with read_poll_timeout()
- replace functions to access to registers with readl/writel() directly
- replace a function to access to macaddr with ave_hw_write_macaddr()
- change return value of ave_dma_map() to error value
- move mdiobus_unregister() from ave_remove() to ave_uninit()
- eliminate else block at the end of ave_dma_map()
- add mask definitions for packet filter
- sort bitmap definitions in descending order
- add error check to some functions
- rename and sort functions to clear sub-categories
- fix error value consistency
- remove unneeded initializers
- change type of constant arrays
Changes since v2:
- replace clk_get() with devm_clk_get()
- replace reset_control_get() with devm_reset_control_get_optional_shared()
- add error return when the error occurs on the above *_get functions
- sort soc data and compatible strings
- remove clearly obvious comments
- modify dt-bindings document consistent with these modifications
Changes since v1:
- add/remove devicetree properties and sub-node
- remove "internal-phy-interrupt" and "desc-bits" property
- add SoC data structures based on compatible strings
- add node operation to apply "mdio" sub-node
- add support for features
- add support for {get,set}_pauseparam and pause frame operations
- add support for ndo_get_stats64 instead of ndo_get_stats
- replace with desiable functions
- replace check for valid phy_mode with phy_interface{_mode}_is_rgmii()
- replace phy attach message with phy_attached_info()
- replace 32bit operation with {upper,lower}_32_bits() on ave_wdesc_addr()
- replace nway_reset and get_link with generic functions
- move operations to proper functions
- move phy_start_aneg() to ndo_open,
and remove unnecessary PHY interrupt operations
See http://www.spinics.net/lists/netdev/msg454590.html
- move irq initialization and descriptor memory allocation to ndo_open
- move initialization of reset and clock and mdiobus to ndo_init
- fix skbuffer operations
- fix skb alignment operations and add Rx buffer adjustment for descriptor
See http://www.spinics.net/lists/netdev/msg456014.html
- add error returns when dma_map_single() failed
- clean up code structures
- clean up wait-loop and wake-queue conditions
- add ave_wdesc_addr() and offset definitions
- add ave_macaddr_init() to clean up mac-address operation
- fix checking whether Tx entry is not enough
- fix supported features of phydev
- add necessary free/disable operations
- add phydev check on ave_{get,set}_wol()
- remove netif_carrier functions, phydev initializer, and Tx budget check
- change obsolate codes
- replace ndev->{base_addr,irq} with the members of ave_private
- rename goto labels and mask definitions, and remove unused codes
Kunihiko Hayashi (2):
dt-bindings: net: add DT bindings for Socionext UniPhier AVE
net: ethernet: socionext: add AVE ethernet driver
.../bindings/net/socionext,uniphier-ave4.txt | 48 +
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/socionext/Kconfig | 22 +
drivers/net/ethernet/socionext/Makefile | 5 +
drivers/net/ethernet/socionext/sni_ave.c | 1736 ++++++++++++++++++++
6 files changed, 1813 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
create mode 100644 drivers/net/ethernet/socionext/Kconfig
create mode 100644 drivers/net/ethernet/socionext/Makefile
create mode 100644 drivers/net/ethernet/socionext/sni_ave.c
--
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
* Re: [PATCH V8 3/3] OPP: Allow "opp-hz" and "opp-microvolt" to contain magic values
From: Viresh Kumar @ 2017-12-28 4:37 UTC (permalink / raw)
To: Rob Herring
Cc: Ulf Hansson, Kevin Hilman, Viresh Kumar, Nishanth Menon,
Stephen Boyd, Rafael Wysocki, linux-pm, Vincent Guittot,
Rajendra Nayak, Sudeep Holla,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-kernel@vger.kernel.org
In-Reply-To: <CAL_JsqJzMfNhHK=6Wt4dzBRS9BVGMZ-f7uk3OnUupudTfwuyUA@mail.gmail.com>
On 27-12-17, 15:54, Rob Herring wrote:
> On Wed, Dec 27, 2017 at 2:56 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > On 26-12-17, 14:29, Rob Herring wrote:
> >> On Mon, Dec 18, 2017 at 03:51:30PM +0530, Viresh Kumar wrote:
> >
> >> > +On some platforms the exact frequency or voltage may be hidden from the OS by
> >> > +the firmware and the "opp-hz" or the "opp-microvolt" properties may contain
> >> > +magic values that represent the frequency or voltage in a firmware dependent
> >> > +way, for example an index of an array in the firmware.
> >>
> >> I'm still not convinced this is a good idea.
> >
> > You were kind-of a few days back :)
> >
> > lkml.kernel.org/r/CAL_JsqK-qtAaM_Ou5NtxcWR3F_q=8rMPJUm-VqGtKhbtWe5SAQ@mail.gmail.com
>
> Yeah, well that was before Stephen said anything.
>
> > So here is the deal:
> >
> > - I proposed "domain-performance-state" property for this stuff
> > initially.
> > - But Kevin didn't like that and proposed reusing "opp-hz" and
> > "opp-microvolt", which we all agreed to multiple times..
> > - And we are back to the same discussion now and its painful and time
> > killing for all of us.
>
> There's bigger issues than where we put magic values as I raised in
> the other patch.
>
> > TBH, I don't have too strong preferences about any of the suggestions
> > you guys have and I need you guys to tell me what binding changes to
> > do here and I will do that.
> >
> >> If you have firmware
> >> partially managing things, then I think we should have platform specific
> >> bindings or drivers.
> >
> > What about the initial idea then, like "performance-state" for the
> > power domains ? All platforms will anyway replicate that binding only.
>
> I don't really know. I don't really care either. I'll probably go
> along with what everyone agrees to, but the only one I see any
> agreement from is Ulf. Also, it is pretty vague as to what platforms
> will use this. You claimed you can support QCom scenarios, but there's
> really no evidence that that is true.
Well, I sent out the code few days back based on these bindings and everyone can
see how these bindings will get used now.
> What I don't want to see is this
> merged and then we need something more yet again in a few months for
> another platform.
Sure, I get your concerns.
So what we need now is:
- Stephen to start responding and clarify all the doubts he had as being silent
isn't helping.
- Or Rajendra to post patches which can prove that this is usable. The last time
I had a chat with him, he confirmed that he will post patches after 4.15-rc1
and he should have posted them by now, but he didn't :(
--
viresh
^ permalink raw reply
* Re: [RFC V7 2/2] OPP: Allow "opp-hz" and "opp-microvolt" to contain magic values
From: Viresh Kumar @ 2017-12-28 4:32 UTC (permalink / raw)
To: Rob Herring
Cc: Stephen Boyd, Ulf Hansson, Kevin Hilman, Viresh Kumar,
Nishanth Menon, Rafael Wysocki,
linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Vincent Guittot,
Rajendra Nayak, Sudeep Holla,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAL_JsqJA-cCOLRwHC1ZegHEt9v7pMoxY6qXF7Taq3k19bU-k3w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 27-12-17, 15:36, Rob Herring wrote:
> On Tue, Dec 26, 2017 at 10:45 PM, Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> > On 26-12-17, 14:23, Rob Herring wrote:
> >> > cpu_opp_table: cpu_opp_table {
> >> > compatible = "operating-points-v2";
> >> > opp-shared;
> >> >
> >> > opp00 {
> >> > opp-hz = /bits/ 64 <208000000>;
> >> > clock-latency-ns = <500000>;
> >> > power-domain-opp = <&domain_opp_1>;
> >>
> >> What is this? opp00 here is not a device. One OPP should not point to
> >> another. "power-domain-opp" is only supposed to appear in devices
> >> alongside power-domains properties.
> >
> > There are two type of devices:
> >
> > A.) With fixed performance state requirements and they will have the
> > new "required-opp" property in the device node itself as you said.
> >
> > B.) Devices which can do DVFS (CPU, MMC, LCD, etc) and those may need
> > a different performance state of the domain for their individual OPPs
> > and so we can't have this property in the device all the time.
> >
> > Does this make sense ?
>
> No. From the definition for power-domain-opp
>
> "+- power-domain-opp: This contains phandle to one of the OPP nodes of
> the master
> + power domain. This specifies the minimum required OPP of the master
> domain for
> + the functioning of the device in this OPP (where this property is present).
The per-opp thing was mentioned here.
> + This property can only be set for a device if the device node contains the
> + "power-domains" property.
This was trying to say something else, though it wasn't clear and so your
concerns.
I wanted to say that the device node or its OPP nodes can have the
"power-domain-opp" property only if the device node has a "power-domains"
property. i.e. you need to have power domain first and then only the
power-domain-opp property.
> Also, either all or none of the OPP nodes in an OPP
> + table should have it set."
>
> In the above example, you are violating the next to last sentence.
>
> Though, I'm now confused by what the last sentence means.
Yeah, lets leave it as is as the V8 has changed this significantly and you
already Acked it :)
--
viresh
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC PATCH v11 4/5] PCI / PM: Add support for the PCIe WAKE# signal for OF
From: Tony Lindgren @ 2017-12-28 4:22 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Rafael J. Wysocki, JeffyChen, Linux Kernel Mailing List,
Bjorn Helgaas, Linux PM, Shawn Lin, Brian Norris, Doug Anderson,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux PCI,
Rob Herring, Frank Rowand
In-Reply-To: <CAJZ5v0iaHPGiZJURhqZb8wdJXHxrAEHVN=U6rNHWGf-FGemPJA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
* Rafael J. Wysocki <rafael-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> [171228 00:51]:
> On Wed, Dec 27, 2017 at 4:08 PM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> > * Rafael J. Wysocki <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org> [171227 01:00]:
> >> On Tuesday, December 26, 2017 2:06:47 AM CET JeffyChen wrote:
> >> > Hi Rafael,
> >> >
> >> > Thanks for your reply :)
> >> >
> >> > On 12/26/2017 08:11 AM, Rafael J. Wysocki wrote:
> >> > >> >+
> >> > >> >+ dn = pci_device_to_OF_node(ppdev);
> >> > >> >+ if (!dn)
> >> > >> >+ return 0;
> >> > >> >+
> >> > >> >+ irq = of_irq_get_byname(dn, "wakeup");
> >> > > Why is this a property of the bridge and not of the device itself?
> >> >
> >> > That is suggested by Brian, because in that way, the wakeup pin would
> >> > not "tied to what exact device is installed (or no device, if it's a slot)."
> >>
> >> But I don't think it works when there are two devices using different WAKE#
> >> interrupt lines under the same bridge. Or how does it work then?
> >
> > It won't work currently for multiple devices but adding more than
> > one wakeriq per device is doable. And I think we will have other
> > cases where multiple wakeirqs are connected to a single device, so
> > that issue should be sorted out sooner or later.
> >
> > And if requesting wakeirq for the PCI WAKE# lines at the PCI
> > controller does the job, then maybe that's all we need to start with.
>
> These are expected to be out-of-band, so not having anything to do
> with the Root Complex.
>
> In-band PME Messages go through the PCIe hierarchy, but that is a
> standard mechanism and it is supported already.
>
> WAKE# are platform-specific, pretty much by definition and I guess
> that on most ARM boards they are just going to be some kind of GPIO
> pins.
OK. So probably supporting the following two configurations
should be enough then:
1. One or more WAKE# lines configured as a wakeirq for the PCI
controller
When the wakeirq calls pm_wakeup_event() for the PCI controller
device driver, the PCI controller wakes up and can deal with
it's child devices
2. Optionally a WAKE# line from a PCI device configured as wakeirq
for the PCI device driver
In this case calling the PM runtime resume in the child
PCI device will also wake up the parent PCI controller,
and then the PCI controller can deal with it's children
Seems like this series is pretty close to 1 above except
we need to have a list of wakeirqs per device instead of
just one. And option 2 should already work as long as the
PCI device driver parses and configures the wakeirq.
> > Then in addition to that, we could do the following to allow
> > PCI devices to request the wakeirq from the PCI controller:
> >
> > 1. PCI controller or framework implements a chained irq for
> > the WAKE# lines assuming it can mask/unmask the WAKE# lines
> >
> > 2. PCI devices then can just request the wakeirq from the PCI
> > controller
> >
> > And that's about it. Optionally we could leave out the dependency
> > to having PCI devices implement PM runtime and just resume the
> > parent (PCI controller) if PCI devices has not implemented
> > PM runtime.
>
> So if my understanding is correct, DT should give you the WAKE# IRQ
> for the given endpoint PCI device and you only are expected to request
> it. The rest should just follow from the other pieces of information
> in the DT.
Yeah and it seems that we should allow configuring both cases
1 and 2 above.
> With the quite obvious caveat that the same IRQ may be used as WAKE#
> for multiple endpoint devices (which BTW need not be under the same
> bridge even).
And with the shared interrupts we can't do the masking/unmasking
automatically..
> >> > >> >+ if (irq == -EPROBE_DEFER)
> >> > > Braces here, please.
> >> > ok, will fix in the next version.
> >> >
> >> > >
> >> > >> >+ return irq;
> >> > >> >+ /* Ignore other errors, since a missing wakeup is non-fatal. */
> >> > >> >+ else if (irq < 0) {
> >> > >> >+ dev_info(&pdev->dev, "cannot get wakeup interrupt: %d\n", irq);
> >> > >> >+ return 0;
> >> > >> >+ }
> >> > >> >+
> >> > >> >+ device_init_wakeup(&pdev->dev, true);
> >> > > Why do you call this before dev_pm_set_dedicated_wake_irq()?
> >> >
> >> > hmmm, i thought so too, but it turns out the dedicated wake irq
> >> > framework requires device_init_wakeup(dev, true) before attach the wake irq:
> >> >
> >> > int device_wakeup_attach_irq(struct device *dev,
> >> > struct wake_irq *wakeirq)
> >> > {
> >> > struct wakeup_source *ws;
> >> >
> >> > ws = dev->power.wakeup;
> >> > if (!ws) {
> >> > dev_err(dev, "forgot to call device_init_wakeup?\n");
> >> > return -EINVAL;
> >> >
> >>
> >> Well, that's a framework issue, fair enough.
> >>
> >> That said, what if user space removes the wakeup source from under you
> >> concurrently via sysfs? Tony?
> >
> > Hmm sounds racy, need to take a look.
>
> Not only racy, as I don't see anything to prevent user space from
> making the dev->power.wakeup wakeup source go away via sysfs at any
> time *after* the IRQ has been requested.
Currently nothing happens with wakeirqs if there's no struct
wakeup_source. On device_wakeup_enable() we call device_wakeup_attach()
that just copies dev->power.wakeirq to ws->wakeirq. And when struct
wake_source is freed the device should be active and wakeirq
disabled. Or are you seeing other issues here?
> Pretty much right after dev_pm_set_dedicated_wake_irq() has returned,
> device_wakeup_disable() may be called on the device via wakeup_store()
> and it doesn't even check if the device has a wakeup irq.
>
> > I think the only reason
> > to have the wakeirq pointer there was to save memory. It might
> > make sense to remove the wakeirq dependency here.
>
> Well, that looks necessary to be honest.
Seems like we're OK there except for the race. But I still wonder
if could just get rid of wakeirq in struct wakeup_source. Maybe
all we need is to see if dev->power.wakeup is allocated for the
wakeirqs.
Regards,
Tony
--
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 v5 2/2] PCI: mediatek: Set up class type and vendor ID for MT7622
From: Honghui Zhang @ 2017-12-28 1:39 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w,
eddie.huang-NuS5LvNUpcJWk0Htik3J/w,
ryder.lee-NuS5LvNUpcJWk0Htik3J/w, lorenzo.pieralisi-5wv7dgnIgG8,
hongkun.cao-NuS5LvNUpcJWk0Htik3J/w,
youlin.pei-NuS5LvNUpcJWk0Htik3J/w, yong.wu-NuS5LvNUpcJWk0Htik3J/w,
yt.shen-NuS5LvNUpcJWk0Htik3J/w, sean.wang-NuS5LvNUpcJWk0Htik3J/w,
xinping.qian-NuS5LvNUpcJWk0Htik3J/w
In-Reply-To: <20171227184542.GA79892-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org>
On Wed, 2017-12-27 at 12:45 -0600, Bjorn Helgaas wrote:
> On Wed, Dec 27, 2017 at 08:59:54AM +0800, honghui.zhang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org wrote:
> > From: Honghui Zhang <honghui.zhang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> >
> > The hardware default value of IDs and class type is not correct,
> > fix that by setup the correct values before start up.
> >
> > Signed-off-by: Honghui Zhang <honghui.zhang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> > drivers/pci/host/pcie-mediatek.c | 12 ++++++++++++
> > include/linux/pci_ids.h | 2 ++
> > 2 files changed, 14 insertions(+)
> >
> > diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
> > index fc29a9a..62aac0ea 100644
> > --- a/drivers/pci/host/pcie-mediatek.c
> > +++ b/drivers/pci/host/pcie-mediatek.c
> > @@ -74,6 +74,10 @@
> >
> > /* PCIe V2 per-port registers */
> > #define PCIE_MSI_VECTOR 0x0c0
> > +
> > +#define PCIE_CONF_ID 0x100
> > +#define PCIE_CONF_CLASS 0x104
> > +
> > #define PCIE_INT_MASK 0x420
> > #define INTX_MASK GENMASK(19, 16)
> > #define INTX_SHIFT 16
> > @@ -393,6 +397,14 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
> > val |= PCIE_CSR_LTSSM_EN(port->slot) |
> > PCIE_CSR_ASPM_L1_EN(port->slot);
> > writel(val, pcie->base + PCIE_SYS_CFG_V2);
> > +
> > + /* Set up vendor ID and device ID for MT7622*/
> > + val = PCI_VENDOR_ID_MEDIATEK;
> > + writel(val, port->base + PCIE_CONF_ID);
> > +
> > + /* Set up class code for MT7622 */
> > + val = PCI_CLASS_BRIDGE_PCI << 16;
> > + writel(val, port->base + PCIE_CONF_CLASS);
>
> 1) Your comments mention MT7622 specifically, but this code is run for
> both mt2712-pcie and mt7622-pcie. If this code is safe and necessary
> for both mt2712-pcie and mt7622-pcie, please remove the mention of
> MT7622.
Hmm, the code snippet added here will only be executed by MT7622, since
MT2712 will not enter this "if (pcie->base) {" condition.
Should the mention of MT7622 must be removed in this case?
>
> 2) The first comment mentions both "vendor ID and device ID" but you
> don't write the device ID. Since this code applies to both
> mt2712-pcie and mt7622-pcie, my guess is that you don't *want* to
> write the device ID. If that's the case, please fix the comment.
>
My bad, I did not check the comments carefully.
Thanks.
> 3) If you only need to set the vendor ID, you're performing a 32-bit
> write (writel()) to update a 16-bit value. Please use writew()
> instead.
>
Ok, thanks, I guess I could use the following code snippet in the next
version:
val = readl(port->base + PCIE_CONF_VENDOR_ID)
val &= ~GENMASK(15, 0);
val |= PCI_VENDOR_ID_MEDIATEK;
writel(val, port->base + PCIE_CONF_VENDOR_ID);
> 4) If you only need to set the vendor ID, please use a definition like
> "PCIE_CONF_VENDOR_ID" instead of the ambiguous "PCIE_CONF_ID".
>
> 5) If you only need to set the vendor ID, please update the changelog
> to mention "vendor ID" specifically instead of the ambiguous "IDs".
> 6) Please add a space before the closing "*/" of the first comment.
>
> 7) PCI_CLASS_BRIDGE_PCI is for a PCI-to-PCI bridge, i.e., one that has
> PCI on both the primary (upstream) side and the secondary (downstream)
> side. That kind of bridge has a type 1 config header (see
> PCI_HEADER_TYPE) and the PCI_PRIMARY_BUS and PCI_SECONDARY_BUS
> registers tell us the bus number of the primary and secondary sides.
>
> I don't believe this device is a PCI-to-PCI bridge. I think it's a
> *host* bridge that has some non-PCI interface on the upstream side and
> should have a type 0 config header. If that's the case you should use
> PCI_CLASS_BRIDGE_HOST instead.
>
Thanks very much for your help with the review, I will fix the other
issue in the next version.
> > }
> >
> > /* Assert all reset signals */
> > diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> > index ab20dc5..2480b0e 100644
> > --- a/include/linux/pci_ids.h
> > +++ b/include/linux/pci_ids.h
> > @@ -2113,6 +2113,8 @@
> >
> > #define PCI_VENDOR_ID_MYRICOM 0x14c1
> >
> > +#define PCI_VENDOR_ID_MEDIATEK 0x14c3
> > +
> > #define PCI_VENDOR_ID_TITAN 0x14D2
> > #define PCI_DEVICE_ID_TITAN_010L 0x8001
> > #define PCI_DEVICE_ID_TITAN_100L 0x8010
> > --
> > 2.6.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 v4 1/2] dt-bindings: media: Add Allwinner V3s Camera Sensor Interface (CSI)
From: Yong @ 2017-12-28 1:05 UTC (permalink / raw)
To: Rob Herring
Cc: Maxime Ripard, Mauro Carvalho Chehab, Mark Rutland, Chen-Yu Tsai,
David S. Miller, Greg Kroah-Hartman, Randy Dunlap, Hans Verkuil,
Stanimir Varbanov, Hugues Fruchet, Yannick Fertre, Philipp Zabel,
Arnd Bergmann, Benjamin Gaignard, Ramesh Shanmugasundaram,
Sakari Ailus, Rick Chang, linux-media-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20171226215537.cmn4l7k2w764yrsg@rob-hp-laptop>
Hi,
On Tue, 26 Dec 2017 15:55:37 -0600
Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Dec 22, 2017 at 05:41:29PM +0800, Yong Deng wrote:
> > Add binding documentation for Allwinner V3s CSI.
> >
> > Signed-off-by: Yong Deng <yong.deng-+3dxTMOEIRNWk0Htik3J/w@public.gmane.org>
> > ---
> > .../devicetree/bindings/media/sun6i-csi.txt | 51 ++++++++++++++++++++++
> > 1 file changed, 51 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/media/sun6i-csi.txt
> >
> > diff --git a/Documentation/devicetree/bindings/media/sun6i-csi.txt b/Documentation/devicetree/bindings/media/sun6i-csi.txt
> > new file mode 100644
> > index 0000000..b5bfe3f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/sun6i-csi.txt
> > @@ -0,0 +1,51 @@
> > +Allwinner V3s Camera Sensor Interface
> > +------------------------------
> > +
> > +Required properties:
> > + - compatible: value must be "allwinner,sun8i-v3s-csi"
> > + - reg: base address and size of the memory-mapped region.
> > + - interrupts: interrupt associated to this IP
> > + - clocks: phandles to the clocks feeding the CSI
> > + * bus: the CSI interface clock
> > + * mod: the CSI module clock
> > + * ram: the CSI DRAM clock
> > + - clock-names: the clock names mentioned above
> > + - resets: phandles to the reset line driving the CSI
> > +
> > +- ports: A ports node with endpoint definitions as defined in
> > + Documentation/devicetree/bindings/media/video-interfaces.txt.
> > + Currently, the driver only support the parallel interface. So, a single port
> > + node with one endpoint and parallel bus is supported.
>
> What the driver supports is not relevant. Please document what the h/w
> has.
OK.
>
> > +
> > +Example:
> > +
> > + csi1: csi@1cb4000 {
> > + compatible = "allwinner,sun8i-v3s-csi";
> > + reg = <0x01cb4000 0x1000>;
> > + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_CSI>,
> > + <&ccu CLK_CSI1_SCLK>,
> > + <&ccu CLK_DRAM_CSI>;
> > + clock-names = "bus", "mod", "ram";
> > + resets = <&ccu RST_BUS_CSI>;
> > +
> > + port {
>
> > + #address-cells = <1>;
> > + #size-cells = <0>;
>
> These are not needed with a single endpoint.
OK.
>
> > +
> > + /* Parallel bus endpoint */
> > + csi1_ep: endpoint {
> > + remote-endpoint = <&adv7611_ep>;
> > + bus-width = <16>;
> > + data-shift = <0>;
> > +
> > + /* If hsync-active/vsync-active are missing,
> > + embedded BT.656 sync is used */
> > + hsync-active = <0>; /* Active low */
> > + vsync-active = <0>; /* Active low */
> > + data-active = <1>; /* Active high */
> > + pclk-sample = <1>; /* Rising */
> > + };
> > + };
> > + };
> > +
> > --
> > 1.8.3.1
> >
Thanks,
Yong
^ permalink raw reply
* Re: [PATCH v2 2/3] dt-bindings: media: Add Allwinner V3s Camera Sensor Interface (CSI)
From: Yong @ 2017-12-28 1:04 UTC (permalink / raw)
To: Sakari Ailus
Cc: maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
Mauro Carvalho Chehab, Rob Herring, Mark Rutland, Chen-Yu Tsai,
Greg Kroah-Hartman, David S. Miller, Hans Verkuil, Arnd Bergmann,
Hugues Fruchet, Yannick Fertre, Philipp Zabel, Benoit Parrot,
Benjamin Gaignard, Jean-Christophe Trotin,
Ramesh Shanmugasundaram, Minghsiu Tsai, Krzysztof Kozlowski,
Robert Jarzmik, linux-media-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20171227214723.rcssyay2lqqjf6ty-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
Hi,
On Wed, 27 Dec 2017 23:47:23 +0200
Sakari Ailus <sakari.ailus-X3B1VOXEql0@public.gmane.org> wrote:
> Hi Yong,
>
> On Thu, Dec 21, 2017 at 10:49:35AM +0800, Yong wrote:
> > Hi,
> >
> > On Tue, 19 Dec 2017 13:53:28 +0200
> > Sakari Ailus <sakari.ailus-X3B1VOXEql0@public.gmane.org> wrote:
> >
> > > Hi Yong,
> > >
> > > On Thu, Jul 27, 2017 at 01:01:36PM +0800, Yong Deng wrote:
> > > > Add binding documentation for Allwinner V3s CSI.
> > > >
> > > > Signed-off-by: Yong Deng <yong.deng-+3dxTMOEIRNWk0Htik3J/w@public.gmane.org>
> > >
> > > DT bindings should precede the driver.
> >
> > OK.
> >
> > >
> > > > ---
> > > > .../devicetree/bindings/media/sun6i-csi.txt | 49 ++++++++++++++++++++++
> > > > 1 file changed, 49 insertions(+)
> > > > create mode 100644 Documentation/devicetree/bindings/media/sun6i-csi.txt
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/media/sun6i-csi.txt b/Documentation/devicetree/bindings/media/sun6i-csi.txt
> > > > new file mode 100644
> > > > index 0000000..f8d83f6
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/media/sun6i-csi.txt
> > > > @@ -0,0 +1,49 @@
> > > > +Allwinner V3s Camera Sensor Interface
> > > > +------------------------------
> > > > +
> > > > +Required properties:
> > > > + - compatible: value must be "allwinner,sun8i-v3s-csi"
> > >
> > > What are sun6i and sun8i? Is this device first present in sun6i SoCs,
> > > whereas you have only defined bindings for sun8i?
> >
> > Yes, some sun6i SoCs has the almost same CSI module.
> > There is only V3s on my hand. So, I only tested it on V3s. But
> > some people work on the others.
>
> Ack.
>
> >
> > >
> > > > + - reg: base address and size of the memory-mapped region.
> > > > + - interrupts: interrupt associated to this IP
> > > > + - clocks: phandles to the clocks feeding the CSI
> > > > + * ahb: the CSI interface clock
> > > > + * mod: the CSI module clock
> > > > + * ram: the CSI DRAM clock
> > > > + - clock-names: the clock names mentioned above
> > > > + - resets: phandles to the reset line driving the CSI
> > > > +
> > > > +- ports: A ports node with endpoint definitions as defined in
> > > > + Documentation/devicetree/bindings/media/video-interfaces.txt.
> > >
> > > Please document mandatory and optional endpoint properties relevant for the
> > > hardware.
> >
> > I have added below commit in my v3:
> > Currently, the driver only support the parallel interface. So, a single port
> > node with one endpoint and parallel bus is supported.
>
> Please specify the exact properties that are relevant for the hardware. No
> references should be made to the driver, the bindings are entirely
> separate.
>
> Are the non-parallel (CSI-2?) and parallel bus on the same interface? If
> yes, they should probably use different endpoints, if not, then different
> ports.
>
> You could document the other bus or omit it now altogether, in which case
> you'd only detail the parallel bus properties here.
Thanks for your explication. I have misunderstood this.
>
> >
> > >
> > > > +
> > > > +Example:
> > > > +
> > > > + csi1: csi@01cb4000 {
> > > > + compatible = "allwinner,sun8i-v3s-csi";
> > > > + reg = <0x01cb4000 0x1000>;
> > > > + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
> > > > + clocks = <&ccu CLK_BUS_CSI>,
> > > > + <&ccu CLK_CSI1_SCLK>,
> > > > + <&ccu CLK_DRAM_CSI>;
> > > > + clock-names = "ahb", "mod", "ram";
> > > > + resets = <&ccu RST_BUS_CSI>;
> > > > +
> > > > + port {
> > > > + #address-cells = <1>;
> > > > + #size-cells = <0>;
> > > > +
> > > > + /* Parallel bus endpoint */
> > > > + csi1_ep: endpoint {
> > > > + remote-endpoint = <&adv7611_ep>;
> > > > + bus-width = <16>;
> > > > + data-shift = <0>;
> > > > +
> > > > + /* If hsync-active/vsync-active are missing,
> > > > + embedded BT.656 sync is used */
> > > > + hsync-active = <0>; /* Active low */
> > > > + vsync-active = <0>; /* Active low */
> > > > + data-active = <1>; /* Active high */
> > > > + pclk-sample = <1>; /* Rising */
> > > > + };
> > > > + };
> > > > + };
> > > > +
> > >
> > > --
> > > Kind regards,
> > >
> > > Sakari Ailus
> > > e-mail: sakari.ailus-X3B1VOXEql0@public.gmane.org
> >
> >
> > Thanks,
> > Yong
>
> --
> Regards,
>
> Sakari Ailus
> e-mail: sakari.ailus-X3B1VOXEql0@public.gmane.org
Thanks,
Yong
^ permalink raw reply
* Re: [RFC PATCH v11 4/5] PCI / PM: Add support for the PCIe WAKE# signal for OF
From: Rafael J. Wysocki @ 2017-12-28 0:48 UTC (permalink / raw)
To: Tony Lindgren
Cc: Rafael J. Wysocki, JeffyChen, Linux Kernel Mailing List,
Bjorn Helgaas, Linux PM, Shawn Lin, Brian Norris, Doug Anderson,
devicetree@vger.kernel.org, Linux PCI, Rob Herring, Frank Rowand
In-Reply-To: <20171227150800.GF3875@atomide.com>
On Wed, Dec 27, 2017 at 4:08 PM, Tony Lindgren <tony@atomide.com> wrote:
> * Rafael J. Wysocki <rjw@rjwysocki.net> [171227 01:00]:
>> On Tuesday, December 26, 2017 2:06:47 AM CET JeffyChen wrote:
>> > Hi Rafael,
>> >
>> > Thanks for your reply :)
>> >
>> > On 12/26/2017 08:11 AM, Rafael J. Wysocki wrote:
>> > >> >+
>> > >> >+ dn = pci_device_to_OF_node(ppdev);
>> > >> >+ if (!dn)
>> > >> >+ return 0;
>> > >> >+
>> > >> >+ irq = of_irq_get_byname(dn, "wakeup");
>> > > Why is this a property of the bridge and not of the device itself?
>> >
>> > That is suggested by Brian, because in that way, the wakeup pin would
>> > not "tied to what exact device is installed (or no device, if it's a slot)."
>>
>> But I don't think it works when there are two devices using different WAKE#
>> interrupt lines under the same bridge. Or how does it work then?
>
> It won't work currently for multiple devices but adding more than
> one wakeriq per device is doable. And I think we will have other
> cases where multiple wakeirqs are connected to a single device, so
> that issue should be sorted out sooner or later.
>
> And if requesting wakeirq for the PCI WAKE# lines at the PCI
> controller does the job, then maybe that's all we need to start with.
These are expected to be out-of-band, so not having anything to do
with the Root Complex.
In-band PME Messages go through the PCIe hierarchy, but that is a
standard mechanism and it is supported already.
WAKE# are platform-specific, pretty much by definition and I guess
that on most ARM boards they are just going to be some kind of GPIO
pins.
> Then in addition to that, we could do the following to allow
> PCI devices to request the wakeirq from the PCI controller:
>
> 1. PCI controller or framework implements a chained irq for
> the WAKE# lines assuming it can mask/unmask the WAKE# lines
>
> 2. PCI devices then can just request the wakeirq from the PCI
> controller
>
> And that's about it. Optionally we could leave out the dependency
> to having PCI devices implement PM runtime and just resume the
> parent (PCI controller) if PCI devices has not implemented
> PM runtime.
So if my understanding is correct, DT should give you the WAKE# IRQ
for the given endpoint PCI device and you only are expected to request
it. The rest should just follow from the other pieces of information
in the DT.
With the quite obvious caveat that the same IRQ may be used as WAKE#
for multiple endpoint devices (which BTW need not be under the same
bridge even).
>> > >> >+ if (irq == -EPROBE_DEFER)
>> > > Braces here, please.
>> > ok, will fix in the next version.
>> >
>> > >
>> > >> >+ return irq;
>> > >> >+ /* Ignore other errors, since a missing wakeup is non-fatal. */
>> > >> >+ else if (irq < 0) {
>> > >> >+ dev_info(&pdev->dev, "cannot get wakeup interrupt: %d\n", irq);
>> > >> >+ return 0;
>> > >> >+ }
>> > >> >+
>> > >> >+ device_init_wakeup(&pdev->dev, true);
>> > > Why do you call this before dev_pm_set_dedicated_wake_irq()?
>> >
>> > hmmm, i thought so too, but it turns out the dedicated wake irq
>> > framework requires device_init_wakeup(dev, true) before attach the wake irq:
>> >
>> > int device_wakeup_attach_irq(struct device *dev,
>> > struct wake_irq *wakeirq)
>> > {
>> > struct wakeup_source *ws;
>> >
>> > ws = dev->power.wakeup;
>> > if (!ws) {
>> > dev_err(dev, "forgot to call device_init_wakeup?\n");
>> > return -EINVAL;
>> >
>>
>> Well, that's a framework issue, fair enough.
>>
>> That said, what if user space removes the wakeup source from under you
>> concurrently via sysfs? Tony?
>
> Hmm sounds racy, need to take a look.
Not only racy, as I don't see anything to prevent user space from
making the dev->power.wakeup wakeup source go away via sysfs at any
time *after* the IRQ has been requested.
Pretty much right after dev_pm_set_dedicated_wake_irq() has returned,
device_wakeup_disable() may be called on the device via wakeup_store()
and it doesn't even check if the device has a wakeup irq.
> I think the only reason
> to have the wakeirq pointer there was to save memory. It might
> make sense to remove the wakeirq dependency here.
Well, that looks necessary to be honest.
Thanks,
Rafael
^ permalink raw reply
* Re: [RFC PATCH v12 4/5] PCI / PM: Add support for the PCIe WAKE# signal for OF
From: Rafael J. Wysocki @ 2017-12-28 0:32 UTC (permalink / raw)
To: Rob Herring
Cc: JeffyChen, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Bjorn Helgaas, Linux PM, Tony Lindgren, Shawn Lin, Brian Norris,
Rafael J. Wysocki, Doug Anderson,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Linux PCI, Frank Rowand, Andy Shevchenko
In-Reply-To: <CAL_JsqJssPABjoRM-XAnuN_Xd2-sHoFifJNrRDdk_ruQ0DRw6A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, Dec 27, 2017 at 4:30 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Tue, Dec 26, 2017 at 7:32 PM, JeffyChen <jeffy.chen-TNX95d0MmH7DzftRWevZcw@public.gmane.org> wrote:
>> Hi Rob,
>>
>> Thanks for your reply.
>>
>> On 12/27/2017 07:56 AM, Rob Herring wrote:
>>>>
>>>> >
>>>> > drivers/of/of_pci_irq.c | 49 +++++++++++++++++++++++++++++++
>>>
>>> Please move this to drivers/pci/of.c (or perhaps create pci/of_irq.c).
>>>
>>>> > drivers/pci/Makefile | 1 +
>>>> > drivers/pci/pci-driver.c | 10 +++++++
>>>> > drivers/pci/pci-of.c | 75
>>>> > ++++++++++++++++++++++++++++++++++++++++++++++++
>>>
>>> We already have drivers/pci/of.c. It's not clear what the difference is
>>> from the filenames. Either merge with of.c or perhaps of-pm.c.
>>
>>
>> this new file does something similar to the pci-acpi.c and pci-mid.c..
>
> pci-acpi.c has similar things to pci/of.c. The naming is just not consistent.
>
> Also, I plan to move the rest of drivers/of/of_pci* to drivers/pci.
>
>> and i am agree the naming is not clear, maybe we can rename both of those
>> files to something like pci-pm-***.c?
>
> At least pci-acpi.c is more than just PM functions, so that doesn't
> make sense. Given that all the ACPI related functions are in 1 file,
> we should do the same for DT.
Agreed.
Thanks,
Rafael
--
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] ARM: dts: qcom: msm8974: Add Sony Xperia Z1 Compact
From: Bjorn Andersson @ 2017-12-27 23:22 UTC (permalink / raw)
To: Attila Sz?ll??si
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Russell King,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Brown, Rob Herring,
Andy Gross, linux-soc-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20171203040919.16243-1-ata2001-baQpNawxmjKjKv3TNrM5DQ@public.gmane.org>
On Sat 02 Dec 20:09 PST 2017, Attila Sz?ll??si wrote:
> This patch adds a DTS file for Sony Xperia Z1 Compact with support for
> regulators, serial UART, eMMC/SD-card, USB, charger, backlight,
> coincell and buttons.
>
> Work based on arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts.
>
> Signed-off-by: Attila Szöll??si <ata2001-baQpNawxmjKjKv3TNrM5DQ@public.gmane.org>
Acked-by: Bjorn Andersson <bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
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
* Re: [PATCH v3 1/5] dt-bindings: at24: consistently document the compatible property
From: Peter Rosin @ 2017-12-27 22:02 UTC (permalink / raw)
To: Bartosz Golaszewski, Andy Shevchenko, Rob Herring, Mark Rutland,
Javier Martinez Canillas, David Lechner, Divagar Mohandass
Cc: linux-i2c, devicetree, linux-kernel
In-Reply-To: <20171227135054.29690-2-brgl@bgdev.pl>
On 2017-12-27 14:50, Bartosz Golaszewski wrote:
> Current description of the compatible property for at24 is quite vague.
>
> State explicitly that any "<manufacturer>,<model>" pair is accepted as
> long as one of the listed strings is used as fallback.
>
> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
> ---
> Documentation/devicetree/bindings/eeprom/at24.txt | 37 +++++++++--------------
> 1 file changed, 15 insertions(+), 22 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/eeprom/at24.txt b/Documentation/devicetree/bindings/eeprom/at24.txt
> index cbc80e194ac6..b5ce5a247554 100644
> --- a/Documentation/devicetree/bindings/eeprom/at24.txt
> +++ b/Documentation/devicetree/bindings/eeprom/at24.txt
> @@ -2,28 +2,21 @@ EEPROMs (I2C)
>
> Required properties:
>
> - - compatible : should be "<manufacturer>,<type>", like these:
> -
> - "atmel,24c00", "atmel,24c01", "atmel,24c02", "atmel,24c04",
> - "atmel,24c08", "atmel,24c16", "atmel,24c32", "atmel,24c64",
> - "atmel,24c128", "atmel,24c256", "atmel,24c512", "atmel,24c1024"
> -
> - "catalyst,24c32"
> -
> - "microchip,24c128"
> -
> - "ramtron,24c64"
> -
> - "renesas,r1ex24002"
> -
> - The following manufacturers values have been deprecated:
> - "at", "at24"
> -
> - If there is no specific driver for <manufacturer>, a generic
> - device with <type> and manufacturer "atmel" should be used.
> - Possible types are:
> - "24c00", "24c01", "24c02", "24c04", "24c08", "24c16", "24c32", "24c64",
> - "24c128", "24c256", "24c512", "24c1024", "spd"
> + - compatible: must be a "<manufacturer>,<model>" pair with one of the
> + following values as fallback:
> +
> + "atmel,24c00",
> + "atmel,24c01",
I read the above as if it is no longer allowed to have a plain old atmel
chip, since the atmel compatibles are now valid as fallbacks /only/. I don't
think that's what you intended?
Cheers,
Peter
> + "atmel,24c02",
> + "atmel,24c04",
> + "atmel,24c08",
> + "atmel,24c16",
> + "atmel,24c32",
> + "atmel,24c64",
> + "atmel,24c128",
> + "atmel,24c256",
> + "atmel,24c512",
> + "atmel,24c1024"
>
> - reg : the I2C address of the EEPROM
>
>
^ permalink raw reply
* Re: [PATCH v5 15/15] devicetree: bindings: Document qcom,pvs
From: Rob Herring @ 2017-12-27 21:58 UTC (permalink / raw)
To: Sricharan R
Cc: Mark Rutland, Rafael J. Wysocki,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Viresh Kumar, Michael Turquette, linux-pm, Stephen Boyd,
Russell King, linux-kernel@vger.kernel.org, David Brown,
linux-arm-msm, Andy Gross, open list:ARM/QUALCOMM SUPPORT,
linux-clk,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <4fdb2ab5-1dca-c44c-b647-3388a8ecea81@codeaurora.org>
On Wed, Dec 27, 2017 at 4:20 AM, Sricharan R <sricharan@codeaurora.org> wrote:
> Hi Rob,
>
> On 12/26/2017 11:06 PM, Rob Herring wrote:
>> On Thu, Dec 21, 2017 at 5:53 AM, Sricharan R <sricharan@codeaurora.org> wrote:
>>> Hi Rob,
>>>
>>> On 12/21/2017 2:48 AM, Rob Herring wrote:
>>>> On Wed, Dec 20, 2017 at 11:55:33AM +0530, Sricharan R wrote:
>>>>> Hi Viresh,
>>>>>
>>>>> On 12/20/2017 8:56 AM, Viresh Kumar wrote:
>>>>>> On 19-12-17, 21:25, Sricharan R wrote:
>>>>>>> + cpu@0 {
>>>>>>> + compatible = "qcom,krait";
>>>>>>> + enable-method = "qcom,kpss-acc-v1";
>>>>>>> + device_type = "cpu";
>>>>>>> + reg = <0>;
>>>>>>> + qcom,acc = <&acc0>;
>>>>>>> + qcom,saw = <&saw0>;
>>>>>>> + clocks = <&kraitcc 0>;
>>>>>>> + clock-names = "cpu";
>>>>>>> + cpu-supply = <&smb208_s2a>;
>>>>>>> + operating-points-v2 = <&cpu_opp_table>;
>>>>>>> + };
>>>>>>> +
>>>>>>> + qcom,pvs {
>>>>>>> + qcom,pvs-format-a;
>>>>>>> + };
>>>>>>
>>>>>> Not sure what Rob is going to say on that :)
>>>>>>
>>>>>
>>>>> Yes. Would be good to know the best way.
>>>>
>>>> Seems like this should be a property of an efuse node either implied by
>>>> the compatible or a separate property. What determines format A vs. B?
>>>>
>>>
>>> Yes, this efuse registers are part of the eeprom (qfprom) tied to the soc.
>>> So this property (details like bitfields and register offsets that it represents)
>>> can be put soc specific and nvmem apis can be used to read
>>> the registers. Does something like below look ok ?
>>>
>>> qcom,pvs {
>>> compatible = "qcom,pvs-ipq8064";
>>> nvmem-cells = <&pvs_efuse>;
>>> }
>>
>> Why do you need this node? It doesn't look like it corresponds to a
>> h/w block. It looks like you are just creating it to instantiate a
>> driver.
>>
>>> qfprom: qfprom@700000 {
>>> compatible = "qcom,qfprom";
>>
>> Either this or...
>>
>>> reg = <0x00700000 0x1000>;
>>> #address-cells = <1>;
>>> #size-cells = <1>;
>>> ranges;
>>> pvs_efuse: pvs {
>>
>> a compatible here should be specific enough so the OS can know what
>> the bits are.
>
> Infact the above "qcom,pvs" node is required mainly to act as a consumer
> for the nvmem data provider ("qcom,qfprom") (using nvmem-cells = <&pvs_efuse>)
> Then "qfprom" can be made to contain a "format_a" or "format_b" specific cell.
>
> So all that is needed is, nvmem-cells = <&pvs_efuse_phandle> needs to be available
> somewhere. The requirement is similar what is now done by "operating-points-v2-ti-cpu"
> and the ti-cpufreq.c. There "operating-points-v2-ti-cpu" node, contains the syscon
> register to read the efuse values. Similarly does defining a new
> "operating-points-v2-krait-cpu" which would contain the nvmem-cells property look ok ?
> This would avoid defining a new qcom,pvs node.
Yes, this seems reasonable.
>
> cpu@0 {
> compatible = "qcom,krait";
> enable-method = "qcom,kpss-acc-v1";
> device_type = "cpu";
> reg = <0>;
> qcom,acc = <&acc0>;
> qcom,saw = <&saw0>;
> clocks = <&kraitcc 0>;
> clock-names = "cpu";
> cpu-supply = <&smb208_s2a>;
> operating-points-v2 = <&cpu_opp_table>;
> };
>
> cpu_opp_table: opp_table {
> compatible = "operating-points-v2-krait-cpu";
>
> nvmem-cells = <&pvs_efuse_format_a>;
> /*
> * Missing opp-shared property means CPUs switch DVFS states
> * independently.
> */
>
> opp-1400000000 {
> opp-hz = /bits/ 64 <1400000000>;
> opp-microvolt-speed0-pvs0-v0 = <1250000>;
> opp-microvolt-speed0-pvs1-v0 = <1175000>;
> opp-microvolt-speed0-pvs2-v0 = <1125000>;
> opp-microvolt-speed0-pvs3-v0 = <1050000>;
>
> };
> ...
> }
>
> qfprom: qfprom@700000 {
> compatible = "qcom,qfprom";
> reg = <0x00700000 0x1000>;
> #address-cells = <1>;
> #size-cells = <1>;
> ranges;
> pvs_efuse_format_a: pvs {
> reg = <0xc0 0x8>;
> };
> }
>
> Regards,
> Sricharan
>
> --
> "QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply
* Re: [PATCH V8 3/3] OPP: Allow "opp-hz" and "opp-microvolt" to contain magic values
From: Rob Herring @ 2017-12-27 21:54 UTC (permalink / raw)
To: Viresh Kumar
Cc: Ulf Hansson, Kevin Hilman, Viresh Kumar, Nishanth Menon,
Stephen Boyd, Rafael Wysocki, linux-pm, Vincent Guittot,
Rajendra Nayak, Sudeep Holla,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-kernel@vger.kernel.org
In-Reply-To: <20171227085645.GF8312@vireshk-i7>
On Wed, Dec 27, 2017 at 2:56 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 26-12-17, 14:29, Rob Herring wrote:
>> On Mon, Dec 18, 2017 at 03:51:30PM +0530, Viresh Kumar wrote:
>
>> > +On some platforms the exact frequency or voltage may be hidden from the OS by
>> > +the firmware and the "opp-hz" or the "opp-microvolt" properties may contain
>> > +magic values that represent the frequency or voltage in a firmware dependent
>> > +way, for example an index of an array in the firmware.
>>
>> I'm still not convinced this is a good idea.
>
> You were kind-of a few days back :)
>
> lkml.kernel.org/r/CAL_JsqK-qtAaM_Ou5NtxcWR3F_q=8rMPJUm-VqGtKhbtWe5SAQ@mail.gmail.com
Yeah, well that was before Stephen said anything.
> So here is the deal:
>
> - I proposed "domain-performance-state" property for this stuff
> initially.
> - But Kevin didn't like that and proposed reusing "opp-hz" and
> "opp-microvolt", which we all agreed to multiple times..
> - And we are back to the same discussion now and its painful and time
> killing for all of us.
There's bigger issues than where we put magic values as I raised in
the other patch.
> TBH, I don't have too strong preferences about any of the suggestions
> you guys have and I need you guys to tell me what binding changes to
> do here and I will do that.
>
>> If you have firmware
>> partially managing things, then I think we should have platform specific
>> bindings or drivers.
>
> What about the initial idea then, like "performance-state" for the
> power domains ? All platforms will anyway replicate that binding only.
I don't really know. I don't really care either. I'll probably go
along with what everyone agrees to, but the only one I see any
agreement from is Ulf. Also, it is pretty vague as to what platforms
will use this. You claimed you can support QCom scenarios, but there's
really no evidence that that is true. What I don't want to see is this
merged and then we need something more yet again in a few months for
another platform.
Rob
^ permalink raw reply
* Re: [PATCH v4] hwrng: exynos - add Samsung Exynos True RNG driver
From: Philippe Ombredanne @ 2017-12-27 21:51 UTC (permalink / raw)
To: Łukasz Stelmach
Cc: Andrew F . Davis, PrasannaKumar Muralidharan, Rob Herring,
Matt Mackall, Herbert Xu, Krzysztof Kozlowski, Kukjin Kim,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-crypto-u79uwXL29TY76Z2rM5mHXA,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, LKML, Marek Szyprowski,
Bartlomiej Zolnierkiewicz
In-Reply-To: <87shbwh43f.fsf%l.stelmach-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Łukasz,
On Wed, Dec 27, 2017 at 11:12 AM, Łukasz Stelmach
<l.stelmach-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> It was <2017-12-22 pią 19:30>, when Philippe Ombredanne wrote:
>> On Fri, Dec 22, 2017 at 5:38 PM, Łukasz Stelmach <l.stelmach@samsung.com> wrote:
>>> It was <2017-12-22 pią 14:34>, when Philippe Ombredanne wrote:
>>>> Łukasz,
>>>>
>>>> On Fri, Dec 22, 2017 at 2:23 PM, Łukasz Stelmach <l.stelmach@samsung.com> wrote:
>>>>> Add support for True Random Number Generator found in Samsung Exynos
>>>>> 5250+ SoCs.
>>>>>
>>>>> Signed-off-by: Łukasz Stelmach <l.stelmach-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>>>>> Reviewed-by: Krzysztof Kozlowski <krzk-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>>>
>>>> <snip>
>>>>
>>>>> --- /dev/null
>>>>> +++ b/drivers/char/hw_random/exynos-trng.c
>>>>> @@ -0,0 +1,245 @@
>>>>> +/*
>>>>> + * RNG driver for Exynos TRNGs
>>>>> + *
>>>>> + * Author: Łukasz Stelmach <l.stelmach-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>>>>> + *
>>>>> + * Copyright 2017 (c) Samsung Electronics Software, Inc.
>>>>> + *
>>>>> + * Based on the Exynos PRNG driver drivers/crypto/exynos-rng by
>>>>> + * Krzysztof Kozłowski <krzk-DgEjT+Ai2ygdnm+yROfE0A@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 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.
>>>>> + */
>>>>
>>>>
>>>> Would you mind using the new SPDX tags documented in Thomas patch set
>>>> [1] rather than this fine but longer legalese?
>>>>
>>>> And if you could spread the word to others in your team this would be very nice.
>>>> See also this fine article posted by Mauro on the Samsung Open Source
>>>> Group Blog [2]
>>>> Thank you!
>>>
>>> Cool! We've been using SPDX to tag RPM packages in Tizen for three years or
>>> more. ;-)
>>
>> Very nice! any pubic pointers?
> ^^^^^
>
> I assume you request an URL of a publicly available web-page ;-)
>
> https://wiki.tizen.org/Packaging/Guidelines#License_Tag
Thank you!
I reckon it took me a minute to figure why you were making a somewhat
cryptic URL related comment.
Then I realized that I had made a rather unfortunate typo, or may be
it was a freudian slip of sorts :D
--
Cordially
Philippe Ombredanne
--
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] dt-bindings: media: Add Allwinner V3s Camera Sensor Interface (CSI)
From: Sakari Ailus @ 2017-12-27 21:47 UTC (permalink / raw)
To: Yong
Cc: maxime.ripard, Mauro Carvalho Chehab, Rob Herring, Mark Rutland,
Chen-Yu Tsai, Greg Kroah-Hartman, David S. Miller, Hans Verkuil,
Arnd Bergmann, Hugues Fruchet, Yannick Fertre, Philipp Zabel,
Benoit Parrot, Benjamin Gaignard, Jean-Christophe Trotin,
Ramesh Shanmugasundaram, Minghsiu Tsai, Krzysztof Kozlowski,
Robert
In-Reply-To: <20171221104935.663812085b616935ca3046de@magewell.com>
Hi Yong,
On Thu, Dec 21, 2017 at 10:49:35AM +0800, Yong wrote:
> Hi,
>
> On Tue, 19 Dec 2017 13:53:28 +0200
> Sakari Ailus <sakari.ailus@iki.fi> wrote:
>
> > Hi Yong,
> >
> > On Thu, Jul 27, 2017 at 01:01:36PM +0800, Yong Deng wrote:
> > > Add binding documentation for Allwinner V3s CSI.
> > >
> > > Signed-off-by: Yong Deng <yong.deng@magewell.com>
> >
> > DT bindings should precede the driver.
>
> OK.
>
> >
> > > ---
> > > .../devicetree/bindings/media/sun6i-csi.txt | 49 ++++++++++++++++++++++
> > > 1 file changed, 49 insertions(+)
> > > create mode 100644 Documentation/devicetree/bindings/media/sun6i-csi.txt
> > >
> > > diff --git a/Documentation/devicetree/bindings/media/sun6i-csi.txt b/Documentation/devicetree/bindings/media/sun6i-csi.txt
> > > new file mode 100644
> > > index 0000000..f8d83f6
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/sun6i-csi.txt
> > > @@ -0,0 +1,49 @@
> > > +Allwinner V3s Camera Sensor Interface
> > > +------------------------------
> > > +
> > > +Required properties:
> > > + - compatible: value must be "allwinner,sun8i-v3s-csi"
> >
> > What are sun6i and sun8i? Is this device first present in sun6i SoCs,
> > whereas you have only defined bindings for sun8i?
>
> Yes, some sun6i SoCs has the almost same CSI module.
> There is only V3s on my hand. So, I only tested it on V3s. But
> some people work on the others.
Ack.
>
> >
> > > + - reg: base address and size of the memory-mapped region.
> > > + - interrupts: interrupt associated to this IP
> > > + - clocks: phandles to the clocks feeding the CSI
> > > + * ahb: the CSI interface clock
> > > + * mod: the CSI module clock
> > > + * ram: the CSI DRAM clock
> > > + - clock-names: the clock names mentioned above
> > > + - resets: phandles to the reset line driving the CSI
> > > +
> > > +- ports: A ports node with endpoint definitions as defined in
> > > + Documentation/devicetree/bindings/media/video-interfaces.txt.
> >
> > Please document mandatory and optional endpoint properties relevant for the
> > hardware.
>
> I have added below commit in my v3:
> Currently, the driver only support the parallel interface. So, a single port
> node with one endpoint and parallel bus is supported.
Please specify the exact properties that are relevant for the hardware. No
references should be made to the driver, the bindings are entirely
separate.
Are the non-parallel (CSI-2?) and parallel bus on the same interface? If
yes, they should probably use different endpoints, if not, then different
ports.
You could document the other bus or omit it now altogether, in which case
you'd only detail the parallel bus properties here.
>
> >
> > > +
> > > +Example:
> > > +
> > > + csi1: csi@01cb4000 {
> > > + compatible = "allwinner,sun8i-v3s-csi";
> > > + reg = <0x01cb4000 0x1000>;
> > > + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
> > > + clocks = <&ccu CLK_BUS_CSI>,
> > > + <&ccu CLK_CSI1_SCLK>,
> > > + <&ccu CLK_DRAM_CSI>;
> > > + clock-names = "ahb", "mod", "ram";
> > > + resets = <&ccu RST_BUS_CSI>;
> > > +
> > > + port {
> > > + #address-cells = <1>;
> > > + #size-cells = <0>;
> > > +
> > > + /* Parallel bus endpoint */
> > > + csi1_ep: endpoint {
> > > + remote-endpoint = <&adv7611_ep>;
> > > + bus-width = <16>;
> > > + data-shift = <0>;
> > > +
> > > + /* If hsync-active/vsync-active are missing,
> > > + embedded BT.656 sync is used */
> > > + hsync-active = <0>; /* Active low */
> > > + vsync-active = <0>; /* Active low */
> > > + data-active = <1>; /* Active high */
> > > + pclk-sample = <1>; /* Rising */
> > > + };
> > > + };
> > > + };
> > > +
> >
> > --
> > Kind regards,
> >
> > Sakari Ailus
> > e-mail: sakari.ailus@iki.fi
>
>
> Thanks,
> Yong
--
Regards,
Sakari Ailus
e-mail: sakari.ailus@iki.fi
^ permalink raw reply
* Re: [PATCH 2/3] dt-bindings: mtd: atmel-quadspi: add an optional property 'dmacap,memcpy'
From: Cyrille Pitchen @ 2017-12-27 21:40 UTC (permalink / raw)
To: Rob Herring, Ludovic Desroches
Cc: computersforpeace-Re5JQEeQqe8AvxtiuMwx3w,
dwmw2-wEGCiKHe2LqWVfeAwA7xHQ, richard-/L3Ra7n9ekc,
boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
marek.vasut-Re5JQEeQqe8AvxtiuMwx3w,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
broonie-DgEjT+Ai2ygdnm+yROfE0A, vigneshr-l0cyMroinI0,
linux-I+IVW8TIWO2tmTQ+vhA3Yw, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
nicolas.ferre-UWL1GkI3JZL3oGB3hsPCZA,
radu.pirea-UWL1GkI3JZL3oGB3hsPCZA
In-Reply-To: <20171226232330.trljk2ofyvu4ly3n@rob-hp-laptop>
Hi Rob,
+ Ludovic Desroches, maintainer of the DMA controller drivers for AT91 SoCs.
Le 27/12/2017 à 00:23, Rob Herring a écrit :
> On Sun, Dec 24, 2017 at 05:36:05AM +0100, Cyrille Pitchen wrote:
>> The optional 'dmacap,memcpy' DT property tells the Atmel QSPI controller
>> driver to reserve some DMA channel then to use it to perform DMA
>> memcpy() during data transfers. This feature relies on the generic
>> bounce buffer helper from spi-nor.c.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen-yU5RGvR974pGWvitb5QawA@public.gmane.org>
>> ---
>> Documentation/devicetree/bindings/mtd/atmel-quadspi.txt | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
>> index b93c1e2f25dd..002d3f0a445b 100644
>> --- a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
>> +++ b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
>> @@ -12,6 +12,10 @@ Required properties:
>> - #address-cells: Should be <1>.
>> - #size-cells: Should be <0>.
>>
>> +Optional properties:
>> +- dmacap,memcpy: Reserve a DMA channel to perform DMA memcpy() between the
>> + system memory and the QSPI mapped memory.
>
> How is this a h/w property? Why would I not want to always enable DMA if
> possible?
The number of DMA channels is limited for a given SoC. This number may be
lower than the number of enabled controllers (spi, i2c, qspi, aes, sha,
des, sdmmc, usart, ...).
So we use a DT property to explicitly tell the matching drivers to request
and reserved the DMA channels they need. This policy is not driver or even
SoC specific but board specific. It's very common to reserved DMA channels
for the most used or most performance dependent controllers, setting the
relevant properties in the device-tree then restricting remaining
controllers to their PIO mode.
>
> Furthermore, you are reusing a property, but giving it a different
> meaning. The current definition is an indication whether a DMA
> controller supports memcpy operations or not. It is not a flag for
> clients to use memcpy channels.
>
I don't mind changing the name. I thought it would be better to use some
existing one than creating another. However I was not confident on whether
"dmacap,memcpy" was actually a good candidate for what I do in the DMA
patch for the atmel-quadspi.c driver.
Actually, I was relying on your feedbacks :)
> Why don't you use "dmas" property to point to the DMA controller.
I didn't use the "dmas" property because I thought it would not have been
consistent with how this property is used in all other nodes of the sama5*
device-trees. The flags provided in the dma-cells are designed for "memory
to peripheral" or "peripheral to memory" DMA transfers only.
However, here I need to perform some "memory to memory" transfer: the SPI
NOR flash memory is mapped into the AHB bus of SAMA5D2 SoCs. Besides,
once in Serial Memory Mode, data can no longer be transfered through the
TDR or RDR registers of the QSPI controller, only through its AHB mapped
memory window.
So I cannot configured the DMA channel for "peripheral to memory" or
"memory to peripheral" like for other controllers embedded in the SoC but
only for "memory to memory".
Maybe we could extend the flags supported by the "dmas" property but I
guess it may require some little rework in the at_xdmac_xlate() function
of the at_xdmac.c driver.
Or maybe no change at all is required at the at_xdmac.c driver side: we
just don't care about the provided flags in the "dmas" property, especially
the "peripheral id". They would be ignored anyway when the atmel-quadspi.c
driver later calls dmaengine_prep_dma_memcpy(). So I could simply set the
dma cells to 0 in the device-tree?
Ludovic, what do you think about that ?
Best regards,
Cyrille
>
>> +
>> Example:
>>
>> spi@f0020000 {
>> @@ -24,6 +28,7 @@ spi@f0020000 {
>> #size-cells = <0>;
>> pinctrl-names = "default";
>> pinctrl-0 = <&pinctrl_spi0_default>;
>> + dmacap,memcpy;
>>
>> m25p80@0 {
>> ...
>> --
>> 2.11.0
>>
>> --
>> 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
>
--
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
* Re: [RFC V7 2/2] OPP: Allow "opp-hz" and "opp-microvolt" to contain magic values
From: Rob Herring @ 2017-12-27 21:36 UTC (permalink / raw)
To: Viresh Kumar
Cc: Stephen Boyd, Ulf Hansson, Kevin Hilman, Viresh Kumar,
Nishanth Menon, Rafael Wysocki,
linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Vincent Guittot,
Rajendra Nayak, Sudeep Holla,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20171227044526.GE8312@vireshk-i7>
On Tue, Dec 26, 2017 at 10:45 PM, Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On 26-12-17, 14:23, Rob Herring wrote:
>> > cpu_opp_table: cpu_opp_table {
>> > compatible = "operating-points-v2";
>> > opp-shared;
>> >
>> > opp00 {
>> > opp-hz = /bits/ 64 <208000000>;
>> > clock-latency-ns = <500000>;
>> > power-domain-opp = <&domain_opp_1>;
>>
>> What is this? opp00 here is not a device. One OPP should not point to
>> another. "power-domain-opp" is only supposed to appear in devices
>> alongside power-domains properties.
>
> There are two type of devices:
>
> A.) With fixed performance state requirements and they will have the
> new "required-opp" property in the device node itself as you said.
>
> B.) Devices which can do DVFS (CPU, MMC, LCD, etc) and those may need
> a different performance state of the domain for their individual OPPs
> and so we can't have this property in the device all the time.
>
> Does this make sense ?
No. From the definition for power-domain-opp
"+- power-domain-opp: This contains phandle to one of the OPP nodes of
the master
+ power domain. This specifies the minimum required OPP of the master
domain for
+ the functioning of the device in this OPP (where this property is present).
+ This property can only be set for a device if the device node contains the
+ "power-domains" property. Also, either all or none of the OPP nodes in an OPP
+ table should have it set."
In the above example, you are violating the next to last sentence.
Though, I'm now confused by what the last sentence means.
Rob
--
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] dt: bindings: as3645a: Fix the example node
From: Pavel Machek @ 2017-12-27 21:19 UTC (permalink / raw)
To: Rob Herring
Cc: Dan Murphy, Mark Rutland, Richard Purdie, Jacek Anaszewski,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Linux LED Subsystem
In-Reply-To: <CAL_JsqKG2TWLTREqNecy_3pOqLFJWa4SM4G4yzyKsZqW7opDvw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1622 bytes --]
On Thu 2017-12-07 09:42:29, Rob Herring wrote:
> On Wed, Dec 6, 2017 at 4:32 PM, Dan Murphy <dmurphy@ti.com> wrote:
> > Rob
> >
> > On 12/06/2017 03:52 PM, Rob Herring wrote:
> >> On Tue, Dec 05, 2017 at 07:36:37AM -0600, Dan Murphy wrote:
> >>> Fix the address-cells and size-cells example node
> >>> to reflect to the correct representation.
> >>>
> >>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
> >>> ---
> >>> Documentation/devicetree/bindings/leds/ams,as3645a.txt | 4 ++--
> >>> 1 file changed, 2 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/leds/ams,as3645a.txt b/Documentation/devicetree/bindings/leds/ams,as3645a.txt
> >>> index fdc40e354a64..8a49ccfec29b 100644
> >>> --- a/Documentation/devicetree/bindings/leds/ams,as3645a.txt
> >>> +++ b/Documentation/devicetree/bindings/leds/ams,as3645a.txt
> >>> @@ -59,8 +59,8 @@ Example
> >>> =======
> >>>
> >>> as3645a@30 {
> >>> - #address-cells: 1
> >>> - #size-cells: 0
> >>> + #address-cells = <1>;
> >>> + #size-cells = <0>;
> >>> reg = <0x30>;
> >>> compatible = "ams,as3645a";
> >>
> >> Convention is also we put compatible first.
> >>
> >
> > OK I will move that too for v2.
> >
> > Can that be in the same patch or do you want a separate patch?
>
> Same patch is fine.
For fixed patch:
Signed-off-by: Pavel Machek <pavel@ucw.cz>
Thanks,
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 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