* [PATCH] drivers: mfd: ti_am335x_tscadc: increase ADC ref clock to 24MHz
From: Vignesh R @ 2016-10-31 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <A5F6974F-5793-4E85-BF82-2D9309980991@gmail.com>
On Friday 28 October 2016 02:47 AM, John Syne wrote:
>>>>>>>>>>
>>>>>>>>>> ---
>>>>>>>>>> include/linux/mfd/ti_am335x_tscadc.h | 4 ++--
>>>>>>>>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>>>>>>>>
>>>>>>>>>> diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
>>>>>>>>>> index b9a53e0..96c4207 100644
>>>>>>>>>> --- a/include/linux/mfd/ti_am335x_tscadc.h
>>>>>>>>>> +++ b/include/linux/mfd/ti_am335x_tscadc.h
>>>>>>>>>> @@ -90,7 +90,7 @@
>>>>>>>>>> /* Delay register */
>>>>>>>>>> #define STEPDELAY_OPEN_MASK (0x3FFFF << 0)
>>>>>>>>>> #define STEPDELAY_OPEN(val) ((val) << 0)
>>>>>>>>>> -#define STEPCONFIG_OPENDLY STEPDELAY_OPEN(0x098)
>>>>>>>> Wouldn?t this be better to add this to the devicetree?
>>>>>>>>
>>>>>>>> ti,chan-step-avg = <0x16 0x16 0x16 0x16 0x16 0x16 0x16>;
>>>>>>>> ti,chan-step-opendelay = <0x500 0x500 0x500 0x500 0x500 0x500 0x500>;
>>>>>>>> ti,chan-step-sampledelay = <0x0 0x0 0x0 0x0 0x0 0x0 0x0>;
>>>>>>>
>>>>>>> For a touch screen, there is not need to change in these parameter
>>>>>>> settings, so my opinion is to keep it as is. Or am I missing something?
>>>>>> I was thinking that if you are using this driver as an ADC, you may want the flexibility to make these changes in the DT. I?m doing this by connecting sensors to the ADC inputs. I?m not using this driver for a touchscreen.
>>>>>
>>>>> Here is a DT overlay were this gets using on the BeagleBoneBlack.
>>>>>
>>>>> https://github.com/RobertCNelson/bb.org-overlays/blob/master/src/arm/BB-ADC-00A0.dts
>>>>>
>>>>> Besides, these DT features are already implemented in the driver so it is just a matter of adding these entries to the am33xx.dtsi & am4372.dtsi, which you modified in this patch series.
>>>>
>>>> This looks like configuration, no?
>>>>
>>>> DT should be used to describe the hardware.
>>> You may be right, but how is this different to setting the baud rate on a serial channel or sampling rate on a audio channel? Looking through the DT, there are many configuration settings, so I?m not sure what is the correct way to handle this. Surely it is better to handle this in DT vs hard coding these settings?
>>
>> I think setting the UART baud rate is also an invalid DT entry.
>>
>> It's okay to list all of the options in DT, but to actually select
>> one, that should be done either in userspace or as a kernel option.
>> Perhaps as a Kconfig selection.
> Yeah, this has been inconsistent for a long time. My only point was that these DT parameters had already been implemented in the ti_am335x_adc KM and I thought that this was better than hard coding these settings. Implementing this in Kconfig means rebuilding the KM, which isn?t desirable.
>Perhaps this should be done via sysfs attributes so as you say, a userspace app can configure this driver.
This was discussed when DT properties were added. Patches are welcome
to add sysfs entries. There is nothing wrong with specifying an initial
value in the DT.
>I guess the DT code in ti_am335x_adc.c should be removed.
>
Removing DT properties is not an option as it will break DT backward
compatibility.
--
Regards
Vignesh
^ permalink raw reply
* [PATCH v7 1/4] ARM: davinci: da8xx: Add USB PHY platform declaration
From: Sekhar Nori @ 2016-10-31 11:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477527498-21930-2-git-send-email-david@lechnology.com>
On Thursday 27 October 2016 05:48 AM, David Lechner wrote:
> There is now a proper phy driver for the DA8xx SoC USB PHY. This adds the
> platform device declarations needed to use it.
>
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
>
> Updated this patch so that it applies/builds cleanly before "ARM: davinci:
> da8xx: add usb phy clocks" since that patch now uses da8xx_usb_phy from this
> patch.
>
>
> arch/arm/mach-davinci/board-da830-evm.c | 22 +++++++---------------
> arch/arm/mach-davinci/board-omapl138-hawk.c | 5 +++++
> arch/arm/mach-davinci/include/mach/da8xx.h | 1 +
> arch/arm/mach-davinci/usb-da8xx.c | 11 +++++++++++
> 4 files changed, 24 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
> index 2a96b40..829f68d 100644
> --- a/arch/arm/mach-davinci/board-da830-evm.c
> +++ b/arch/arm/mach-davinci/board-da830-evm.c
> @@ -26,7 +26,6 @@
> #include <linux/platform_data/mtd-davinci.h>
> #include <linux/platform_data/mtd-davinci-aemif.h>
> #include <linux/platform_data/spi-davinci.h>
> -#include <linux/platform_data/usb-davinci.h>
I applied this patch, but did not drop this include. usb-davinci.h
provides the definition of da8xx_ohci_root_hub which is still used in
this file. I guess it did not lead to a build error because the file is
still getting included indirectly. But I rather prefer a direct include
of this file.
Attached is the patch I applied for reference.
Thanks,
Sekhar
---8<---
>From 00e69229147533769df8637ff4d4bb098150e325 Mon Sep 17 00:00:00 2001
From: David Lechner <david@lechnology.com>
Date: Wed, 26 Oct 2016 19:18:15 -0500
Subject: [PATCH] ARM: davinci: da8xx: Add USB PHY platform device
There is now a proper phy driver for the DA8xx SoC USB PHY. This adds the
platform device declarations needed to use it.
Signed-off-by: David Lechner <david@lechnology.com>
[nsekhar at ti.com: keep usb-davinci.h included in board-da830-evm.c
minor subject line adjustment]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
arch/arm/mach-davinci/board-da830-evm.c | 21 +++++++--------------
arch/arm/mach-davinci/board-omapl138-hawk.c | 5 +++++
arch/arm/mach-davinci/include/mach/da8xx.h | 1 +
arch/arm/mach-davinci/usb-da8xx.c | 11 +++++++++++
4 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index 6001b32305ec..53172add5248 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -112,7 +112,7 @@ static __init void da830_evm_usb_init(void)
int ret;
/*
- * Set up USB clock/mode in the CFGCHIP2 register.
+ * Set up USB clock in the CFGCHIP2 register.
* FYI: CFGCHIP2 is 0x0000ef00 initially.
*/
cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
@@ -129,22 +129,15 @@ static __init void da830_evm_usb_init(void)
cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX;
- /*
- * We have to override VBUS/ID signals when MUSB is configured into the
- * host-only mode -- ID pin will float if no cable is connected, so the
- * controller won't be able to drive VBUS thinking that it's a B-device.
- * Otherwise, we want to use the OTG mode and enable VBUS comparators.
- */
- cfgchip2 &= ~CFGCHIP2_OTGMODE_MASK;
-#ifdef CONFIG_USB_MUSB_HOST
- cfgchip2 |= CFGCHIP2_FORCE_HOST;
-#else
- cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
-#endif
-
__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
/* USB_REFCLKIN is not used. */
+
+ ret = da8xx_register_usb_phy();
+ if (ret)
+ pr_warn("%s: USB PHY registration failed: %d\n",
+ __func__, ret);
+
ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
if (ret)
pr_warn("%s: USB 2.0 PinMux setup failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 70ed5ef2ef8c..67477ca4f15a 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -260,6 +260,11 @@ static __init void omapl138_hawk_usb_init(void)
cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ ret = da8xx_register_usb_phy();
+ if (ret)
+ pr_warn("%s: USB PHY registration failed: %d\n",
+ __func__, ret);
+
ret = gpio_request_one(DA850_USB1_VBUS_PIN,
GPIOF_DIR_OUT, "USB1 VBUS");
if (ret < 0) {
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 2f6fe2f0c733..5e07d06f60e4 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -89,6 +89,7 @@ int da850_register_edma(struct edma_rsv_info *rsv[2]);
int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
int da8xx_register_spi_bus(int instance, unsigned num_chipselect);
int da8xx_register_watchdog(void);
+int da8xx_register_usb_phy(void);
int da8xx_register_usb20(unsigned mA, unsigned potpgt);
int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
int da8xx_register_emac(void);
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index f141f5171906..4bb190380060 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -3,6 +3,7 @@
*/
#include <linux/dma-mapping.h>
#include <linux/init.h>
+#include <linux/phy/phy.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_device.h>
#include <linux/usb/musb.h>
@@ -15,6 +16,16 @@
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
+static struct platform_device da8xx_usb_phy = {
+ .name = "da8xx-usb-phy",
+ .id = -1,
+};
+
+int __init da8xx_register_usb_phy(void)
+{
+ return platform_device_register(&da8xx_usb_phy);
+}
+
#if IS_ENABLED(CONFIG_USB_MUSB_HDRC)
static struct musb_hdrc_config musb_config = {
--
2.9.0
^ permalink raw reply related
* [PATCH v7 2/4] ARM: davinci: da8xx: Add USB device names to clock lookup tables
From: Sekhar Nori @ 2016-10-31 11:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477527498-21930-3-git-send-email-david@lechnology.com>
On Thursday 27 October 2016 05:48 AM, David Lechner wrote:
> This adds device names for the SoC USB devices to the clock lookup tables
> in da830.c and da850.c.
>
> Also add the USB device names to the da850_auxdata_lookup[] table.
>
> Signed-off-by: David Lechner <david@lechnology.com>
Applied to v4.10/soc
Thanks,
Sekhar
^ permalink raw reply
* [PATCH 1/3] Documentation: dt: Add TI SCI clock driver
From: Tero Kristo @ 2016-10-31 12:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161030204121.qvb5d33dh65awwzx@rob-hp-laptop>
On 30/10/16 22:41, Rob Herring wrote:
> On Fri, Oct 21, 2016 at 03:45:59PM +0300, Tero Kristo wrote:
>> Add a clock implementation, TI SCI clock, that will hook to the common
>> clock framework, and allow each clock to be controlled via TI SCI
>> protocol.
>>
>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>> ---
>> .../devicetree/bindings/clock/ti,sci-clk.txt | 37 ++++++++++++++++++++++
>> MAINTAINERS | 1 +
>> 2 files changed, 38 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>> new file mode 100644
>> index 0000000..bfc3ca4
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>> @@ -0,0 +1,37 @@
>> +Texas Instruments TI-SCI Clocks
>> +===============================
>> +
>> +All clocks on Texas Instruments' SoCs that contain a System Controller,
>> +are only controlled by this entity. Communication between a host processor
>> +running an OS and the System Controller happens through a protocol known
>> +as TI-SCI[1]. This clock implementation plugs into the common clock
>> +framework and makes use of the TI-SCI protocol on clock API requests.
>> +
>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>> +
>> +Required properties:
>> +-------------------
>> +- compatible: Must be "ti,k2g-sci-clk"
>> +- #clock-cells: Shall be 2.
>> + In clock consumers, this cell represents the device ID and clock ID
>> + exposed by the PM firmware. The assignments can be found in the header
>> + files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
>> + <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
>> + is the SoC involved, for example 'k2g'.
>> +
>> +Examples:
>> +--------
>> +
>> +pmmc: pmmc {
>> + compatible = "ti,k2g-sci";
>> +
>> + k2g_clks: k2g_clks {
>
> Use "clocks" for node name instead.
>
>> + compatible = "ti,k2g-sci-clk";
>
> I'm starting to think all these child nodes for SCI are pointless. Is
> there any reason why the parent node can't be the clock provider (along
> with all the other providers it acks as)?
I believe the only reason to keep them separate is to have kernel side
of things modular. If we have separate nodes, the drivers can be probed
separately.
If not, we need to build one huge blob with all the features in it, so
the main driver can probe everything in one go, with annoying
back-and-forth callbacks in place (assuming we still want to keep stuff
somehow modular.)
-Tero
>
>> + #clock-cells = <2>;
>> + };
>> +};
>> +
>> +uart0: serial at 2530c00 {
>> + compatible = "ns16550a";
>> + clocks = <&k2g_clks K2G_DEV_UART0 0>;
>> +};
^ permalink raw reply
* [PATCH] ARM: mediatek: clean up mach-mediatek/Makefile
From: Masahiro Yamada @ 2016-10-31 13:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474222273-23116-1-git-send-email-yamada.masahiro@socionext.com>
Hi Matthias,
Can you pick up this for your next pull request?
2016-09-19 3:11 GMT+09:00 Masahiro Yamada <yamada.masahiro@socionext.com>:
> Kbuild descends into arch/arm/mach-mediatek/Makefile only when
> CONFIG_ARCH_MEDIATEK is enabled. So, obj-$(CONFIG_ARCH_MEDIATEK)
> is always equivalent to obj-y in this Makefile.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
> ---
>
> arch/arm/mach-mediatek/Makefile | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
> index 2116460..dadae67 100644
> --- a/arch/arm/mach-mediatek/Makefile
> +++ b/arch/arm/mach-mediatek/Makefile
> @@ -1,4 +1,2 @@
> -ifeq ($(CONFIG_SMP),y)
> -obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
> -endif
> -obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
> +obj-$(CONFIG_SMP) += platsmp.o
> +obj-y += mediatek.o
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Best Regards
Masahiro Yamada
^ permalink raw reply
* [PATCH] ARM: mm: add ARM_L1_CACHE_SHIFT_7 for UniPhier outer cache
From: Masahiro Yamada @ 2016-10-31 13:32 UTC (permalink / raw)
To: linux-arm-kernel
The UniPhier outer cache (arch/arm/mm/cache-uniphier.c) has 128 byte
line length and its tags are also managed per 128 byte line. This
is very unfortunate, but the current 64 byte alignment for kmalloc()
causes sharing problems on DMA if used with this outer cache.
This commit adds ARM_L1_CACHE_SHIFT_7 to increase the DMA minimum
alignment to 128 byte if CACHE_UNIPHIER is enabled. There are
several drivers that assume aligning to L1_CACHE_BYTES will be DMA
safe, so this commit also changes the L1_CACHE_BYTES for safety.
Having said that, I hesitate to align all the other SoCs in Multi
platform to the UniPhier's requirement. So, I am disabling the
CONFIG_CACHE_UNIPHIER by default, so that multi_v7_defconfig will
still stay with CONFIG_ARM_L1_CACHE_SHIFT=6. With this commit,
UniPhier SoCs will become slower, but it is much better than system
crash. If desired, the outer-cache can be enabled by merge_config
or something.
Note:
The UniPhier PH1-Pro5 SoC is equipped also with L3 cache with 256
byte line size but its tags are managed per 128 byte sub-line.
So, ARM_L1_CACHE_SHIFT_7 should be fine for all the UniPhier SoCs.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
Kernel Version: 4.9-rc1
arch/arm/mm/Kconfig | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c1799dd..f68e8ec 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -991,7 +991,7 @@ config CACHE_TAUROS2
config CACHE_UNIPHIER
bool "Enable the UniPhier outer cache controller"
depends on ARCH_UNIPHIER
- default y
+ select ARM_L1_CACHE_SHIFT_7
select OUTER_CACHE
select OUTER_CACHE_SYNC
help
@@ -1012,8 +1012,14 @@ config ARM_L1_CACHE_SHIFT_6
help
Setting ARM L1 cache line size to 64 Bytes.
+config ARM_L1_CACHE_SHIFT_7
+ bool
+ help
+ Setting ARM L1 cache line size to 128 Bytes.
+
config ARM_L1_CACHE_SHIFT
int
+ default 7 if ARM_L1_CACHE_SHIFT_7
default 6 if ARM_L1_CACHE_SHIFT_6
default 5
--
1.9.1
^ permalink raw reply related
* [PATCH] ARM: mm: add ARM_L1_CACHE_SHIFT_7 for UniPhier outer cache
From: Masahiro Yamada @ 2016-10-31 13:37 UTC (permalink / raw)
To: linux-arm-kernel
The UniPhier outer cache (arch/arm/mm/cache-uniphier.c) has 128 byte
line length and its tags are also managed per 128 byte line. This
is very unfortunate, but the current 64 byte alignment for kmalloc()
causes sharing problems on DMA if used with this outer cache.
This commit adds ARM_L1_CACHE_SHIFT_7 to increase the DMA minimum
alignment to 128 byte if CACHE_UNIPHIER is enabled. There are
several drivers that assume aligning to L1_CACHE_BYTES will be DMA
safe, so this commit also changes the L1_CACHE_BYTES for safety.
Having said that, I hesitate to align all the other SoCs in Multi
platform to the UniPhier's requirement. So, I am disabling the
CONFIG_CACHE_UNIPHIER by default, so that multi_v7_defconfig will
still stay with CONFIG_ARM_L1_CACHE_SHIFT=6. With this commit,
UniPhier SoCs will become slower, but it is much better than system
crash. If desired, the outer-cache can be enabled by merge_config
or something.
Note:
The UniPhier PH1-Pro5 SoC is equipped also with L3 cache with 256
byte line size but its tags are managed per 128 byte sub-line.
So, ARM_L1_CACHE_SHIFT_7 should be fine for all the UniPhier SoCs.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
KernelVersion: 4.9-rc1
arch/arm/mm/Kconfig | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c1799dd..f68e8ec 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -991,7 +991,7 @@ config CACHE_TAUROS2
config CACHE_UNIPHIER
bool "Enable the UniPhier outer cache controller"
depends on ARCH_UNIPHIER
- default y
+ select ARM_L1_CACHE_SHIFT_7
select OUTER_CACHE
select OUTER_CACHE_SYNC
help
@@ -1012,8 +1012,14 @@ config ARM_L1_CACHE_SHIFT_6
help
Setting ARM L1 cache line size to 64 Bytes.
+config ARM_L1_CACHE_SHIFT_7
+ bool
+ help
+ Setting ARM L1 cache line size to 128 Bytes.
+
config ARM_L1_CACHE_SHIFT
int
+ default 7 if ARM_L1_CACHE_SHIFT_7
default 6 if ARM_L1_CACHE_SHIFT_6
default 5
--
1.9.1
^ permalink raw reply related
* [PATCH] ARM: shmobile: r8a7779/marzen: Add board part number to DT bindings
From: Geert Uytterhoeven @ 2016-10-31 13:43 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Documentation/devicetree/bindings/arm/shmobile.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt
index 44b3129a8ded539b..d2e408795889fbec 100644
--- a/Documentation/devicetree/bindings/arm/shmobile.txt
+++ b/Documentation/devicetree/bindings/arm/shmobile.txt
@@ -63,7 +63,7 @@ Boards:
compatible = "renesas,kzm9g", "renesas,sh73a0"
- Lager (RTP0RC7790SEB00010S)
compatible = "renesas,lager", "renesas,r8a7790"
- - Marzen
+ - Marzen (R0P7779A00010S)
compatible = "renesas,marzen", "renesas,r8a7779"
- Porter (M2-LCDP)
compatible = "renesas,porter", "renesas,r8a7791"
--
1.9.1
^ permalink raw reply related
* [crypto] [marvell-cesa] Possible regression after Linux 4.7
From: radioconfusion at gmail.com @ 2016-10-31 13:59 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
Fri, 09 Sep 2016 10:24:50 +0300, radioconfusion at gmail.com wrote:
> Thu, 8 Sep 2016 16:52:16 +0200, Romain Perier wrote:
> > > Hello,
> > >
> > > I'm testing the marvell-cesa -driver on Armada 385 board and I think I've found
> > > a regression between Linux 4.7 and 4.8-rc4.
> > > I want to accelerate my curl connections. So I compiled the 4.8-rc4 with
> > > marvell-cesa enabled and HEAD revision of cryptodev-linux.
> > >
> > > Here is my output:
> > >
> > > ~# uname -r
> > > 4.8.0-rc4
> > > ~# modprobe cryptodev
> > > ~# modprobe marvell-cesa
> > > ~# curl -k --ciphers AES256-SHA256 https://myserver/myfile >/dev/null
> > > % Total % Received % Xferd Average Speed Time Time Time Current
> > > Dload Upload Total Spent Left Speed
> > > 19 200M 19 39.7M 0 0 16.2M 0 0:00:12 0:00:02 0:00:10 16.2M
> > > curl: (56) SSL read: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption
> > > failed or bad record mac, errno 0
> > >
> --- snip ---
> >
> > Thank you for your feedbacks.
> > I can reproduce the issue with and without multiple engines.
I can still reproduce the issue with Linux 4.9-rc3 (2a26d99b251b8625d27aed14e97fc10707a3a81f)
> > However, I have found an interesting thing, If I use only --ciphers
> > AES256, it works perfectly fine, could you confirm this ?
>
> Yes, I can confirm. And I have found the reason too.
> Most of available ciphers will not be accelerated at all.
> Only these ones I have verified to be accelerated by cesa:
> AES256-SHA256
> AES256-SHA
> AES128-SHA256
> AES128-SHA
>
> When cesa is working, I can see "irq/42-f1090000" on process list of top(1) and
> curl doesn't take all of available cpu.
>
--- snip ---
> > In any case, I will investigate.
Do you have any improvement for the issue?
Please let me know if you need any help to resolve it.
Best Regards,
Jussi
^ permalink raw reply
* [PATCH v5 0/2] drm: tilcdc: improved support for rev1
From: Bartosz Golaszewski @ 2016-10-31 14:19 UTC (permalink / raw)
To: linux-arm-kernel
This series contains two patches needed to support revision 1 of the
LCD controller on da850 SoCs.
The first one implements palette loading - this is a resend of v4 of
the stand-alone patch.
The second resets the input FIFO in the DMA controller if a sync lost
error occurs and disables the interrupt completely if we're being
flooded with these errors.
v1 -> v2:
- only allocate dma memory for revision 1
v2 -> v3:
- use devres managed API for dma memory allocation
v3 -> v4:
- reinit the palette completion in tilcdc_crtc_disable()
v4 -> v5:
- add a second patch clearing the sync lost bit in case of a sync lost
error due to insufficient bandwidth
Bartosz Golaszewski (2):
drm: tilcdc: implement palette loading for rev1
drm: tilcdc: clear the sync lost bit in crtc isr
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 138 +++++++++++++++++++++++++++++++----
drivers/gpu/drm/tilcdc/tilcdc_regs.h | 1 +
2 files changed, 124 insertions(+), 15 deletions(-)
--
2.9.3
^ permalink raw reply
* [PATCH v5 1/2] drm: tilcdc: implement palette loading for rev1
From: Bartosz Golaszewski @ 2016-10-31 14:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477923567-1610-1-git-send-email-bgolaszewski@baylibre.com>
Revision 1 of the IP doesn't work if we don't load the palette (even
if it's not used, which is the case for the RGB565 format).
Add a function called from tilcdc_crtc_enable() which performs all
required actions if we're dealing with a rev1 chip.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 88 +++++++++++++++++++++++++++++++++++-
1 file changed, 87 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index db2f538..937697d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -21,11 +21,15 @@
#include <drm/drm_flip_work.h>
#include <drm/drm_plane_helper.h>
#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
#include "tilcdc_drv.h"
#include "tilcdc_regs.h"
-#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000
+#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000
+#define TILCDC_REV1_PALETTE_SIZE 32
+#define TILCDC_REV1_PALETTE_FIRST_ENTRY 0x4000
struct tilcdc_crtc {
struct drm_crtc base;
@@ -53,6 +57,10 @@ struct tilcdc_crtc {
int sync_lost_count;
bool frame_intact;
+
+ dma_addr_t palette_dma_handle;
+ void *palette_base;
+ struct completion palette_loaded;
};
#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
@@ -98,6 +106,55 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
tilcdc_crtc->curr_fb = fb;
}
+/*
+ * The driver currently only supports the RGB565 format for revision 1. For
+ * 16 bits-per-pixel the palette block is bypassed, but the first 32 bytes of
+ * the framebuffer are still considered palette. The first 16-bit entry must
+ * be 0x4000 while all other entries must be zeroed.
+ */
+static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
+{
+ u32 dma_fb_base, dma_fb_ceiling, raster_ctl;
+ struct tilcdc_crtc *tilcdc_crtc;
+ struct drm_device *dev;
+ u16 *first_entry;
+
+ dev = crtc->dev;
+ tilcdc_crtc = to_tilcdc_crtc(crtc);
+ first_entry = tilcdc_crtc->palette_base;
+
+ *first_entry = TILCDC_REV1_PALETTE_FIRST_ENTRY;
+
+ dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG);
+ dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG);
+ raster_ctl = tilcdc_read(dev, LCDC_RASTER_CTRL_REG);
+
+ /* Tell the LCDC where the palette is located. */
+ tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG,
+ tilcdc_crtc->palette_dma_handle);
+ tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG,
+ (u32)tilcdc_crtc->palette_dma_handle
+ + TILCDC_REV1_PALETTE_SIZE - 1);
+
+ /* Load it. */
+ tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
+ LCDC_PALETTE_LOAD_MODE(DATA_ONLY));
+ tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
+ LCDC_PALETTE_LOAD_MODE(PALETTE_ONLY));
+
+ /* Enable the LCDC and wait for palette to be loaded. */
+ tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
+ tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+
+ wait_for_completion(&tilcdc_crtc->palette_loaded);
+
+ /* Restore the registers. */
+ tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+ tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_fb_base);
+ tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, dma_fb_ceiling);
+ tilcdc_write(dev, LCDC_RASTER_CTRL_REG, raster_ctl);
+}
+
static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
{
struct tilcdc_drm_private *priv = dev->dev_private;
@@ -152,6 +209,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
+ struct tilcdc_drm_private *priv = dev->dev_private;
WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
@@ -162,6 +220,9 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
reset(crtc);
+ if (priv->rev == 1 && !completion_done(&tilcdc_crtc->palette_loaded))
+ tilcdc_crtc_load_palette(crtc);
+
tilcdc_crtc_enable_irqs(dev);
tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE);
@@ -200,6 +261,13 @@ void tilcdc_crtc_disable(struct drm_crtc *crtc)
__func__);
}
+ /*
+ * LCDC will not retain the palette when reset. Make sure it gets
+ * reloaded on tilcdc_crtc_enable().
+ */
+ if (priv->rev == 1)
+ reinit_completion(&tilcdc_crtc->palette_loaded);
+
drm_crtc_vblank_off(crtc);
tilcdc_crtc_disable_irqs(dev);
@@ -802,6 +870,14 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow",
__func__, stat);
+ if (priv->rev == 1) {
+ if (stat & LCDC_PL_LOAD_DONE) {
+ complete(&tilcdc_crtc->palette_loaded);
+ tilcdc_clear(dev,
+ LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
+ }
+ }
+
/* For revision 2 only */
if (priv->rev == 2) {
if (stat & LCDC_FRAME_DONE) {
@@ -843,6 +919,16 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
return NULL;
}
+ if (priv->rev == 1) {
+ init_completion(&tilcdc_crtc->palette_loaded);
+ tilcdc_crtc->palette_base = dmam_alloc_coherent(dev->dev,
+ TILCDC_REV1_PALETTE_SIZE,
+ &tilcdc_crtc->palette_dma_handle,
+ GFP_KERNEL | __GFP_ZERO);
+ if (!tilcdc_crtc->palette_base)
+ return ERR_PTR(-ENOMEM);
+ }
+
crtc = &tilcdc_crtc->base;
ret = tilcdc_plane_init(dev, &tilcdc_crtc->primary);
--
2.9.3
^ permalink raw reply related
* [PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr
From: Bartosz Golaszewski @ 2016-10-31 14:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477923567-1610-1-git-send-email-bgolaszewski@baylibre.com>
The frame synchronization error happens when the DMA engine attempts
to read what it believes to be the first word of the video buffer but
it cannot be recognized as such or when the LCDC is starved of data
due to insufficient bandwidth of the system interconnect.
On some SoCs (notably: da850) the memory settings do not meet the
LCDC throughput requirements even after increasing the memory
controller command re-ordering and the LDCD master peripheral
priority, sometimes causing the sync lost error (typically when
changing the resolution).
When the sync lost error occurs, simply reset the input FIFO in the
DMA controller unless a sync lost flood is detected in which case
disable the interrupt.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 50 ++++++++++++++++++++++++++----------
drivers/gpu/drm/tilcdc/tilcdc_regs.h | 1 +
2 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 937697d..c4c6323 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -163,7 +163,7 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
if (priv->rev == 1) {
tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
- LCDC_V1_UNDERFLOW_INT_ENA);
+ LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_SYNC_LOST_ENA);
tilcdc_set(dev, LCDC_DMA_CTRL_REG,
LCDC_V1_END_OF_FRAME_INT_ENA);
} else {
@@ -181,7 +181,9 @@ static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
/* disable irqs that we might have enabled: */
if (priv->rev == 1) {
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
- LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
+ LCDC_V1_UNDERFLOW_INT_ENA |
+ LCDC_V1_PL_INT_ENA |
+ LCDC_V1_SYNC_LOST_ENA);
tilcdc_clear(dev, LCDC_DMA_CTRL_REG,
LCDC_V1_END_OF_FRAME_INT_ENA);
} else {
@@ -885,24 +887,44 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
wake_up(&tilcdc_crtc->frame_done_wq);
}
- if (stat & LCDC_SYNC_LOST) {
- dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
- __func__, stat);
- tilcdc_crtc->frame_intact = false;
- if (tilcdc_crtc->sync_lost_count++ >
- SYNC_LOST_COUNT_LIMIT) {
- dev_err(dev->dev, "%s(0x%08x): Sync lost flood detected, disabling the interrupt", __func__, stat);
- tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
- LCDC_SYNC_LOST);
- }
- }
-
/* Indicate to LCDC that the interrupt service routine has
* completed, see 13.3.6.1.6 in AM335x TRM.
*/
tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
}
+ if (stat & LCDC_SYNC_LOST) {
+ dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
+ __func__, stat);
+
+ tilcdc_crtc->frame_intact = false;
+ if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) {
+ dev_err(dev->dev,
+ "%s(0x%08x): Sync lost flood detected, disabling the interrupt",
+ __func__, stat);
+ if (priv->rev == 2)
+ tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
+ LCDC_SYNC_LOST);
+ else if (priv->rev == 1)
+ tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
+ LCDC_V1_SYNC_LOST_ENA);
+ }
+
+ if (priv->rev == 2) {
+ /*
+ * Indicate to LCDC that the interrupt service routine
+ * has completed, see 13.3.6.1.6 in AM335x TRM.
+ */
+ tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
+ } else if (priv->rev == 1) {
+ /* Reset the input FIFO in the DMA controller. */
+ tilcdc_clear(dev,
+ LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+ tilcdc_set(dev,
+ LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+ }
+ }
+
return IRQ_HANDLED;
}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
index f57c0d6..beb8c21 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
@@ -61,6 +61,7 @@
#define LCDC_V2_UNDERFLOW_INT_ENA BIT(5)
#define LCDC_V1_PL_INT_ENA BIT(4)
#define LCDC_V2_PL_INT_ENA BIT(6)
+#define LCDC_V1_SYNC_LOST_ENA BIT(5)
#define LCDC_MONOCHROME_MODE BIT(1)
#define LCDC_RASTER_ENABLE BIT(0)
#define LCDC_TFT_ALT_ENABLE BIT(23)
--
2.9.3
^ permalink raw reply related
* [PATCH v1 2/3] nvmem: Add the Broadcom OTP controller driver
From: Srinivas Kandagatla @ 2016-10-31 14:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477336324-10543-3-git-send-email-jonathan.richardson@broadcom.com>
On 24/10/16 20:12, Jonathan Richardson wrote:
> From: Jonathan Richardson <jonathar@broadcom.com>
>
> Add support for 32 and 64-bit versions of Broadcom's On-Chip OTP
> controller. These controllers are used on SoC's such as Cygnus and
> Stingray.
>
> Reviewed-by: Ray Jui <ray.jui@broadcom.com>
> Tested-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> Signed-off-by: Scott Branden <scott.branden@broadcom.com>
> Signed-off-by: Oza Pawandeep <oza@broadcom.com>
> Signed-off-by: Jonathan Richardson <jonathan.richardson@broadcom.com>
> ---
> drivers/nvmem/Kconfig | 12 ++
> drivers/nvmem/Makefile | 2 +
> drivers/nvmem/bcm-ocotp.c | 335 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 349 insertions(+)
> create mode 100644 drivers/nvmem/bcm-ocotp.c
I can pick this patch along with dt bindings document, but dts patch has
to go via arm-soc tree.
Thanks,
srini
>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index ba140ea..06935a7 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -80,6 +80,18 @@ config ROCKCHIP_EFUSE
> This driver can also be built as a module. If so, the module
> will be called nvmem_rockchip_efuse.
>
> +config NVMEM_BCM_OCOTP
> + tristate "Broadcom On-Chip OTP Controller support"
> + depends on ARCH_BCM_IPROC || COMPILE_TEST
> + depends on HAS_IOMEM
> + default ARCH_BCM_IPROC
?
> + help
> + Say y here to enable read/write access to the Broadcom OTP
> + controller.
> +
> + This driver can also be built as a module. If so, the module
> + will be called nvmem-bcm-ocotp.
> +
> config NVMEM_SUNXI_SID
> tristate "Allwinner SoCs SID support"
> depends on ARCH_SUNXI
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index 8f942a0..71781ca 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -6,6 +6,8 @@ obj-$(CONFIG_NVMEM) += nvmem_core.o
> nvmem_core-y := core.o
>
> # Devices
> +obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o
> +nvmem-bcm-ocotp-y := bcm-ocotp.o
> obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o
> nvmem-imx-ocotp-y := imx-ocotp.o
> obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) += nvmem_lpc18xx_eeprom.o
> diff --git a/drivers/nvmem/bcm-ocotp.c b/drivers/nvmem/bcm-ocotp.c
> new file mode 100644
> index 0000000..646cadb
> --- /dev/null
> +++ b/drivers/nvmem/bcm-ocotp.c
> @@ -0,0 +1,335 @@
> +/*
> + * Copyright (C) 2016 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +
> +/*
> + * # of tries for OTP Status. The time to execute a command varies. The slowest
> + * commands are writes which also vary based on the # of bits turned on. Writing
> + * 0xffffffff takes ~3800 us.
> + */
> +#define OTPC_RETRIES 5000
> +
> +/* Sequence to enable OTP program */
> +#define OTPC_PROG_EN_SEQ { 0xf, 0x4, 0x8, 0xd }
> +
> +/* OTPC Commands */
> +#define OTPC_CMD_READ 0x0
> +#define OTPC_CMD_OTP_PROG_ENABLE 0x2
> +#define OTPC_CMD_OTP_PROG_DISABLE 0x3
> +#define OTPC_CMD_PROGRAM 0xA
> +
> +/* OTPC Status Bits */
> +#define OTPC_STAT_CMD_DONE BIT(1)
> +#define OTPC_STAT_PROG_OK BIT(2)
> +
> +/* OTPC register definition */
> +#define OTPC_MODE_REG_OFFSET 0x0
> +#define OTPC_MODE_REG_OTPC_MODE 0
> +#define OTPC_COMMAND_OFFSET 0x4
> +#define OTPC_COMMAND_COMMAND_WIDTH 6
> +#define OTPC_CMD_START_OFFSET 0x8
> +#define OTPC_CMD_START_START 0
> +#define OTPC_CPU_STATUS_OFFSET 0xc
> +#define OTPC_CPUADDR_REG_OFFSET 0x28
> +#define OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH 16
> +#define OTPC_CPU_WRITE_REG_OFFSET 0x2c
> +
> +#define OTPC_CMD_MASK (BIT(OTPC_COMMAND_COMMAND_WIDTH) - 1)
> +#define OTPC_ADDR_MASK (BIT(OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH) - 1)
> +
> +
> +struct otpc_map {
> + /* in words. */
> + u32 otpc_row_size;
> + /* 128 bit row / 4 words support. */
> + u16 data_r_offset[4];
> + /* 128 bit row / 4 words support. */
> + u16 data_w_offset[4];
> +};
> +
> +static struct otpc_map otp_map = {
> + .otpc_row_size = 1,
> + .data_r_offset = {0x10},
> + .data_w_offset = {0x2c},
> +};
> +
> +static struct otpc_map otp_map_v2 = {
> + .otpc_row_size = 2,
> + .data_r_offset = {0x10, 0x5c},
> + .data_w_offset = {0x2c, 0x64},
> +};
> +
> +struct otpc_priv {
> + struct device *dev;
> + void __iomem *base;
> + struct otpc_map *map;
> + struct nvmem_config *config;
> +};
> +
> +static inline void set_command(void __iomem *base, u32 command)
> +{
> + writel(command & OTPC_CMD_MASK, base + OTPC_COMMAND_OFFSET);
> +}
> +
> +static inline void set_cpu_address(void __iomem *base, u32 addr)
> +{
> + writel(addr & OTPC_ADDR_MASK, base + OTPC_CPUADDR_REG_OFFSET);
> +}
> +
> +static inline void set_start_bit(void __iomem *base)
> +{
> + writel(1 << OTPC_CMD_START_START, base + OTPC_CMD_START_OFFSET);
> +}
> +
> +static inline void reset_start_bit(void __iomem *base)
> +{
> + writel(0, base + OTPC_CMD_START_OFFSET);
> +}
> +
> +static inline void write_cpu_data(void __iomem *base, u32 value)
> +{
> + writel(value, base + OTPC_CPU_WRITE_REG_OFFSET);
> +}
> +
> +static int poll_cpu_status(void __iomem *base, u32 value)
> +{
> + u32 status;
> + u32 retries;
> +
> + for (retries = 0; retries < OTPC_RETRIES; retries++) {
> + status = readl(base + OTPC_CPU_STATUS_OFFSET);
> + if (status & value)
> + break;
> + udelay(1);
> + }
> + if (retries == OTPC_RETRIES)
> + return -EAGAIN;
> +
> + return 0;
> +}
> +
> +static int enable_ocotp_program(void __iomem *base)
> +{
> + static const u32 vals[] = OTPC_PROG_EN_SEQ;
> + int i;
> + int ret;
> +
> + /* Write the magic sequence to enable programming */
> + set_command(base, OTPC_CMD_OTP_PROG_ENABLE);
> + for (i = 0; i < ARRAY_SIZE(vals); i++) {
> + write_cpu_data(base, vals[i]);
> + set_start_bit(base);
> + ret = poll_cpu_status(base, OTPC_STAT_CMD_DONE);
> + reset_start_bit(base);
> + if (ret)
> + return ret;
> + }
> +
> + return poll_cpu_status(base, OTPC_STAT_PROG_OK);
> +}
> +
> +static int disable_ocotp_program(void __iomem *base)
> +{
> + int ret;
> +
> + set_command(base, OTPC_CMD_OTP_PROG_DISABLE);
> + set_start_bit(base);
> + ret = poll_cpu_status(base, OTPC_STAT_PROG_OK);
> + reset_start_bit(base);
> +
> + return ret;
> +}
> +
> +static int bcm_otpc_read(void *context, unsigned int offset, void *val,
> + size_t bytes)
> +{
> + struct otpc_priv *priv = context;
> + u32 *buf = val;
> + u32 bytes_read;
> + u32 address = offset / priv->config->word_size;
> + int i, ret;
> +
> + for (bytes_read = 0; bytes_read < bytes;) {
> + set_command(priv->base, OTPC_CMD_READ);
> + set_cpu_address(priv->base, address++);
> + set_start_bit(priv->base);
> + ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE);
> + if (ret) {
> + dev_err(priv->dev, "otp read error: 0x%x", ret);
> + return -EIO;
> + }
> +
> + for (i = 0; i < priv->map->otpc_row_size; i++) {
> + *buf++ = readl(priv->base +
> + priv->map->data_r_offset[i]);
> + bytes_read += sizeof(*buf);
> + }
> +
> + reset_start_bit(priv->base);
> + }
> +
> + return 0;
> +}
> +
> +static int bcm_otpc_write(void *context, unsigned int offset, void *val,
> + size_t bytes)
> +{
> + struct otpc_priv *priv = context;
> + u32 *buf = val;
> + u32 bytes_written;
> + u32 address = offset / priv->config->word_size;
> + int i, ret;
> +
> + if (offset % priv->config->word_size)
> + return -EINVAL;
> +
> + ret = enable_ocotp_program(priv->base);
> + if (ret)
> + return -EIO;
> +
> + for (bytes_written = 0; bytes_written < bytes;) {
> + set_command(priv->base, OTPC_CMD_PROGRAM);
> + set_cpu_address(priv->base, address++);
> + for (i = 0; i < priv->map->otpc_row_size; i++) {
> + writel(*buf, priv->base + priv->map->data_r_offset[i]);
> + buf++;
> + bytes_written += sizeof(*buf);
> + }
> + set_start_bit(priv->base);
> + ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE);
> + reset_start_bit(priv->base);
> + if (ret) {
> + dev_err(priv->dev, "otp write error: 0x%x", ret);
> + return -EIO;
> + }
> + }
> +
> + disable_ocotp_program(priv->base);
> +
> + return 0;
> +}
> +
> +static struct nvmem_config bcm_otpc_nvmem_config = {
> + .name = "bcm-ocotp",
> + .read_only = false,
> + .word_size = 4,
> + .stride = 4,
> + .owner = THIS_MODULE,
> + .reg_read = bcm_otpc_read,
> + .reg_write = bcm_otpc_write,
> +};
> +
> +static const struct of_device_id bcm_otpc_dt_ids[] = {
> + { .compatible = "brcm,ocotp" },
> + { .compatible = "brcm,ocotp-v2" },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, bcm_otpc_dt_ids);
> +
> +static int bcm_otpc_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *dn = dev->of_node;
> + struct resource *res;
> + struct otpc_priv *priv;
> + struct nvmem_device *nvmem;
> + int err;
> + u32 num_words;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + if (of_device_is_compatible(dev->of_node, "brcm,ocotp"))
> + priv->map = &otp_map;
> + else if (of_device_is_compatible(dev->of_node, "brcm,ocotp-v2"))
> + priv->map = &otp_map_v2;
> + else {
> + dev_err(&pdev->dev,
> + "%s otpc config map not defined\n", __func__);
> + return -EINVAL;
> + }
> +
> + /* Get OTP base address register. */
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + priv->base = devm_ioremap_resource(dev, res);
> + if (IS_ERR(priv->base)) {
> + dev_err(dev, "unable to map I/O memory\n");
> + return PTR_ERR(priv->base);
> + }
> +
> + /* Enable CPU access to OTPC. */
> + writel(readl(priv->base + OTPC_MODE_REG_OFFSET) |
> + BIT(OTPC_MODE_REG_OTPC_MODE),
> + priv->base + OTPC_MODE_REG_OFFSET);
> + reset_start_bit(priv->base);
> +
> + /* Read size of memory in words. */
> + err = of_property_read_u32(dn, "brcm,ocotp-size", &num_words);
> + if (err) {
> + dev_err(dev, "size parameter not specified\n");
> + return -EINVAL;
> + } else if (num_words == 0) {
> + dev_err(dev, "size must be > 0\n");
> + return -EINVAL;
> + }
> +
> + bcm_otpc_nvmem_config.size = 4 * num_words;
> + bcm_otpc_nvmem_config.dev = dev;
> + bcm_otpc_nvmem_config.priv = priv;
> +
> + if (of_device_is_compatible(dev->of_node, "brcm,ocotp-v2")) {
> + bcm_otpc_nvmem_config.word_size = 8;
> + bcm_otpc_nvmem_config.stride = 8;
> + }
> +
> + priv->config = &bcm_otpc_nvmem_config;
> +
> + nvmem = nvmem_register(&bcm_otpc_nvmem_config);
> + if (IS_ERR(nvmem)) {
> + dev_err(dev, "error registering nvmem config\n");
> + return PTR_ERR(nvmem);
> + }
> +
> + platform_set_drvdata(pdev, nvmem);
> +
> + return 0;
> +}
> +
> +static int bcm_otpc_remove(struct platform_device *pdev)
> +{
> + struct nvmem_device *nvmem = platform_get_drvdata(pdev);
> +
> + return nvmem_unregister(nvmem);
> +}
> +
> +static struct platform_driver bcm_otpc_driver = {
> + .probe = bcm_otpc_probe,
> + .remove = bcm_otpc_remove,
> + .driver = {
> + .name = "brcm-otpc",
> + .of_match_table = bcm_otpc_dt_ids,
> + },
> +};
> +module_platform_driver(bcm_otpc_driver);
> +
> +MODULE_DESCRIPTION("Broadcom OTPC driver");
> +MODULE_LICENSE("GPL v2");
>
^ permalink raw reply
* [RFC PATCH 08/13] dwmac-meson8b: add support for phy selection
From: Neil Armstrong @ 2016-10-31 14:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161021160807.GT16974@lunn.ch>
On 10/21/2016 06:08 PM, Andrew Lunn wrote:
> Hi Neil
>
>> Yes this would be a good idea if we were able to scan the internal
>> and external PHYs at the same time, but with our limited knowledge
>> the values we write in the register seems to switch a mux for the
>> whole RMII and MDIO signals to either interface.
>
> Ah, O.K. So you need something like:
>
> drivers/net/phy/mdio-mux-mmioreg.c
>
> This seems to be limited to a single byte for the mux register, so you
> might need to make some extensions.
>
> Andrew
>
Thanks for the hint, I will try to make use of this !
Neil
^ permalink raw reply
* [PATCH 0/3] ARM: dts: oxnas: Update support for OX820 and use dt-bindings
From: Olof Johansson @ 2016-10-31 14:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <fce063fd-6aaa-8d30-1588-e656e93bdebc@baylibre.com>
Hi,
On Mon, Oct 31, 2016 at 2:58 AM, Neil Armstrong <narmstrong@baylibre.com> wrote:
> On 10/21/2016 05:10 PM, Neil Armstrong wrote:
>> This patchset updates the ARM DTS for the Oxnas platform by :
>> - Add support for the Oxford Semicondutor OX820 and the PogoPlug V3
>> - Update the OX810SE to use the dt-bindings includes files introduced in [1] and [2]
>> - Fix the MAINTAINERS entry and add the PogoPlug V3 file maintainance
>>
>> This patchset depends on dt-bindings include headers posted at [1] and [2],
>> that were accepted/merged in the subsystem trees.
>>
>> How could I manage this dependency for 4.10 ?
>>
>> [1] https://listengine.tuxfamily.org/lists.tuxfamily.org/linux-oxnas/2016/10/msg00008.html
>> [2] https://listengine.tuxfamily.org/lists.tuxfamily.org/linux-oxnas/2016/10/msg00007.html
>>
>> Neil Armstrong (3):
>> ARM: dts: Add support for OX820 and Pogoplug V3
>> ARM: dts: OX810: Update with dt-bindings includes
>> MAINTAINERS: oxnas: Add new files definitions
>>
>> Documentation/devicetree/bindings/arm/oxnas.txt | 5 +
>> MAINTAINERS | 3 +-
>> arch/arm/boot/dts/Makefile | 3 +-
>> .../boot/dts/cloudengines-pogoplug-series-3.dts | 94 +++++++
>> arch/arm/boot/dts/ox810se.dtsi | 10 +-
>> arch/arm/boot/dts/ox820.dtsi | 298 +++++++++++++++++++++
>> 6 files changed, 407 insertions(+), 6 deletions(-)
>> create mode 100644 arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
>> create mode 100644 arch/arm/boot/dts/ox820.dtsi
>>
>
> Hi,
>
> I'm ready to send a pull request for arm-soc-dt, but I need to understand how this dependency
> should be worked out.
>
> Should this be sent as a late pull request ?
The need for dt-include changes is one of my pet peeves these days,
since they require coordination between trees.
There's two ways to solve this:
1) Make sure that the branches you sent to other maintainers are
stable, that they merge them as-is and don't rebase. This is a
three-way handshake (we want to be cc:d on it). Then base your branch
on top of those two branches.
or:
2) Avoid using the includes now, using numerical constants instead.
Then, after next merge window, follow up with a patch that converts to
symbols.
-Olof
^ permalink raw reply
* [RFC PATCH 09/13] net: phy: Add Meson GXL Internal PHY driver
From: Neil Armstrong @ 2016-10-31 14:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0ea5a7a8-3913-0e6a-6ff2-9f34015ea071@gmail.com>
On 10/21/2016 10:56 PM, Florian Fainelli wrote:
> On 10/21/2016 07:40 AM, Neil Armstrong wrote:
>> Add driver for the Internal RMII PHY found in the Amlogic Meson GXL SoCs.
>>
>> This PHY seems to only implement some standard registers and need some
>> workarounds to provide autoneg values from vendor registers.
>>
>> Some magic values are currently used to configure the PHY, and this a
>> temporary setup until clarification about these registers names and
>> registers fields are provided by Amlogic.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>> +
>> +static int meson_gxl_config_init(struct phy_device *phydev)
>> +{
>> + int val;
>> + u32 features;
>> +
>> + meson_gxl_phy_config(phydev);
>> +
>> + features = SUPPORTED_MII;
>
> This does not really belong in the PHY driver, and this is statically
> assigned, I would just drop this.
>
Ok
>> +
>> + /* Do we support autonegotiation? */
>> + val = phy_read(phydev, MII_BMSR);
>> + if (val < 0)
>> + return val;
>> +
>> + if (val & BMSR_ANEGCAPABLE)
>> + features |= SUPPORTED_Autoneg;
>> + if (val & BMSR_100FULL)
>> + features |= SUPPORTED_100baseT_Full;
>> + if (val & BMSR_100HALF)
>> + features |= SUPPORTED_100baseT_Half;
>> + if (val & BMSR_10FULL)
>> + features |= SUPPORTED_10baseT_Full;
>> + if (val & BMSR_10HALF)
>> + features |= SUPPORTED_10baseT_Half;
>> +
>> + phydev->supported = features;
>> + phydev->advertising = features;
>
> This is redundant with what PHYLIB will determine for the PHY.
>
ok
>> +
>> + return 0;
>> +}
>> +
>> +static int meson_gxl_phy_read_status(struct phy_device *phydev)
>> +{
>> + int err;
>> +
>> + /* Update the link, but return if there was an error */
>> + err = genphy_update_link(phydev);
>> + if (err)
>> + return err;
>> +
>> + phydev->lp_advertising = 0;
>> + phydev->pause = 0;
>> + phydev->asym_pause = 0;
>> +
>> + if (phydev->autoneg == AUTONEG_ENABLE) {
>> + unsigned int speed;
>> + int reg = phy_read(phydev, GXL_REG_ANEG);
>
> Is all of this really necessary? This should all be reflected in the
> standard BMSR register, is not this the case here that we have to read
> this non-standard register?
>
This is what I understood from the original driver code, but I will make some further tests
and see if the BMSR returns some good data.
> You use genphy_config_aneg(), so surely, the standard auto-negotiation
> part works somehow?
Yes, and the BMSR is also used in the config_init here...
>
>> +
>> + if (reg < 0)
>> + return reg;
>> +
>> + speed = reg & REG_ANEG_SPEED_MASK;
>> +
>> + if (reg & REG_ANEG_FDUPLEX)
>> + phydev->duplex = DUPLEX_FULL;
>> + else
>> + phydev->duplex = DUPLEX_HALF;
>> +
>> + if ((reg & REG_ANEG_SPEED_MASK) == REG_ANEG_SPEED10)
>> + phydev->speed = SPEED_10;
>> + else if ((reg & REG_ANEG_SPEED_MASK) == REG_ANEG_SPEED100)
>> + phydev->speed = SPEED_100;
>> + } else {
>> + int bmcr = phy_read(phydev, MII_BMCR);
>> +
>> + if (bmcr < 0)
>> + return bmcr;
>> +
>> + if (bmcr & BMCR_FULLDPLX)
>> + phydev->duplex = DUPLEX_FULL;
>> + else
>> + phydev->duplex = DUPLEX_HALF;
>> +
>> + if (bmcr & BMCR_SPEED1000)
>> + phydev->speed = SPEED_1000;
>> + else if (bmcr & BMCR_SPEED100)
>> + phydev->speed = SPEED_100;
>> + else
>> + phydev->speed = SPEED_10;
>> + }
>
>> +
>> + return 0;
>> +}
>> +
>> +static struct phy_driver meson_gxl_phy = {
>> + .phy_id = 0x01814400,
>> + .name = "Meson GXL Internal PHY",
>> + .phy_id_mask = 0x0fffffff,
>
> Usually the last 4 bits are 0, since that's where the revision part is
> located.
>
Fixed
>> + .features = 0,
>
> You should set PHY_GBIT_FEATURES and set .flags to PHY_IS_INTERNAL since
> this is an internal PHY?
>
Ok
Thanks,
Neil
^ permalink raw reply
* [PATCH 0/3] ARM: dts: oxnas: Update support for OX820 and use dt-bindings
From: Neil Armstrong @ 2016-10-31 14:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOesGMjsjYPKyH2CD4siZmB3F64h+c7vndfjFdniTDLB4Eh4Pw@mail.gmail.com>
Hi Olof,
On 10/31/2016 03:24 PM, Olof Johansson wrote:
> Hi,
>>
>> Hi,
>>
>> I'm ready to send a pull request for arm-soc-dt, but I need to understand how this dependency
>> should be worked out.
>>
>> Should this be sent as a late pull request ?
>
>
> The need for dt-include changes is one of my pet peeves these days,
> since they require coordination between trees.
>
> There's two ways to solve this:
>
> 1) Make sure that the branches you sent to other maintainers are
> stable, that they merge them as-is and don't rebase. This is a
> three-way handshake (we want to be cc:d on it). Then base your branch
> on top of those two branches.
It may be possible, at least from the clock tree.
Anyway, it's good to know, if I had a single tree to synchronize with,
I'll eventually select this option...
>
> or:
>
> 2) Avoid using the includes now, using numerical constants instead.
> Then, after next merge window, follow up with a patch that converts to
> symbols.
I will select this option for now, my ultimate goal is to have something booting
for 4.10, cleanup can really wait 4.11...
>
> -Olof
>
Thanks,
Neil
^ permalink raw reply
* [PATCH v2 0/5] ARM: da850: new drivers for better LCDC support
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
This series adds two new drivers in order to better support the LCDC
rev1 present on the da850 boards.
The first patch adds a new memory driver which allows to write to the
DDR2/mDDR memory controller present on the da8xx SoCs.
The second patch adds a new bus driver which allows to interact with
the MSTPRI registers of the SYSCFG0 module
As is mentioned in the comments: we don't want to commit to supporting
stable interfaces (DT bindings or sysfs attributes) so we hardcode the
settings required by some boards (for now only da850-lcdk) with the
hope that linux gets an appropriate framework for performance knobs
in the future.
Potential extensions of these drivers should be straightforward in the
future.
Subsequent patches add DT nodes for the new drivers: disabled nodes
in da850.dtsi and enabled in da850-lcdk.dts.
The last patch adds a workaround for current lack of support for drm
bridges in tilcdc.
Tested on a da850-lcdk with a display connected over VGA and two
additional patches for tilcdc (sent to linux-drm): ran simple modetest
for supported resolutions, used X.org and fluxbox as graphical
environment, played video with mplayer.
v1 -> v2:
- used regular readl()/writel() instead of __raw_** versions
- used resource_size() instead of calculating the size by hand
- used ioremap instead of syscon in patch [2/5]
- added the DT nodes in patches [3/5]-[5/5]
Bartosz Golaszewski (5):
ARM: memory: da8xx-ddrctl: new driver
ARM: bus: da8xx-mstpri: new driver
ARM: dts: da850: add the mstpri and ddrctl nodes
ARM: dts: da850-lcdk: enable mstpri and ddrctl nodes
ARM: dts: da850-lcdk: add tilcdc panel node
.../devicetree/bindings/bus/ti,da850-mstpri.txt | 20 ++
.../memory-controllers/ti-da8xx-ddrctl.txt | 20 ++
arch/arm/boot/dts/da850-lcdk.dts | 71 ++++++
arch/arm/boot/dts/da850.dtsi | 11 +
drivers/bus/Kconfig | 9 +
drivers/bus/Makefile | 2 +
drivers/bus/da8xx-mstpri.c | 269 +++++++++++++++++++++
drivers/memory/Kconfig | 8 +
drivers/memory/Makefile | 1 +
drivers/memory/da8xx-ddrctl.c | 175 ++++++++++++++
10 files changed, 586 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
create mode 100644 drivers/bus/da8xx-mstpri.c
create mode 100644 drivers/memory/da8xx-ddrctl.c
--
2.9.3
^ permalink raw reply
* [PATCH v2 1/5] ARM: memory: da8xx-ddrctl: new driver
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
Create a new driver for the da8xx DDR2/mDDR controller and implement
support for writing to the Peripheral Bus Burst Priority Register.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
.../memory-controllers/ti-da8xx-ddrctl.txt | 20 +++
drivers/memory/Kconfig | 8 +
drivers/memory/Makefile | 1 +
drivers/memory/da8xx-ddrctl.c | 175 +++++++++++++++++++++
4 files changed, 204 insertions(+)
create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
create mode 100644 drivers/memory/da8xx-ddrctl.c
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
new file mode 100644
index 0000000..ec1dd40
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
@@ -0,0 +1,20 @@
+* Device tree bindings for Texas Instruments da8xx DDR2/mDDR memory controller
+
+The DDR2/mDDR memory controller present on Texas Instruments da8xx SoCs features
+a set of registers which allow to tweak the controller's behavior.
+
+Documentation:
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
+
+Required properties:
+
+- compatible: "ti,da850-ddr-controller" - for da850 SoC based boards
+- reg: a tuple containing the base address of the memory
+ controller and the size of the memory area to map
+
+Example for da850 shown below.
+
+ddrctl {
+ compatible = "ti,da850-ddr-controller";
+ reg = <0xb0000000 0xe8>;
+};
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 4b4c0c3..ec80e35 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -134,6 +134,14 @@ config MTK_SMI
mainly help enable/disable iommu and control the power domain and
clocks for each local arbiter.
+config DA8XX_DDRCTL
+ bool "Texas Instruments da8xx DDR2/mDDR driver"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ This driver is for the DDR2/mDDR Memory Controller present on
+ Texas Instruments da8xx SoCs. It's used to tweak various memory
+ controller configuration options.
+
source "drivers/memory/samsung/Kconfig"
source "drivers/memory/tegra/Kconfig"
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index b20ae38..e88097fb 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
obj-$(CONFIG_MTK_SMI) += mtk-smi.o
+obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
obj-$(CONFIG_SAMSUNG_MC) += samsung/
obj-$(CONFIG_TEGRA_MC) += tegra/
diff --git a/drivers/memory/da8xx-ddrctl.c b/drivers/memory/da8xx-ddrctl.c
new file mode 100644
index 0000000..a20e7bb
--- /dev/null
+++ b/drivers/memory/da8xx-ddrctl.c
@@ -0,0 +1,175 @@
+/*
+ * TI da8xx DDR2/mDDR controller driver
+ *
+ * Copyright (C) 2016 BayLibre SAS
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+/*
+ * REVISIT: Linux doesn't have a good framework for the kind of performance
+ * knobs this driver controls. We can't use device tree properties as it deals
+ * with hardware configuration rather than description. We also don't want to
+ * commit to maintaining some random sysfs attributes.
+ *
+ * For now we just hardcode the register values for the boards that need
+ * some changes (as is the case for the LCD controller on da850-lcdk - the
+ * first board we support here). When linux gets an appropriate framework,
+ * we'll easily convert the driver to it.
+ */
+
+struct da8xx_ddrctl_config_knob {
+ const char *name;
+ u32 reg;
+ u32 mask;
+ u32 shift;
+};
+
+static const struct da8xx_ddrctl_config_knob da8xx_ddrctl_knobs[] = {
+ {
+ .name = "da850-pbbpr",
+ .reg = 0x20,
+ .mask = 0xffffff00,
+ .shift = 0,
+ },
+};
+
+struct da8xx_ddrctl_setting {
+ const char *name;
+ u32 val;
+};
+
+struct da8xx_ddrctl_board_settings {
+ const char *board;
+ const struct da8xx_ddrctl_setting *settings;
+};
+
+static const struct da8xx_ddrctl_setting da850_lcdk_ddrctl_settings[] = {
+ {
+ .name = "da850-pbbpr",
+ .val = 0x20,
+ },
+ { }
+};
+
+static const struct da8xx_ddrctl_board_settings da8xx_ddrctl_board_confs[] = {
+ {
+ .board = "ti,da850-lcdk",
+ .settings = da850_lcdk_ddrctl_settings,
+ },
+};
+
+static const struct da8xx_ddrctl_config_knob *
+da8xx_ddrctl_match_knob(const struct da8xx_ddrctl_setting *setting)
+{
+ const struct da8xx_ddrctl_config_knob *knob;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_ddrctl_knobs); i++) {
+ knob = &da8xx_ddrctl_knobs[i];
+
+ if (strcmp(knob->name, setting->name) == 0)
+ return knob;
+ }
+
+ return NULL;
+}
+
+static const struct da8xx_ddrctl_setting *da8xx_ddrctl_get_board_settings(void)
+{
+ const struct da8xx_ddrctl_board_settings *board_settings;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_ddrctl_board_confs); i++) {
+ board_settings = &da8xx_ddrctl_board_confs[i];
+
+ if (of_machine_is_compatible(board_settings->board))
+ return board_settings->settings;
+ }
+
+ return NULL;
+}
+
+static int da8xx_ddrctl_probe(struct platform_device *pdev)
+{
+ const struct da8xx_ddrctl_config_knob *knob;
+ const struct da8xx_ddrctl_setting *setting;
+ struct device_node *node;
+ struct resource *res;
+ void __iomem *ddrctl;
+ struct device *dev;
+ u32 reg;
+
+ dev = &pdev->dev;
+ node = dev->of_node;
+
+ setting = da8xx_ddrctl_get_board_settings();
+ if (!setting) {
+ dev_err(dev, "no settings for board '%s'\n",
+ of_flat_dt_get_machine_name());
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ddrctl = devm_ioremap_resource(dev, res);
+ if (IS_ERR(ddrctl)) {
+ dev_err(dev, "unable to map memory controller registers\n");
+ return PTR_ERR(ddrctl);
+ }
+
+ for (; setting->name; setting++) {
+ knob = da8xx_ddrctl_match_knob(setting);
+ if (!knob) {
+ dev_warn(dev,
+ "no such config option: %s\n", setting->name);
+ continue;
+ }
+
+ if (knob->reg + sizeof(u32) > resource_size(res)) {
+ dev_warn(dev,
+ "register offset of '%s' exceeds mapped memory size\n",
+ knob->name);
+ continue;
+ }
+
+ reg = readl(ddrctl + knob->reg);
+ reg &= knob->mask;
+ reg |= setting->val << knob->shift;
+
+ dev_dbg(dev, "writing 0x%08x to %s\n", reg, setting->name);
+
+ writel(reg, ddrctl + knob->reg);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id da8xx_ddrctl_of_match[] = {
+ { .compatible = "ti,da850-ddr-controller", },
+ { },
+};
+
+static struct platform_driver da8xx_ddrctl_driver = {
+ .probe = da8xx_ddrctl_probe,
+ .driver = {
+ .name = "da850-ddr-controller",
+ .of_match_table = da8xx_ddrctl_of_match,
+ },
+};
+module_platform_driver(da8xx_ddrctl_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("TI da8xx DDR2/mDDR controller driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
^ permalink raw reply related
* [PATCH v2 2/5] ARM: bus: da8xx-mstpri: new driver
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
Create the driver for the da8xx master peripheral priority
configuration and implement support for writing to the three
Master Priority registers on da850 SoCs.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
.../devicetree/bindings/bus/ti,da850-mstpri.txt | 20 ++
drivers/bus/Kconfig | 9 +
drivers/bus/Makefile | 2 +
drivers/bus/da8xx-mstpri.c | 269 +++++++++++++++++++++
4 files changed, 300 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
create mode 100644 drivers/bus/da8xx-mstpri.c
diff --git a/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt b/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
new file mode 100644
index 0000000..72daefc
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
@@ -0,0 +1,20 @@
+* Device tree bindings for Texas Instruments da8xx master peripheral
+ priority driver
+
+DA8XX SoCs feature a set of registers allowing to change the priority of all
+peripherals classified as masters.
+
+Documentation:
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
+
+Required properties:
+
+- compatible: "ti,da850-mstpri" - for da850 based boards
+- reg: offset and length of the mstpri registers
+
+Example for da850-lcdk is shown below.
+
+mstpri {
+ compatible = "ti,da850-mstpri";
+ reg = <0x14110 0x0c>;
+};
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 7875105..f5db3a7 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -167,4 +167,13 @@ config VEXPRESS_CONFIG
help
Platform configuration infrastructure for the ARM Ltd.
Versatile Express.
+
+config DA8XX_MSTPRI
+ bool "TI da8xx master peripheral priority driver"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ Driver for Texas Instruments da8xx master peripheral priority
+ configuration. Allows to adjust the priorities of all master
+ peripherals.
+
endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index c6cfa6b..2adb540 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -21,3 +21,5 @@ obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
obj-$(CONFIG_TEGRA_ACONNECT) += tegra-aconnect.o
obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
+
+obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o
diff --git a/drivers/bus/da8xx-mstpri.c b/drivers/bus/da8xx-mstpri.c
new file mode 100644
index 0000000..85f0b53
--- /dev/null
+++ b/drivers/bus/da8xx-mstpri.c
@@ -0,0 +1,269 @@
+/*
+ * TI da8xx master peripheral priority driver
+ *
+ * Copyright (C) 2016 BayLibre SAS
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.com.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/of_fdt.h>
+
+/*
+ * REVISIT: Linux doesn't have a good framework for the kind of performance
+ * knobs this driver controls. We can't use device tree properties as it deals
+ * with hardware configuration rather than description. We also don't want to
+ * commit to maintaining some random sysfs attributes.
+ *
+ * For now we just hardcode the register values for the boards that need
+ * some changes (as is the case for the LCD controller on da850-lcdk - the
+ * first board we support here). When linux gets an appropriate framework,
+ * we'll easily convert the driver to it.
+ */
+
+#define DA8XX_MSTPRI0_OFFSET 0
+#define DA8XX_MSTPRI1_OFFSET 4
+#define DA8XX_MSTPRI2_OFFSET 8
+
+enum {
+ DA8XX_MSTPRI_ARM_I = 0,
+ DA8XX_MSTPRI_ARM_D,
+ DA8XX_MSTPRI_UPP,
+ DA8XX_MSTPRI_SATA,
+ DA8XX_MSTPRI_PRU0,
+ DA8XX_MSTPRI_PRU1,
+ DA8XX_MSTPRI_EDMA30TC0,
+ DA8XX_MSTPRI_EDMA30TC1,
+ DA8XX_MSTPRI_EDMA31TC0,
+ DA8XX_MSTPRI_VPIF_DMA_0,
+ DA8XX_MSTPRI_VPIF_DMA_1,
+ DA8XX_MSTPRI_EMAC,
+ DA8XX_MSTPRI_USB0CFG,
+ DA8XX_MSTPRI_USB0CDMA,
+ DA8XX_MSTPRI_UHPI,
+ DA8XX_MSTPRI_USB1,
+ DA8XX_MSTPRI_LCDC,
+};
+
+struct da8xx_mstpri_descr {
+ int reg;
+ int shift;
+ int mask;
+};
+
+static const struct da8xx_mstpri_descr da8xx_mstpri_priority_list[] = {
+ [DA8XX_MSTPRI_ARM_I] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_ARM_D] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 4,
+ .mask = 0x000000f0,
+ },
+ [DA8XX_MSTPRI_UPP] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 16,
+ .mask = 0x000f0000,
+ },
+ [DA8XX_MSTPRI_SATA] = {
+ .reg = DA8XX_MSTPRI0_OFFSET,
+ .shift = 20,
+ .mask = 0x00f00000,
+ },
+ [DA8XX_MSTPRI_PRU0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_PRU1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 4,
+ .mask = 0x000000f0,
+ },
+ [DA8XX_MSTPRI_EDMA30TC0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 8,
+ .mask = 0x00000f00,
+ },
+ [DA8XX_MSTPRI_EDMA30TC1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 12,
+ .mask = 0x0000f000,
+ },
+ [DA8XX_MSTPRI_EDMA31TC0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 16,
+ .mask = 0x000f0000,
+ },
+ [DA8XX_MSTPRI_VPIF_DMA_0] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 24,
+ .mask = 0x0f000000,
+ },
+ [DA8XX_MSTPRI_VPIF_DMA_1] = {
+ .reg = DA8XX_MSTPRI1_OFFSET,
+ .shift = 28,
+ .mask = 0xf0000000,
+ },
+ [DA8XX_MSTPRI_EMAC] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 0,
+ .mask = 0x0000000f,
+ },
+ [DA8XX_MSTPRI_USB0CFG] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 8,
+ .mask = 0x00000f00,
+ },
+ [DA8XX_MSTPRI_USB0CDMA] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 12,
+ .mask = 0x0000f000,
+ },
+ [DA8XX_MSTPRI_UHPI] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 20,
+ .mask = 0x00f00000,
+ },
+ [DA8XX_MSTPRI_USB1] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 24,
+ .mask = 0x0f000000,
+ },
+ [DA8XX_MSTPRI_LCDC] = {
+ .reg = DA8XX_MSTPRI2_OFFSET,
+ .shift = 28,
+ .mask = 0xf0000000,
+ },
+};
+
+struct da8xx_mstpri_priority {
+ int which;
+ u32 val;
+};
+
+struct da8xx_mstpri_board_priorities {
+ const char *board;
+ const struct da8xx_mstpri_priority *priorities;
+ size_t numprio;
+};
+
+/*
+ * Default memory settings of da850 do not meet the throughput/latency
+ * requirements of tilcdc. This results in the image displayed being
+ * incorrect and the following warning being displayed by the LCDC
+ * drm driver:
+ *
+ * tilcdc da8xx_lcdc.0: tilcdc_crtc_irq(0x00000020): FIFO underfow
+ */
+static const struct da8xx_mstpri_priority da850_lcdk_priorities[] = {
+ {
+ .which = DA8XX_MSTPRI_LCDC,
+ .val = 0,
+ },
+ {
+ .which = DA8XX_MSTPRI_EDMA30TC1,
+ .val = 0,
+ },
+ {
+ .which = DA8XX_MSTPRI_EDMA30TC0,
+ .val = 1,
+ },
+};
+
+static const struct da8xx_mstpri_board_priorities da8xx_mstpri_board_confs[] = {
+ {
+ .board = "ti,da850-lcdk",
+ .priorities = da850_lcdk_priorities,
+ .numprio = ARRAY_SIZE(da850_lcdk_priorities),
+ },
+};
+
+static const struct da8xx_mstpri_board_priorities *
+da8xx_mstpri_get_board_prio(void)
+{
+ const struct da8xx_mstpri_board_priorities *board_prio;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(da8xx_mstpri_board_confs); i++) {
+ board_prio = &da8xx_mstpri_board_confs[i];
+
+ if (of_machine_is_compatible(board_prio->board))
+ return board_prio;
+ }
+
+ return NULL;
+}
+
+static int da8xx_mstpri_probe(struct platform_device *pdev)
+{
+ const struct da8xx_mstpri_board_priorities *prio_list;
+ const struct da8xx_mstpri_descr *prio_descr;
+ const struct da8xx_mstpri_priority *prio;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ void __iomem *mstpri;
+ u32 reg;
+ int i;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mstpri = devm_ioremap_resource(dev, res);
+ if (IS_ERR(mstpri)) {
+ dev_err(dev, "unable to map MSTPRI registers\n");
+ return PTR_ERR(mstpri);
+ }
+
+ prio_list = da8xx_mstpri_get_board_prio();
+ if (!prio_list) {
+ dev_err(dev, "no master priotities defined for board '%s'\n",
+ of_flat_dt_get_machine_name());
+ return -EINVAL;
+ }
+
+ for (i = 0; i < prio_list->numprio; i++) {
+ prio = &prio_list->priorities[i];
+ prio_descr = &da8xx_mstpri_priority_list[prio->which];
+
+ if (prio_descr->reg + sizeof(u32) > resource_size(res)) {
+ dev_warn(dev, "register offset out of range\n");
+ continue;
+ }
+
+ reg = readl(mstpri + prio_descr->reg);
+ reg &= ~prio_descr->mask;
+ reg |= prio->val << prio_descr->shift;
+
+ writel(reg, mstpri + prio_descr->reg);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id da8xx_mstpri_of_match[] = {
+ { .compatible = "ti,da850-mstpri", },
+ { },
+};
+
+static struct platform_driver da8xx_mstpri_driver = {
+ .probe = da8xx_mstpri_probe,
+ .driver = {
+ .name = "da8xx-mstpri",
+ .of_match_table = da8xx_mstpri_of_match,
+ },
+};
+module_platform_driver(da8xx_mstpri_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("TI da8xx master peripheral priority driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
^ permalink raw reply related
* [PATCH v2 3/5] ARM: dts: da850: add the mstpri and ddrctl nodes
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
Add the nodes for the MSTPRI configuration and DDR2/mDDR memory
controller drivers to da850.dtsi.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/boot/dts/da850.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 112c6d7..44bece3 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -454,6 +454,12 @@
interrupts = <52>;
status = "disabled";
};
+
+ mstpri: mstpri at 14110 {
+ compatible = "ti,da850-mstpri";
+ reg = <0x14110 0x0c>;
+ status = "disabled";
+ };
};
aemif: aemif at 68000000 {
compatible = "ti,da850-aemif";
@@ -465,4 +471,9 @@
1 0 0x68000000 0x00008000>;
status = "disabled";
};
+ ddrctl: ddrctl at b0000000 {
+ compatible = "ti,da850-ddr-controller";
+ reg = <0xb0000000 0xe8>;
+ status = "disabled";
+ };
};
--
2.9.3
^ permalink raw reply related
* [PATCH v2 4/5] ARM: dts: da850-lcdk: enable mstpri and ddrctl nodes
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
Enable the MSTPRI configuration and DDR2/mDDR memory controller
nodes on da850-lcdk. This is needed in order to adjust the memory
throughput constraints for better tilcdc support.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/boot/dts/da850-lcdk.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 4747629..b39796e 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -243,3 +243,11 @@
};
};
};
+
+&mstpri {
+ status = "okay";
+};
+
+&ddrctl {
+ status = "okay";
+};
--
2.9.3
^ permalink raw reply related
* [PATCH v2 5/5] ARM: dts: da850-lcdk: add tilcdc panel node
From: Bartosz Golaszewski @ 2016-10-31 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477925138-23457-1-git-send-email-bgolaszewski@baylibre.com>
The tilcdc driver is not yet ready for working together with the
dumb-vga-dac drm bridge. While the work on enabling drm_bridge
support in tilcdc continues, enable the VGA connector on da850-lcdk
with the following workaround: use the tilcdc-panel driver with
a set of common (and tested) resolutions.
Once the drm bridge support is complete, we'll remove the node added
by this patch and use the correct solution. This change will be
transparent for the user.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/boot/dts/da850-lcdk.dts | 63 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index b39796e..df582c6 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -62,6 +62,65 @@
regulator-max-microvolt = <5000000>;
};
+ /*
+ * Remove this node once the tilcdc driver gets support for
+ * drm bridge modules.
+ */
+ panel {
+ compatible = "ti,tilcdc,panel";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+ status = "okay";
+
+ panel-info {
+ ac-bias = <0>;
+ ac-bias-intrpt = <0>;
+ dma-burst-sz = <16>;
+ bpp = <16>;
+ fdd = <255>;
+ sync-edge = <0>;
+ sync-ctrl = <0>;
+ raster-order = <0>;
+ fifo-th = <5>;
+ };
+
+ display-timings {
+ native-mode = <&svga_timings>;
+ vga_timings: 640x480 at 60 {
+ clock-frequency = <27500000>;
+ hactive = <640>;
+ hback-porch = <90>;
+ hfront-porch = <40>;
+ hsync-len = <128>;
+ vactive = <480>;
+ vback-porch = <23>;
+ vfront-porch = <1>;
+ vsync-len = <4>;
+ };
+ vga_timings_hf: 640x480 at 75 {
+ clock-frequency = <34000000>;
+ hactive = <640>;
+ hback-porch = <90>;
+ hfront-porch = <40>;
+ hsync-len = <128>;
+ vactive = <480>;
+ vback-porch = <23>;
+ vfront-porch = <1>;
+ vsync-len = <4>;
+ };
+ svga_timings: 800x600 at 56 {
+ clock-frequency = <37500000>;
+ hactive = <800>;
+ hback-porch = <140>;
+ hfront-porch = <40>;
+ hsync-len = <128>;
+ vactive = <600>;
+ vback-porch = <23>;
+ vfront-porch = <1>;
+ vsync-len = <4>;
+ };
+ };
+ };
};
&pmx_core {
@@ -251,3 +310,7 @@
&ddrctl {
status = "okay";
};
+
+&display {
+ status = "okay";
+};
--
2.9.3
^ permalink raw reply related
* [PATCH] ARM: davinci: da850: Fix pwm name matching
From: David Lechner @ 2016-10-31 14:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b4f6970b-5723-d1ed-088e-3c07129a005f@ti.com>
On 10/31/2016 05:18 AM, Sekhar Nori wrote:
> On Tuesday 25 October 2016 11:24 PM, David Lechner wrote:
>> This fixes pwm name matching for DA850 familiy devices. When using device
>> tree, the da850_auxdata_lookup[] table caused pwm devices to have the exact
>> same name, which caused errors when trying to register the devices.
>>
>> The names for clock matching in da850_clks[] also have to be updated to
>> to exactly match in order for the clock lookup to work correctly.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>>
>> Tested working on LEGO MINDSTORMS EV3.
>>
>>
>> arch/arm/mach-davinci/da850.c | 10 +++++++---
>> arch/arm/mach-davinci/da8xx-dt.c | 10 +++++-----
>> 2 files changed, 12 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
>> index ed3d0e9..6b78a8f 100644
>> --- a/arch/arm/mach-davinci/da850.c
>> +++ b/arch/arm/mach-davinci/da850.c
>> @@ -510,9 +510,13 @@ static struct clk_lookup da850_clks[] = {
>> CLK("vpif", NULL, &vpif_clk),
>> CLK("ahci_da850", NULL, &sata_clk),
>> CLK("davinci-rproc.0", NULL, &dsp_clk),
>> - CLK("ehrpwm", "fck", &ehrpwm_clk),
>> - CLK("ehrpwm", "tbclk", &ehrpwm_tbclk),
>> - CLK("ecap", "fck", &ecap_clk),
>> + CLK("ehrpwm.0", "fck", &ehrpwm_clk),
>> + CLK("ehrpwm.0", "tbclk", &ehrpwm_tbclk),
>> + CLK("ehrpwm.1", "fck", &ehrpwm_clk),
>> + CLK("ehrpwm.1", "tbclk", &ehrpwm_tbclk),
>> + CLK("ecap.0", "fck", &ecap_clk),
>> + CLK("ecap.1", "fck", &ecap_clk),
>> + CLK("ecap.2", "fck", &ecap_clk),
>
> This has exposed a limitation of DaVinci clock framework. The struct clk
> are stored as a linked list themselves. So a node repeating in the table
> above will create a loop in the linked list. This is easily seen on the
> LCDK board. davinci_clk_disable_unused() never returns. PWMs are unused
> on that board.
>
> There is no "simple" solution to this AFAICS. One solution is to
> separate the iterator from the clock hardware structure and use struct
> clk_hw available in struct clk_lookup.
>
> Or move DaVinci to common clock framework. This is of course preferred
> but much more involved as all 6 supported SoCs have to be moved together.
>
> Thanks,
> Sekhar
>
>
The simple solution for now could be to make child clocks for each of
these that simply enable the parent clock. e.g. ehrpwm0_clk and
ehpwm1_clk are children of ehrpwm_clk, etc.
Looking at da830.c, it looks like the solution was to make multiple
clocks that use the same LPSC, but this does not seem right to me.
^ permalink raw reply
* [RFC] fpga: Pull checks for supported operations into framework
From: Moritz Fischer @ 2016-10-31 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477851123-17686-1-git-send-email-moritz.fischer@ettus.com>
Found a couple of issues, will resubmit after cleaning up. Feel free to add
general feedback on the idea anyways in the meantime. Sorry for double post.
On Sun, Oct 30, 2016 at 11:12 AM, Moritz Fischer
<moritz.fischer@ettus.com> wrote:
> Most of the drivers only support a subset of {PARTIAL, FULL}
> reconfiguration.
> Pull duplicate checks in each driver into the framework.
>
> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
> Cc: Alan Tull <atull@opensource.altera.com>
> Cc: Michal Simek <michal.simek@xilinx.com>
> Cc: S?ren Brinkmann <soren.brinkmann@xilinx.com>
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> ---
> Hi all,
>
> with the new drivers (ice40, altera-ps-spi) being submitted I've noticed
> we're duplicating this check over and over again,
> so I figured we might as well pull it into the framework.
>
> I'm not sure if there are gonna be other 'flags' we need to support
> in the short term (we talked about byte-swapping ...)
>
> Note: This patch goes on top of greg's char-misc-testing that already
> contains Alan's latest changes to support the A10 and won't apply
> to master.
>
> Cheers,
>
> Moritz
>
> ---
> drivers/fpga/fpga-mgr.c | 12 ++++++++++++
> drivers/fpga/socfpga-a10.c | 4 +++-
> drivers/fpga/socfpga.c | 3 ++-
> drivers/fpga/zynq-fpga.c | 3 ++-
> include/linux/fpga/fpga-mgr.h | 9 +++++++--
> 5 files changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
> index c58b4c4..85f17d8 100644
> --- a/drivers/fpga/fpga-mgr.c
> +++ b/drivers/fpga/fpga-mgr.c
> @@ -49,6 +49,11 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
> struct device *dev = &mgr->dev;
> int ret;
>
> + if (!(mgr->supported_flags & info->flags)) {
> + dev_err(dev, "Unsupported flags passed\n");
> + return -ENOTSUPP;
> + }
That condition is obviously garbage ...
> +
> /*
> * Call the low level driver's write_init function. This will do the
> * device-specific things to get the FPGA into the state where it is
> @@ -252,6 +257,7 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
> */
> int fpga_mgr_register(struct device *dev, const char *name,
> const struct fpga_manager_ops *mops,
> + u32 supported_flags,
> void *priv)
> {
> struct fpga_manager *mgr;
> @@ -268,6 +274,11 @@ int fpga_mgr_register(struct device *dev, const char *name,
> return -EINVAL;
> }
>
> + if (!supported_flags) {
> + dev_err(dev, "Attempt to register with no supported flags\n");
> + return -EINVAL;
> + }
> +
> mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
> if (!mgr)
> return -ENOMEM;
> @@ -282,6 +293,7 @@ int fpga_mgr_register(struct device *dev, const char *name,
>
> mgr->name = name;
> mgr->mops = mops;
> + mgr->supported_flags = supported_flags;
> mgr->priv = priv;
>
> /*
> diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
> index ccd9fb2..e7c82ff 100644
> --- a/drivers/fpga/socfpga-a10.c
> +++ b/drivers/fpga/socfpga-a10.c
> @@ -519,7 +519,9 @@ static int socfpga_a10_fpga_probe(struct platform_device *pdev)
> }
>
> return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
> - &socfpga_a10_fpga_mgr_ops, priv);
> + &socfpga_a10_fpga_mgr_ops,
> + FPGA_MGR_PARTIAL_RECONFIG,
> + priv);
> }
>
> static int socfpga_a10_fpga_remove(struct platform_device *pdev)
> diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
> index b6672e6..3285b7d 100644
> --- a/drivers/fpga/socfpga.c
> +++ b/drivers/fpga/socfpga.c
> @@ -582,7 +582,8 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
> return ret;
>
> return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
> - &socfpga_fpga_ops, priv);
> + &socfpga_fpga_ops, FPGA_MGR_FULL_RECONFIG,
> + priv);
> }
>
> static int socfpga_fpga_remove(struct platform_device *pdev)
> diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
> index 249682e..1dabd25 100644
> --- a/drivers/fpga/zynq-fpga.c
> +++ b/drivers/fpga/zynq-fpga.c
> @@ -413,6 +413,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
> struct zynq_fpga_priv *priv;
> struct resource *res;
> int err;
> + u32 flags = FPGA_MGR_FULL_RECONFIG | FPGA_MGR_PARTIAL_RECONFIG;
>
> priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> if (!priv)
> @@ -465,7 +466,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
> clk_disable(priv->clk);
>
> err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
> - &zynq_fpga_ops, priv);
> + &zynq_fpga_ops, flags, priv);
> if (err) {
> dev_err(dev, "unable to register FPGA manager");
> clk_unprepare(priv->clk);
> diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
> index 040b86d..4f4bcf2 100644
> --- a/include/linux/fpga/fpga-mgr.h
> +++ b/include/linux/fpga/fpga-mgr.h
> @@ -64,9 +64,12 @@ enum fpga_mgr_states {
>
> /*
> * FPGA Manager flags
> + * FPGA_MGR_FULL_RECONFIG: do full reconfiguration if supported
> * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
> */
> -#define FPGA_MGR_PARTIAL_RECONFIG BIT(0)
> +#define FPGA_MGR_FULL_RECONFIG BIT(0)
> +#define FPGA_MGR_PARTIAL_RECONFIG BIT(1)
> +#define FPGA_MGR_EXTERNAL_CONFIG BIT(2)
On second thought the FULL_RECONFIG is the same as !PARTIAL_RECONFIG,
so useless ..
>
> /**
> * struct fpga_image_info - information specific to a FPGA image
> @@ -119,6 +122,7 @@ struct fpga_manager {
> enum fpga_mgr_states state;
> const struct fpga_manager_ops *mops;
> void *priv;
> + u32 supported_flags;
> };
>
> #define to_fpga_manager(d) container_of(d, struct fpga_manager, dev)
> @@ -135,7 +139,8 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
> void fpga_mgr_put(struct fpga_manager *mgr);
>
> int fpga_mgr_register(struct device *dev, const char *name,
> - const struct fpga_manager_ops *mops, void *priv);
> + const struct fpga_manager_ops *mops, u32 supported_flags,
> + void *priv);
>
> void fpga_mgr_unregister(struct device *dev);
>
> --
> 2.4.11
>
Cheers,
Moritz
^ 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