* Re: [PATCH v2 1/2] devicetree: i2c-hid: Add Wacom digitizer + regulator support
From: Jiri Kosina @ 2016-12-09 14:36 UTC (permalink / raw)
To: Rob Herring
Cc: Dmitry Torokhov, Benjamin Tissoires, Doug Anderson, Brian Norris,
Caesar Wang, open list:ARM/Rockchip SoC...,
linux-input@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Mark Rutland
In-Reply-To: <CAL_JsqKu0yhLVyEjcZs_rn=VqM9O4F_VMhOkfhEEvbYAjvWSTg@mail.gmail.com>
On Thu, 8 Dec 2016, Rob Herring wrote:
> > And if tomorrow there is Elan device that is drop-in compatible (same
> > connector, etc) with Wacom i2c-hid, will you ask for Elan-specific
> > binding? Atmel? Weida? They all need to be powered up ultimately.
>
> Yes, I will.
What advantage does that bring?
> That in no way means the OS driver has to know about each and every one.
> If they can all claim compatibility with Wacom (including power
> control), then they can have a Wacom compatible string too. Or you can
> just never tell me that there's a different manufacturer and I won't
> care as long you don't need different control. But soon as a device
> needs another power rail, GPIO or different timing, then you'd better
> have a new compatible string.
Again, I simply don't understand what advantage does the aproach you are
trying to use bring.
HID over I2C is a generic protocol. Sure, we need to have quirks for
device-specific bugs, and in such cases enumerate particular devices. But
we don't need DT for that at all.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2 1/2] devicetree: i2c-hid: Add Wacom digitizer + regulator support
From: Rob Herring @ 2016-12-09 14:36 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benjamin Tissoires, Doug Anderson, Brian Norris, Jiri Kosina,
Caesar Wang, open list:ARM/Rockchip SoC...,
linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Mark Rutland
In-Reply-To: <20161208181257.GA12133@dtor-ws>
On Thu, Dec 8, 2016 at 12:12 PM, Dmitry Torokhov
<dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Thu, Dec 08, 2016 at 10:26:41AM -0600, Rob Herring wrote:
>> On Thu, Dec 8, 2016 at 10:13 AM, Dmitry Torokhov
>> <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> > On December 8, 2016 8:03:06 AM PST, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>> >>On Thu, Dec 8, 2016 at 9:41 AM, Benjamin Tissoires
>> >><benjamin.tissoires-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>> >>> On Dec 06 2016 or thereabouts, Doug Anderson wrote:
[...]
>> >>>> When you specify an SDIO bus you don't specify what kind of card
>> >>will
>> >>>> be present, you just say "I've got an SDIO bus" and then the
>> >>specific
>> >>>> device underneath is probed. Here we've say "I've got an i2c
>> >>>> connection intended for HID" and then you probe for the HID device
>> >>>> that's on the connection.
>> >>>>
>> >>>> Also for an SDIO bus, you've possibly got a regulators / GPIOs /
>> >>>> resets that need to be controlled, but the specific details of these
>> >>>> regulator / GPIOs / resets are specific to a given board and not
>> >>>> necessarily a given SDIO device.
>> >>>>
>> >>>
>> >>> Thanks Doug for this. I had the feeling this wasn't right, but you
>> >>> actually managed to put the words on it. If it's a board problem (if
>> >>> you switch the wacom device with an other HID over I2C device and you
>> >>> still need the same regulator/timing parameters), then this should
>> >>> simply be mentioned on the patch.
>> >>>
>> >>> So Brian, could you please respin the series and remve the Wacom
>> >>> mentions and explain that it is required for the board itself?
>> >>
>> >>In advance, NAK.
>> >>
>> >>This is not how DT works. Either this binding needs a Wacom compatible
>> >>or don't use DT.
>> >>
>> >
>> > And if tomorrow there is Elan device that is drop-in compatible
>> > (same connector, etc) with Wacom i2c-hid, will you ask for
>> > Elan-specific binding? Atmel? Weida? They all need to be powered up
>> > ultimately.
>>
>> Yes, I will. Anyone who's worked on drop-in or pin compatible parts
>> knows there's no such thing.
>
> And yet we are shipping quite a few of Chromebooks with touchpads that
> are dual-sourced and can be exchanged at any time without any changes to
> the software (be it kernel or firmware).
>
>>
>> That in no way means the OS driver has to know about each and every
>> one. If they can all claim compatibility with Wacom (including power
>> control), then they can have a Wacom compatible string too. Or you can
>> just never tell me that there's a different manufacturer and I won't
>> care as long you don't need different control. But soon as a device
>> needs another power rail, GPIO or different timing, then you'd better
>> have a new compatible string.
>
> That I simply do not understand. We routinely enhance bindings because
> the devices get used on different boards that expose more or less
> connections. I.e. quite often we start with a device whose rails are
> controlled by the firmware, and so the binding only contains register
> and interrupt data. Then we come across board that exposes reset GPIO
> and we add that to the binding (bit we do not invent new compatible
> string just because there is GPIO now). Then we get a board that
> actually wants kernel to control power to the chip and we add a
> regulator. Non-optional, mind you, because we rely on the regulator
> system to give us a dummy one if it is not described by the
> firmware/other means. And then we get another board that exposes another
> power rail (let's say 3.3V to the panel whereas the previous one did not
> use it). And we add another regulator binding. All this time we have
> the same compatibility string.
All this I agree with, but it almost always starts with a compatible
that matches the device, not a compatible for the protocol. When
adding control for different devices diverge, then they need different
compatibles. Ideally, we'd start with all the supplies and control
lines defined for a binding, so we don't have so much evolving of
bindings. But obviously we can't always get things 100% complete to
start with, so we have to let them evolve. And I can't go read every
datasheet, but I do go read them sometimes for reviews.
> So in this case we finally got to the point where we admit that devices
> speaking HID over I2C do have power rails; we simply did not need to
> control them before. The same Wacom digitizer, that you now demand to
> add a compatible for, may have been used in other boards where power
> rails were either turned on by the firmware at boot time and left on
> until the board is shutdown, or ACPI was controlling them (via _ON/_OFF
> methods), or there was some other magic. Having a supply and ability to
> control the time it takes to bring the device into operating state is in
> no way Wacom-specific, so why new compatibility instead of enhancing
> the current binding?
A new compatible is enhancing the binding IMO. I'm just saying you
need both the compatible and the added properties. Whether the power
on delay should be a property or implied by the compatible is somewhat
debatable, but I'm okay with having it because we already do on other
bindings. What I'm not okay with is "simple" or "generic" bindings
that continually evolve with additional properties to handle more and
more complex cases. DT is not a scripting language. This has been
discussed countless times before...
> And on top of that, currently multiple compatible strings are utterly
> broken with regard to module loading (you only emit modalias for the
> first component), so having DTS with multiples does not work well in
> real life.
Sounds like this should be a fixable problem.
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 v2 1/2] devicetree: i2c-hid: Add Wacom digitizer + regulator support
From: Rob Herring @ 2016-12-09 15:01 UTC (permalink / raw)
To: Jiri Kosina
Cc: Dmitry Torokhov, Benjamin Tissoires, Doug Anderson, Brian Norris,
Caesar Wang, open list:ARM/Rockchip SoC...,
linux-input@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Mark Rutland
In-Reply-To: <alpine.LNX.2.00.1612091532240.16984@cbobk.fhfr.pm>
On Fri, Dec 9, 2016 at 8:36 AM, Jiri Kosina <jikos@kernel.org> wrote:
> On Thu, 8 Dec 2016, Rob Herring wrote:
>
>> > And if tomorrow there is Elan device that is drop-in compatible (same
>> > connector, etc) with Wacom i2c-hid, will you ask for Elan-specific
>> > binding? Atmel? Weida? They all need to be powered up ultimately.
>>
>> Yes, I will.
>
> What advantage does that bring?
>
>> That in no way means the OS driver has to know about each and every one.
>> If they can all claim compatibility with Wacom (including power
>> control), then they can have a Wacom compatible string too. Or you can
>> just never tell me that there's a different manufacturer and I won't
>> care as long you don't need different control. But soon as a device
>> needs another power rail, GPIO or different timing, then you'd better
>> have a new compatible string.
>
> Again, I simply don't understand what advantage does the aproach you are
> trying to use bring.
This is simply how DT works. HID-over-I2C devices are no different
than any other I2C device or any other component. You are not special.
> HID over I2C is a generic protocol.
DT describes h/w, not protocols.
> Sure, we need to have quirks for
> device-specific bugs, and in such cases enumerate particular devices. But
> we don't need DT for that at all.
When it is related to powering on the device you may need to know the
specific device in DT. Compatibles are like VID/PID for devices, a
unique identifier for the specific device. Having that does not to
prevent generic/common drivers. The same rules apply. You wouldn't
want different devices having the same VID/PID (surely that has never
happened) or only change a VID/PID when you find a bug. The same rules
apply for compatible strings. You should be able to apply quirks
without changing/adding compatible strings (or more generally, without
changing the dtb). Just like you wouldn't change a VID/PID for a
device only when you find a bug, you can't add/change a DT compatible.
BTW, As you do have a VID/PID, you could define a compatible string
syntax using VID/PID like is done for PCI and USB.
Rob
^ permalink raw reply
* [PATCH] rtc: pcf8563: Do not disable clk out by default
From: Volodymyr Bendiuga @ 2016-12-09 15:03 UTC (permalink / raw)
To: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA,
volodymyr.bendiuga-Re5JQEeQqe8AvxtiuMwx3w
Cc: Mattias Walström, Volodymyr Bendiuga
From: Mattias Walström <mattias.walstrom-qeDNsGSBLoYwFerOooGFRg@public.gmane.org>
Commit a39a6405d5f949bc651694028a disables CLKOUT of
the rtc after power-up to improve power consumption.
This is very useful, but some designs do require to
have the rtc on all the time, otherwise devices will
be bricked. Therefore this patch is a compromise that
works for both cases, where the default case is when
CLKOUT is on. If one wants to disable the CLKOUT,
clkout-allow-disable can be added to devicetree's rtc node.
Signed-off-by: Volodymyr Bendiuga <volodymyr.bendiuga-qeDNsGSBLoYwFerOooGFRg@public.gmane.org>
---
Documentation/devicetree/bindings/rtc/pcf8563.txt | 1 +
drivers/rtc/rtc-pcf8563.c | 11 +++--------
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/Documentation/devicetree/bindings/rtc/pcf8563.txt b/Documentation/devicetree/bindings/rtc/pcf8563.txt
index 086c998..0b06a36 100644
--- a/Documentation/devicetree/bindings/rtc/pcf8563.txt
+++ b/Documentation/devicetree/bindings/rtc/pcf8563.txt
@@ -7,6 +7,7 @@ see: Documentation/devicetree/bindings/i2c/trivial-admin-guide/devices.rst
Optional property:
- #clock-cells: Should be 0.
+- clkout-allow-disable: Allow the CLKOUT to be disabled if not used.
- clock-output-names:
overwrite the default clock name "pcf8563-clkout"
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 1227cea..1489ee9 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -519,18 +519,13 @@ static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563)
struct device_node *node = client->dev.of_node;
struct clk *clk;
struct clk_init_data init;
- int ret;
- unsigned char buf;
-
- /* disable the clkout output */
- buf = 0;
- ret = pcf8563_write_block_data(client, PCF8563_REG_CLKO, 1, &buf);
- if (ret < 0)
- return ERR_PTR(ret);
init.name = "pcf8563-clkout";
init.ops = &pcf8563_clkout_ops;
+
+ /* disable the clkout output only if it is allowed in devicetree */
init.flags = 0;
+ init.flags |= !of_property_read_bool(node, "clkout-allow-disable") ? CLK_IGNORE_UNUSED : 0;
init.parent_names = NULL;
init.num_parents = 0;
pcf8563->clkout_hw.init = &init;
--
2.7.4
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* Re: [PATCH v2] mtd/spi-nor: Add SPI memory controllers for Aspeed SoCs
From: Cédric Le Goater @ 2016-12-09 15:46 UTC (permalink / raw)
To: Cyrille Pitchen, Marek Vasut, linux-mtd
Cc: Mark Rutland, Boris Brezillon, devicetree, Richard Weinberger,
Rob Herring, Joel Stanley, Brian Norris, David Woodhouse
In-Reply-To: <fbe09cbd-66da-a723-8ac1-4fa10c690388@atmel.com>
Hello Cyrille
On 12/09/2016 03:13 PM, Cyrille Pitchen wrote:
> Le 09/12/2016 à 15:03, Marek Vasut a écrit :
>> On 12/09/2016 02:37 PM, Cyrille Pitchen wrote:
>>> Hi Cedric,
>>>
>>> Le 09/11/2016 à 11:42, Cédric Le Goater a écrit :
>>>> This driver adds mtd support for spi-nor attached to either or both of
>>>> the Firmware Memory Controller or the SPI Flash Controller (AST2400
>>>> only).
>>>>
>>>> The SMC controllers on the Aspeed AST2500 SoC are very similar to the
>>>> ones found on the AST2400. The differences are on the number of
>>>> supported flash modules and their default mappings in the SoC address
>>>> space.
>>>>
>>>> The Aspeed AST2500 has one SPI controller for the BMC firmware and two
>>>> for the host firmware. All controllers have now the same set of
>>>> registers compatible with the AST2400 FMC controller and the legacy
>>>> 'SMC' controller is fully gone.
>>>>
>>>> Each controller has a memory range on which it maps its flash module
>>>> slaves. Each slave is assigned a memory window for its mapping that
>>>> can be changed at bootime with the Segment Address Register.
>>>>
>>>> Each SPI flash slave can then be accessed in two modes: Command and
>>>> User. When in User mode, accesses to the memory segment of the slaves
>>>> are translated in SPI transfers. When in Command mode, the HW
>>>> generates the SPI commands automatically and the memory segment is
>>>> accessed as if doing a MMIO.
>>>>
>>>> Currently, only the User mode is supported. Command mode needs a
>>>> little more work to check that the memory window on the AHB bus fits
>>>> the module size.
>>>>
>>>> Based on previous work from Milton D. Miller II <miltonm@us.ibm.com>
>>>>
>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>> ---
>>> [...]
>>>> +static int aspeed_smc_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
>>>> +{
>>>> + struct aspeed_smc_chip *chip = nor->priv;
>>>> +
>>>> + mutex_lock(&chip->controller->mutex);
>>>> +
>>>> + aspeed_smc_start_user(nor);
>>>> + aspeed_smc_write_to_ahb(chip->base, &opcode, 1);
>>>> + aspeed_smc_read_from_ahb(buf, chip->base, len);
>>>> + aspeed_smc_stop_user(nor);
>>>> +
>>>> + mutex_unlock(&chip->controller->mutex);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int aspeed_smc_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
>>>> + int len)
>>>> +{
>>>> + struct aspeed_smc_chip *chip = nor->priv;
>>>> +
>>>> + mutex_lock(&chip->controller->mutex);
>>>> +
>>>> + aspeed_smc_start_user(nor);
>>>> + aspeed_smc_write_to_ahb(chip->base, &opcode, 1);
>>>> + aspeed_smc_write_to_ahb(chip->base, buf, len);
>>>> + aspeed_smc_stop_user(nor);
>>>> +
>>>> + mutex_unlock(&chip->controller->mutex);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>> [...]
>>>> +static ssize_t aspeed_smc_read_user(struct spi_nor *nor, loff_t from,
>>>> + size_t len, u_char *read_buf)
>>>> +{
>>>> + struct aspeed_smc_chip *chip = nor->priv;
>>>> +
>>>> + mutex_lock(&chip->controller->mutex);
>>>> +
>>>> + aspeed_smc_start_user(nor);
>>>> + aspeed_smc_send_cmd_addr(nor, nor->read_opcode, from);
>>>> + aspeed_smc_read_from_ahb(read_buf, chip->base, len);
>>>> + aspeed_smc_stop_user(nor);
>>>> +
>>>> + mutex_unlock(&chip->controller->mutex);
>>>> +
>>>> + return len;
>>>> +}
>>>> +
>>>> +static ssize_t aspeed_smc_write_user(struct spi_nor *nor, loff_t to, size_t len,
>>>> + const u_char *write_buf)
>>>> +{
>>>> + struct aspeed_smc_chip *chip = nor->priv;
>>>> +
>>>> + mutex_lock(&chip->controller->mutex);
>>>> +
>>>> + aspeed_smc_start_user(nor);
>>>> + aspeed_smc_send_cmd_addr(nor, nor->program_opcode, to);
>>>> + aspeed_smc_write_to_ahb(chip->base, write_buf, len);
>>>> + aspeed_smc_stop_user(nor);
>>>> +
>>>> + mutex_unlock(&chip->controller->mutex);
>>>> +
>>>> + return len;
>>>> +}
>>>
>>> As I've explained in review of the series v1, the chip->controller->mutex
>>> seems to be used only by aspeed_smc_read_reg(), aspeed_smc_write_reg(),
>>> aspeed_smc_read_user() and aspeed_smc_write_user(), the driver
>>> implementations of nor->read_reg(), nor->write_reg(), nor->read() and
>>> nor->write().
>>>
>>> This driver locks the mutex at the very beginning of each of those
>>> functions and unlocks the mutex before returning.
>>>
>>> So my understanding is that you use this mutex to prevent
>>> aspeed_smc_[read|write]_[reg|user]() from being called concurrently.
>>>
>>> If so, the spi-nor framework already takes care of this issue with the
>>> couple of functions: spi_nor_lock_and_prep() / spi_nor_unlock_and_unprep().
>>>
>>> Indeed, spi_nor_lock_and_prep() is called on entering and
>>> spi_nor_unlock_and_unprep() on exiting each of the following functions:
>>> - mtd->_read = spi_nor_read
>>> - mtd->_write = spi_nor_write / sst_write
>>> - mtd->_erase = spi_nor_erase
>>> - mtd->_lock = spi_nor_lock
>>> - mtd->_unlock = spi_nor_unlock
>>> - mtd->_is_lock = spi_nor_is_locked
>>>
>>> Except for spi_nor_scan(), which is called once for all during the probe
>>> and before registering the mtd_info structure, only the above
>>> mtd->_<handlers> call the nor->read_reg, nor->write_reg, nor->read,
>>> nor->erase and nor->write spi-nor handlers.
>>> So your spi-nor / aspeed_smc_<handlers> are always protected from
>>> concurrent access by the mutex locked in spi_nor_lock_and_prep().
>>>
>>> So don't worry about concurrent access issue, the spi-nor framework takes
>>> care of you :)
>>
>> Does it take care of me even if I have multiple flashes ? I recall I had
>> to put mutexes into prepare and unprepare myself in the CQSPI driver to
>> prevent problems when accessing two flashes simultaneously.
>>
>>
>
> Well indeed you're right, with multiple flashes I guess the driver will
> need to use an additional mutex. Then it can be placed either in each
> read_reg/write_reg/read/write handlers like Cedric did or in
> prepare/unprepare handlers like Marek did in the Cadence Quad SPI drivers.
> Both solutions work and are fine for me.
So I will go for the prepare/unprepare handler solution for now.
Thanks,
C.
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
* [PATCH v2 1/2] backlight arcxcnn add support for ArcticSand devices
From: Olimpiu Dejeu @ 2016-12-09 15:49 UTC (permalink / raw)
To: robh-DgEjT+Ai2ygdnm+yROfE0A
Cc: lee.jones-QSEj5FYQhm4dnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
jingoohan1-Re5JQEeQqe8AvxtiuMwx3w, bdodge-eV7fy4qpoLhpLGFMi4vTTA,
Olimpiu Dejeu
Signed-off-by: Olimpiu Dejeu <olimpiu-eV7fy4qpoLhpLGFMi4vTTA@public.gmane.org>
---
v1 => v2:
- Removed "magic numbers" to initialize registers
- Cleaned up device tree bindings
- Fixed code style to address comments and pass "checkpatch"
- Removed unneeded debug and testing code
drivers/video/backlight/Kconfig | 7 +
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/arcxcnn_bl.c | 458 +++++++++++++++++++++++++++++++++++
include/linux/i2c/arcxcnn.h | 51 ++++
4 files changed, 517 insertions(+)
create mode 100644 drivers/video/backlight/arcxcnn_bl.c
create mode 100644 include/linux/i2c/arcxcnn.h
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5ffa4b4..4e1d2ad 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -460,6 +460,13 @@ config BACKLIGHT_BD6107
help
If you have a Rohm BD6107 say Y to enable the backlight driver.
+config BACKLIGHT_ARCXCNN
+ tristate "Backlight driver for the Arctic Sands ARCxCnnnn family"
+ depends on I2C
+ help
+ If you have an ARCxCnnnn family backlight say Y to enable
+ the backlight driver.
+
endif # BACKLIGHT_CLASS_DEVICE
endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 16ec534..8905129 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
+obj-$(CONFIG_BACKLIGHT_ARCXCNN) += arcxcnn_bl.o
diff --git a/drivers/video/backlight/arcxcnn_bl.c b/drivers/video/backlight/arcxcnn_bl.c
new file mode 100644
index 0000000..fcebbd6
--- /dev/null
+++ b/drivers/video/backlight/arcxcnn_bl.c
@@ -0,0 +1,458 @@
+/*
+ * Backlight driver for ArcticSand ARC_X_C_0N_0N Devices
+ *
+ * Copyright 2016 ArcticSand, Inc.
+ * Author : Brian Dodge <bdodge-eV7fy4qpoLhpLGFMi4vTTA@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include "linux/i2c/arcxcnn.h"
+
+#define ARCXCNN_CMD 0x00 /* Command Register */
+#define ARCXCNN_CMD_STDBY 0x80 /* I2C Standby */
+#define ARCXCNN_CMD_RESET 0x40 /* Reset */
+#define ARCXCNN_CMD_BOOST 0x10 /* Boost */
+#define ARCXCNN_CMD_OVP_MASK 0x0C /* --- Over Voltage Threshold */
+#define ARCXCNN_CMD_OVP_XXV 0x0C /* <rsvrd> Over Voltage Threshold */
+#define ARCXCNN_CMD_OVP_20V 0x08 /* 20v Over Voltage Threshold */
+#define ARCXCNN_CMD_OVP_24V 0x04 /* 24v Over Voltage Threshold */
+#define ARCXCNN_CMD_OVP_31V 0x00 /* 31.4v Over Voltage Threshold */
+#define ARCXCNN_CMD_EXT_COMP 0x01 /* part (0) or full (1) ext. comp */
+
+#define ARCXCNN_CONFIG 0x01 /* Configuration */
+#define ARCXCNN_STATUS1 0x02 /* Status 1 */
+#define ARCXCNN_STATUS2 0x03 /* Status 2 */
+#define ARCXCNN_FADECTRL 0x04 /* Fading Control */
+#define ARCXCNN_ILED_CONFIG 0x05 /* ILED Configuration */
+#define ARCXCNN_ILED_DIM_PWM 0x00 /* config dim mode pwm */
+#define ARCXCNN_ILED_DIM_INT 0x04 /* config dim mode internal */
+#define ARCXCNN_LEDEN 0x06 /* LED Enable Register */
+#define ARCXCNN_LEDEN_ISETEXT 0x80 /* Full-scale current set extern */
+#define ARCXCNN_LEDEN_MASK 0x3F /* LED string enables mask */
+#define ARCXCNN_LEDEN_BITS 0x06 /* Bits of LED string enables */
+#define ARCXCNN_LEDEN_LED1 0x01
+#define ARCXCNN_LEDEN_LED2 0x02
+#define ARCXCNN_LEDEN_LED3 0x04
+#define ARCXCNN_LEDEN_LED4 0x08
+#define ARCXCNN_LEDEN_LED5 0x10
+#define ARCXCNN_LEDEN_LED6 0x20
+
+#define ARCXCNN_WLED_ISET_LSB 0x07 /* LED ISET LSB (in upper nibble) */
+#define ARCXCNN_WLED_ISET_LSB_SHIFT 0x04 /* ISET LSB Left Shift */
+#define ARCXCNN_WLED_ISET_MSB 0x08 /* LED ISET MSB (8 bits) */
+
+#define ARCXCNN_DIMFREQ 0x09
+#define ARCXCNN_COMP_CONFIG 0x0A
+#define ARCXCNN_FILT_CONFIG 0x0B
+#define ARCXCNN_IMAXTUNE 0x0C
+#define ARCXCNN_ID_MSB 0x1E
+#define ARCXCNN_ID_LSB 0x1F
+
+#define MAX_BRIGHTNESS 4095
+
+static int s_no_reset_on_remove;
+module_param_named(noreset, s_no_reset_on_remove, int, 0644);
+MODULE_PARM_DESC(noreset, "No reset on module removal");
+
+static int s_ibright = 60;
+module_param_named(ibright, s_ibright, int, 0644);
+MODULE_PARM_DESC(ibright, "Initial brightness (when no plat data)");
+
+static int s_ileden = ARCXCNN_LEDEN_MASK;
+module_param_named(ileden, s_ileden, int, 0644);
+MODULE_PARM_DESC(ileden, "Initial LED String Enables (when no plat data)");
+
+struct arcxcnn {
+ char chipname[64];
+ struct i2c_client *client;
+ struct backlight_device *bl;
+ struct device *dev;
+ struct arcxcnn_platform_data *pdata;
+};
+
+static int arcxcnn_update_bit(struct arcxcnn *lp, u8 reg, u8 mask, u8 data)
+{
+ int ret;
+ u8 tmp;
+
+ ret = i2c_smbus_read_byte_data(lp->client, reg);
+ if (ret < 0) {
+ dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
+ return ret;
+ }
+
+ tmp = (u8)ret;
+ tmp &= ~mask;
+ tmp |= data & mask;
+
+ return i2c_smbus_write_byte_data(lp->client, reg, tmp);
+}
+
+static int arcxcnn_set_brightness(struct arcxcnn *lp, u32 brightness)
+{
+ int ret;
+ u8 val;
+
+ /* lower nibble of brightness goes in upper nibble of LSB register */
+ val = (brightness & 0xF) << ARCXCNN_WLED_ISET_LSB_SHIFT;
+ ret = i2c_smbus_write_byte_data(lp->client, ARCXCNN_WLED_ISET_LSB, val);
+ if (ret < 0)
+ return ret;
+
+ /* remaining 8 bits of brightness go in MSB register */
+ val = (brightness >> 4);
+ ret = i2c_smbus_write_byte_data(lp->client, ARCXCNN_WLED_ISET_MSB, val);
+
+ return ret;
+}
+
+static int arcxcnn_bl_update_status(struct backlight_device *bl)
+{
+ struct arcxcnn *lp = bl_get_data(bl);
+ u32 brightness = bl->props.brightness;
+
+ if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
+ brightness = 0;
+
+ arcxcnn_set_brightness(lp, brightness);
+
+ /* set power-on/off/save modes */
+ if (bl->props.power == 0)
+ /* take out of standby */
+ arcxcnn_update_bit(lp, ARCXCNN_CMD, ARCXCNN_CMD_STDBY, 0);
+ else
+ /* place in low-power standby mode */
+ arcxcnn_update_bit(lp, ARCXCNN_CMD,
+ ARCXCNN_CMD_STDBY, ARCXCNN_CMD_STDBY);
+ return 0;
+}
+
+static const struct backlight_ops arcxcnn_bl_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = arcxcnn_bl_update_status,
+};
+
+static int arcxcnn_backlight_register(struct arcxcnn *lp)
+{
+ struct backlight_properties *props;
+ const char *name = lp->pdata->name ? : "arctic_bl";
+
+ props = devm_kzalloc(lp->dev, sizeof(*props), GFP_KERNEL);
+ if (!props)
+ return -ENOMEM;
+
+ memset(props, 0, sizeof(props));
+ props->type = BACKLIGHT_PLATFORM;
+ props->max_brightness = MAX_BRIGHTNESS;
+
+ if (lp->pdata->initial_brightness > props->max_brightness)
+ lp->pdata->initial_brightness = props->max_brightness;
+
+ props->brightness = lp->pdata->initial_brightness;
+
+ lp->bl = devm_backlight_device_register(lp->dev, name, lp->dev, lp,
+ &arcxcnn_bl_ops, props);
+
+ if (IS_ERR(lp->bl))
+ return PTR_ERR(lp->bl);
+
+ return 0;
+}
+
+static ssize_t arcxcnn_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct arcxcnn *lp = dev_get_drvdata(dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%s\n", lp->chipname);
+}
+
+static ssize_t arcxcnn_leden_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct arcxcnn *lp = dev_get_drvdata(dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%02X\n", lp->pdata->leden);
+}
+
+static ssize_t arcxcnn_leden_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ struct arcxcnn *lp = dev_get_drvdata(dev);
+ unsigned long leden;
+
+ if (kstrtoul(buf, 0, &leden))
+ return 0;
+
+ if (leden != lp->pdata->leden) {
+ /* don't allow 0 for leden, use power to turn all off */
+ if (leden == 0)
+ return -EINVAL;
+ lp->pdata->leden = leden & ARCXCNN_LEDEN_MASK;
+ arcxcnn_update_bit(lp, ARCXCNN_LEDEN,
+ ARCXCNN_LEDEN_MASK, lp->pdata->leden);
+ }
+
+ return len;
+}
+
+static DEVICE_ATTR(chip_id, 0444, arcxcnn_chip_id_show, NULL);
+static DEVICE_ATTR(leden, 0664, arcxcnn_leden_show, arcxcnn_leden_store);
+
+static struct attribute *arcxcnn_attributes[] = {
+ &dev_attr_chip_id.attr,
+ &dev_attr_leden.attr,
+ NULL,
+};
+
+static const struct attribute_group arcxcnn_attr_group = {
+ .attrs = arcxcnn_attributes,
+};
+
+static void arcxcnn_parse_dt(struct arcxcnn *lp)
+{
+ struct device *dev = lp->dev;
+ struct device_node *node = dev->of_node;
+ u32 prog_val, num_entry, entry, sources[ARCXCNN_LEDEN_BITS];
+ int ret;
+
+ /* device tree entry isn't required, defaults are OK */
+ if (!node)
+ return;
+
+ ret = of_property_read_string(node, "label", &lp->pdata->name);
+ if (ret < 0)
+ lp->pdata->name = NULL;
+
+ ret = of_property_read_u32(node, "default-brightness", &prog_val);
+ if (ret == 0)
+ lp->pdata->initial_brightness = prog_val;
+
+ ret = of_property_read_u32(node, "arc,led-config-0", &prog_val);
+ if (ret == 0)
+ lp->pdata->led_config_0 = (u8)prog_val;
+
+ ret = of_property_read_u32(node, "arc,led-config-1", &prog_val);
+ if (ret == 0)
+ lp->pdata->led_config_1 = (u8)prog_val;
+
+ ret = of_property_read_u32(node, "arc,dim-freq", &prog_val);
+ if (ret == 0)
+ lp->pdata->dim_freq = (u8)prog_val;
+
+ ret = of_property_read_u32(node, "arc,comp-config", &prog_val);
+ if (ret == 0)
+ lp->pdata->comp_config = (u8)prog_val;
+
+ ret = of_property_read_u32(node, "arc,filter-config", &prog_val);
+ if (ret == 0)
+ lp->pdata->filter_config = (u8)prog_val;
+
+ ret = of_property_read_u32(node, "arc,trim-config", &prog_val);
+ if (ret == 0)
+ lp->pdata->trim_config = (u8)prog_val;
+
+ ret = of_property_count_u32_elems(node, "led-sources");
+ if (ret < 0) {
+ lp->pdata->leden = ARCXCNN_LEDEN_MASK; /* all on is default */
+ } else {
+ num_entry = ret;
+ if (num_entry > ARCXCNN_LEDEN_BITS)
+ num_entry = ARCXCNN_LEDEN_BITS;
+
+ ret = of_property_read_u32_array(node, "led-sources", sources,
+ num_entry);
+ if (ret < 0) {
+ dev_err(dev, "led-sources node is invalid.\n");
+ } else {
+ u8 onbit;
+
+ lp->pdata->leden = 0;
+
+ /* for each enable in source, set bit in led enable */
+ for (entry = 0; entry < num_entry; entry++) {
+ onbit = 1 << sources[entry];
+ lp->pdata->leden |= onbit;
+ }
+ }
+ }
+}
+
+static int arcxcnn_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+ struct arcxcnn *lp;
+ int ret;
+ u8 regval;
+ u16 chipid;
+
+ if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ lp = devm_kzalloc(&cl->dev, sizeof(*lp), GFP_KERNEL);
+ if (!lp)
+ return -ENOMEM;
+
+ lp->client = cl;
+ lp->dev = &cl->dev;
+ lp->pdata = dev_get_platdata(&cl->dev);
+
+ /* reset the device */
+ i2c_smbus_write_byte_data(lp->client,
+ ARCXCNN_CMD, ARCXCNN_CMD_RESET);
+
+ /* read device ID */
+ regval = i2c_smbus_read_byte_data(lp->client, ARCXCNN_ID_MSB);
+ chipid = regval;
+ chipid <<= 8;
+
+ regval = i2c_smbus_read_byte_data(lp->client, ARCXCNN_ID_LSB);
+ chipid |= regval;
+
+ snprintf(lp->chipname, sizeof(lp->chipname),
+ "%s-%04X", id->name, chipid);
+
+ if (!lp->pdata) {
+ lp->pdata = devm_kzalloc(lp->dev,
+ sizeof(*lp->pdata), GFP_KERNEL);
+ if (!lp->pdata)
+ return -ENOMEM;
+
+ /* Setup defaults based on power-on defaults */
+ lp->pdata->name = NULL;
+ lp->pdata->initial_brightness = s_ibright;
+ lp->pdata->leden = s_ileden;
+
+ lp->pdata->led_config_0 = i2c_smbus_read_byte_data(
+ lp->client, ARCXCNN_FADECTRL);
+
+ lp->pdata->led_config_1 = i2c_smbus_read_byte_data(
+ lp->client, ARCXCNN_ILED_CONFIG);
+ /* insure dim mode is not default pwm */
+ lp->pdata->led_config_1 |= ARCXCNN_ILED_DIM_INT;
+
+ lp->pdata->dim_freq = i2c_smbus_read_byte_data(
+ lp->client, ARCXCNN_DIMFREQ);
+
+ lp->pdata->comp_config = i2c_smbus_read_byte_data(
+ lp->client, ARCXCNN_COMP_CONFIG);
+
+ lp->pdata->filter_config = i2c_smbus_read_byte_data(
+ lp->client, ARCXCNN_FILT_CONFIG);
+
+ lp->pdata->trim_config = i2c_smbus_read_byte_data(
+ lp->client, ARCXCNN_IMAXTUNE);
+
+ if (IS_ENABLED(CONFIG_OF))
+ arcxcnn_parse_dt(lp);
+ }
+
+ i2c_set_clientdata(cl, lp);
+
+ /* constrain settings to what is possible */
+ if (lp->pdata->initial_brightness > MAX_BRIGHTNESS)
+ lp->pdata->initial_brightness = MAX_BRIGHTNESS;
+
+ /* set initial brightness */
+ arcxcnn_set_brightness(lp, lp->pdata->initial_brightness);
+
+ /* set other register values directly */
+ i2c_smbus_write_byte_data(lp->client, ARCXCNN_FADECTRL,
+ lp->pdata->led_config_0);
+ i2c_smbus_write_byte_data(lp->client, ARCXCNN_ILED_CONFIG,
+ lp->pdata->led_config_1);
+ i2c_smbus_write_byte_data(lp->client, ARCXCNN_DIMFREQ,
+ lp->pdata->dim_freq);
+ i2c_smbus_write_byte_data(lp->client, ARCXCNN_COMP_CONFIG,
+ lp->pdata->comp_config);
+ i2c_smbus_write_byte_data(lp->client, ARCXCNN_FILT_CONFIG,
+ lp->pdata->filter_config);
+ i2c_smbus_write_byte_data(lp->client, ARCXCNN_IMAXTUNE,
+ lp->pdata->trim_config);
+
+ /* set initial LED Enables */
+ arcxcnn_update_bit(lp, ARCXCNN_LEDEN,
+ ARCXCNN_LEDEN_MASK, lp->pdata->leden);
+
+ ret = arcxcnn_backlight_register(lp);
+ if (ret) {
+ dev_err(lp->dev,
+ "failed to register backlight. err: %d\n", ret);
+ return ret;
+ }
+
+ ret = sysfs_create_group(&lp->dev->kobj, &arcxcnn_attr_group);
+ if (ret) {
+ dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
+ return ret;
+ }
+
+ backlight_update_status(lp->bl);
+
+ return 0;
+}
+
+static int arcxcnn_remove(struct i2c_client *cl)
+{
+ struct arcxcnn *lp = i2c_get_clientdata(cl);
+
+ if (!s_no_reset_on_remove) {
+ /* disable all strings */
+ i2c_smbus_write_byte_data(lp->client,
+ ARCXCNN_LEDEN, 0x00);
+ /* reset the device */
+ i2c_smbus_write_byte_data(lp->client,
+ ARCXCNN_CMD, ARCXCNN_CMD_RESET);
+ }
+ lp->bl->props.brightness = 0;
+
+ backlight_update_status(lp->bl);
+
+ sysfs_remove_group(&lp->dev->kobj, &arcxcnn_attr_group);
+
+ return 0;
+}
+
+static const struct of_device_id arcxcnn_dt_ids[] = {
+ { .compatible = "arc,arc2c0608" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, arcxcnn_dt_ids);
+
+static const struct i2c_device_id arcxcnn_ids[] = {
+ {"arc2c0608", ARC2C0608},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, arcxcnn_ids);
+
+static struct i2c_driver arcxcnn_driver = {
+ .driver = {
+ .name = "arcxcnn_bl",
+ .of_match_table = of_match_ptr(arcxcnn_dt_ids),
+ },
+ .probe = arcxcnn_probe,
+ .remove = arcxcnn_remove,
+ .id_table = arcxcnn_ids,
+};
+module_i2c_driver(arcxcnn_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Brian Dodge <bdodge-eV7fy4qpoLhpLGFMi4vTTA@public.gmane.org>");
+MODULE_DESCRIPTION("ARCXCNN Backlight driver");
diff --git a/include/linux/i2c/arcxcnn.h b/include/linux/i2c/arcxcnn.h
new file mode 100644
index 0000000..e378d63
--- /dev/null
+++ b/include/linux/i2c/arcxcnn.h
@@ -0,0 +1,51 @@
+/*
+ * Backlight driver for ArcticSand ARC_X_C_0N_0N Devices
+ *
+ * Copyright 2016 ArcticSand, Inc.
+ * Author : Brian Dodge <bdodge-eV7fy4qpoLhpLGFMi4vTTA@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ARCXCNN_H
+#define _ARCXCNN_H
+
+enum arcxcnn_chip_id {
+ ARC2C0608
+};
+
+/**
+ * struct arcxcnn_platform_data
+ * @name : Backlight driver name (NULL will use default)
+ * @initial_brightness : initial value of backlight brightness
+ * @leden : initial LED string enables, upper bit is global on/off
+ * @led_config_0 : fading speed (period between intensity steps)
+ * @led_config_1 : misc settings, see datasheet
+ * @dim_freq : pwm dimming frequency if in pwm mode
+ * @comp_config : misc config, see datasheet
+ * @filter_config : RC/PWM filter config, see datasheet
+ * @trim_config : full scale current trim, see datasheet
+ */
+struct arcxcnn_platform_data {
+ const char *name;
+ u16 initial_brightness;
+ u8 leden;
+ u8 led_config_0;
+ u8 led_config_1;
+ u8 dim_freq;
+ u8 comp_config;
+ u8 filter_config;
+ u8 trim_config;
+};
+
+#endif
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V2 2/2] backlight arcxcnn devicetree bindings for ArcticSand
From: Olimpiu Dejeu @ 2016-12-09 15:49 UTC (permalink / raw)
To: robh-DgEjT+Ai2ygdnm+yROfE0A
Cc: lee.jones-QSEj5FYQhm4dnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
jingoohan1-Re5JQEeQqe8AvxtiuMwx3w, bdodge-eV7fy4qpoLhpLGFMi4vTTA,
Olimpiu Dejeu
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Olimpiu Dejeu <olimpiu-eV7fy4qpoLhpLGFMi4vTTA@public.gmane.org>
---
v1 => v2:
- Version updated to match other patch in set. No other changes.
.../bindings/leds/backlight/arcxcnn_bl.txt | 31 ++++++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 Documentation/devicetree/bindings/leds/backlight/arcxcnn_bl.txt
diff --git a/Documentation/devicetree/bindings/leds/backlight/arcxcnn_bl.txt b/Documentation/devicetree/bindings/leds/backlight/arcxcnn_bl.txt
new file mode 100644
index 0000000..a7b6ff2
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/backlight/arcxcnn_bl.txt
@@ -0,0 +1,33 @@
+Binding for ArcticSand arc2c0608 LED driver
+
+Required properties:
+- compatible: should be "arc,arc2c0608"
+- reg: slave address
+
+Optional properties:
+- default-brightness: brightness value on boot, value from: 0-4095
+- label: The name of the backlight device
+ See Documentation/devicetree/bindings/leds/common.txt
+- led-sources: List of enabled channels from 0 to 5.
+ See Documentation/devicetree/bindings/leds/common.txt
+
+- arc,led-config-0: setting for register ILED_CONFIG_0
+- arc,led-config-1: setting for register ILED_CONFIG_1
+- arc,dim-freq: PWM mode frequence setting (bits [3:0] used)
+- arc,comp-config: setting for register CONFIG_COMP
+- arc,filter-config: setting for register FILTER_CONFIG
+- arc,trim-config: setting for register IMAXTUNE
+
+Note: Optional properties not specified will default to values in IC EPROM
+
+Example:
+
+arc2c0608@30 {
+ compatible = "arc,arc2c0608";
+ reg = <0x30>;
+ default-brightness = <500>;
+ label = "lcd-backlight";
+ linux,default-trigger = "backlight";
+ led-sources = <0 1 2 5>;
+};
+
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v9 3/3] fpga: Add support for Lattice iCE40 FPGAs
From: Moritz Fischer @ 2016-12-09 15:50 UTC (permalink / raw)
To: Joel Holdsworth
Cc: Alan Tull, Rob Herring, Devicetree List,
Linux Kernel Mailing List, linux-spi-u79uwXL29TY76Z2rM5mHXA,
Marek Vašut
In-Reply-To: <1481261749-15301-3-git-send-email-joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org>
Joel,
A couple of minor nits below (none of them are real blockers), other
than that looks good.
On Thu, Dec 8, 2016 at 9:35 PM, Joel Holdsworth
<joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org> wrote:
> The Lattice iCE40 is a family of FPGAs with a minimalistic architecture
> and very regular structure, designed for low-cost, high-volume consumer
> and system applications.
<snip>
> This patch adds support to the FPGA manager for configuring the SRAM of
> iCE40LM, iCE40LP, iCE40HX, iCE40 Ultra, iCE40 UltraLite and iCE40
> UltraPlus devices, through slave SPI.
</snip>
I think just this paragraph would be enough.
>
> The iCE40 family is notable because it is the first FPGA family to have
> complete reverse engineered bit-stream documentation for the iCE40LP and
> iCE40HX devices. Furthermore, there is now a Free Software Verilog
> synthesis tool-chain: the "IceStorm" tool-chain.
>
> This project is the work of Clifford Wolf, who is the maintainer of
> Yosys Verilog RTL synthesis framework, and Mathias Lasser, with notable
> contributions from "Cotton Seed", the main author of "arachne-pnr"; a
> place-and-route tool for iCE40 FPGAs.
>
> Having a Free Software synthesis tool-chain offers interesting
> opportunities for embedded devices that are able reconfigure themselves
> with open firmware that is generated on the device itself. For example
> a mobile device might have an application processor with an iCE40 FPGA
> attached, which implements slave devices, or through which the processor
> communicates with other devices through the FPGA fabric.
>
> A kernel driver for the iCE40 is useful, because in some cases, the FPGA
> may need to be configured before other devices can be accessed.
>
> An example of such a device is the icoBoard; a RaspberryPI HAT which
> features an iCE40HX8K with a 1 or 8 MBit SRAM and ports for
> Digilent-compatible PMOD modules. A PMOD module may contain a device
> with which the kernel communicates, via the FPGA.
>
> Signed-off-by: Joel Holdsworth <joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org>
Modulo nits:
Reviewed-by: Moritz Fischer <moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w@public.gmane.org>
> ---
> drivers/fpga/Kconfig | 6 ++
> drivers/fpga/Makefile | 1 +
> drivers/fpga/ice40-spi.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 220 insertions(+)
> create mode 100644 drivers/fpga/ice40-spi.c
>
> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index ce861a2..967cda4 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -20,6 +20,12 @@ config FPGA_REGION
> FPGA Regions allow loading FPGA images under control of
> the Device Tree.
>
> +config FPGA_MGR_ICE40_SPI
> + tristate "Lattice iCE40 SPI"
> + depends on OF && SPI
> + help
> + FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
> +
> config FPGA_MGR_SOCFPGA
> tristate "Altera SOCFPGA FPGA Manager"
> depends on ARCH_SOCFPGA || COMPILE_TEST
> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
> index 8df07bc..cc0d364 100644
> --- a/drivers/fpga/Makefile
> +++ b/drivers/fpga/Makefile
> @@ -6,6 +6,7 @@
> obj-$(CONFIG_FPGA) += fpga-mgr.o
>
> # FPGA Manager Drivers
> +obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o
> obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
> obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
> obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o
> diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c
> new file mode 100644
> index 0000000..3c99859
> --- /dev/null
> +++ b/drivers/fpga/ice40-spi.c
> @@ -0,0 +1,213 @@
> +/*
> + * FPGA Manager Driver for Lattice iCE40.
> + *
> + * Copyright (c) 2016 Joel Holdsworth
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 2 of the License.
> + *
> + * This driver adds support to the FPGA manager for configuring the SRAM of
> + * Lattice iCE40 FPGAs through slave SPI.
> + */
> +
> +#include <linux/fpga/fpga-mgr.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/of_gpio.h>
> +#include <linux/spi/spi.h>
> +
> +#define ICE40_SPI_FPGAMGR_RESET_DELAY 1 /* us (>200ns) */
> +#define ICE40_SPI_FPGAMGR_HOUSEKEEPING_DELAY 1200 /* us */
> +
> +#define ICE40_SPI_FPGAMGR_NUM_ACTIVATION_BYTES DIV_ROUND_UP(49, 8)
> +
> +struct ice40_fpga_priv {
> + struct spi_device *dev;
> + struct gpio_desc *reset;
> + struct gpio_desc *cdone;
> +};
> +
> +static enum fpga_mgr_states ice40_fpga_ops_state(struct fpga_manager *mgr)
> +{
> + struct ice40_fpga_priv *priv = mgr->priv;
> +
> + return gpiod_get_value(priv->cdone) ? FPGA_MGR_STATE_OPERATING :
> + FPGA_MGR_STATE_UNKNOWN;
> +}
> +
> +static int ice40_fpga_ops_write_init(struct fpga_manager *mgr,
> + struct fpga_image_info *info,
> + const char *buf, size_t count)
> +{
> + struct ice40_fpga_priv *priv = mgr->priv;
> + struct spi_device *dev = priv->dev;
> + struct spi_message message;
> + struct spi_transfer assert_cs_then_reset_delay = {
> + .cs_change = 1,
> + .delay_usecs = ICE40_SPI_FPGAMGR_RESET_DELAY
> + };
> + struct spi_transfer housekeeping_delay_then_release_cs = {
> + .delay_usecs = ICE40_SPI_FPGAMGR_HOUSEKEEPING_DELAY
> + };
> + int ret;
> +
> + if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
> + dev_err(&dev->dev,
> + "Partial reconfiguration is not supported\n");
> + return -ENOTSUPP;
> + }
> +
> + /* Lock the bus, assert CRESET_B and SS_B and delay >200ns */
> + spi_bus_lock(dev->master);
> +
> + gpiod_set_value(priv->reset, 1);
> +
> + spi_message_init(&message);
> + spi_message_add_tail(&assert_cs_then_reset_delay, &message);
> + ret = spi_sync_locked(dev, &message);
> +
> + /* Come out of reset */
> + gpiod_set_value(priv->reset, 0);
> +
> + /* Abort if the chip-select failed */
> + if (ret)
> + goto fail;
> +
> + /* Check CDONE is de-asserted i.e. the FPGA is reset */
> + if (gpiod_get_value(priv->cdone)) {
> + dev_err(&dev->dev, "Device reset failed, CDONE is asserted\n");
> + ret = -EIO;
> + goto fail;
> + }
> +
> + /* Wait for the housekeeping to complete, and release SS_B */
> + spi_message_init(&message);
> + spi_message_add_tail(&housekeeping_delay_then_release_cs, &message);
> + ret = spi_sync_locked(dev, &message);
> +
> +fail:
> + spi_bus_unlock(dev->master);
> +
> + return ret;
> +}
> +
> +static int ice40_fpga_ops_write(struct fpga_manager *mgr,
> + const char *buf, size_t count)
> +{
> + struct ice40_fpga_priv *priv = mgr->priv;
> +
> + return spi_write(priv->dev, buf, count);
> +}
> +
> +static int ice40_fpga_ops_write_complete(struct fpga_manager *mgr,
> + struct fpga_image_info *info)
> +{
> + struct ice40_fpga_priv *priv = mgr->priv;
> + struct spi_device *dev = priv->dev;
> + const u8 padding[ICE40_SPI_FPGAMGR_NUM_ACTIVATION_BYTES] = {0};
> +
> + /* Check CDONE is asserted */
> + if (!gpiod_get_value(priv->cdone)) {
> + dev_err(&dev->dev,
> + "CDONE was not asserted after firmware transfer\n");
> + return -EIO;
> + }
> +
> + /* Send of zero-padding to activate the firmware */
> + return spi_write(dev, padding, sizeof(padding));
> +}
> +
> +static const struct fpga_manager_ops ice40_fpga_ops = {
> + .state = ice40_fpga_ops_state,
> + .write_init = ice40_fpga_ops_write_init,
> + .write = ice40_fpga_ops_write,
> + .write_complete = ice40_fpga_ops_write_complete,
> +};
> +
> +static int ice40_fpga_probe(struct spi_device *spi)
> +{
> + struct device *dev = &spi->dev;
> + struct device_node *np = spi->dev.of_node;
> + struct ice40_fpga_priv *priv;
> + int ret;
> +
> + if (!np) {
> + dev_err(dev, "No Device Tree entry\n");
> + return -EINVAL;
> + }
> +
> + priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->dev = spi;
> +
> + /* Check board setup data. */
> + if (spi->max_speed_hz > 25000000) {
> + dev_err(dev, "Speed is too high\n");
Speed is too high, maximum speed is X. Maybe make it a ICE40_SPI_MAX_SPEED
> + return -EINVAL;
> + }
> +
> + if (spi->max_speed_hz < 1000000) {
> + dev_err(dev, "Speed is too low\n");
Speed is too low, minimum speed is X. Maybe make it a ICE40_SPI_MIN_SPEED
> + return -EINVAL;
> + }
> +
> + if (spi->mode & SPI_CPHA) {
> + dev_err(dev, "Bad mode\n");
'Bad mode, SPI_CPHA not supported' mabye.
> + return -EINVAL;
> + }
> +
> + /* Set up the GPIOs */
> + priv->cdone = devm_gpiod_get(dev, "cdone", GPIOD_IN);
> + if (IS_ERR(priv->cdone)) {
> + dev_err(dev, "Failed to get CDONE GPIO: %ld\n",
> + PTR_ERR(priv->cdone));
> + return -EINVAL;
> + }
> +
> + priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
> + if (IS_ERR(priv->reset)) {
> + dev_err(dev, "Failed to get CRESET_B GPIO: %ld\n",
> + PTR_ERR(priv->reset));
> + return -EINVAL;
> + }
> +
> + /* Register with the FPGA manager */
> + ret = fpga_mgr_register(dev, "Lattice iCE40 FPGA Manager",
> + &ice40_fpga_ops, priv);
> + if (ret) {
> + dev_err(dev, "Unable to register FPGA manager");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int ice40_fpga_remove(struct spi_device *spi)
> +{
> + fpga_mgr_unregister(&spi->dev);
> + return 0;
> +}
> +
> +static const struct of_device_id ice40_fpga_of_match[] = {
> + { .compatible = "lattice,ice40-fpga-mgr", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, ice40_fpga_of_match);
> +
> +static struct spi_driver ice40_fpga_driver = {
> + .probe = ice40_fpga_probe,
> + .remove = ice40_fpga_remove,
> + .driver = {
> + .name = "ice40spi",
> + .of_match_table = of_match_ptr(ice40_fpga_of_match),
> + },
> +};
> +
> +module_spi_driver(ice40_fpga_driver);
> +
> +MODULE_AUTHOR("Joel Holdsworth <joel-IJEoVVyKhCJXvIrf17iDB/XRex20P6io@public.gmane.org>");
> +MODULE_DESCRIPTION("Lattice iCE40 FPGA Manager");
> +MODULE_LICENSE("GPL v2");
> --
> 2.7.4
>
Thanks,
Moritz
PS: can you also Cc linux-fpga mailing list in the future?
--
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: [PATCH 1/2] of: base: add support to get machine model name
From: Rob Herring @ 2016-12-09 16:03 UTC (permalink / raw)
To: Sudeep Holla
Cc: Frank Rowand, linux-kernel@vger.kernel.org, Arnd Bergmann,
devicetree@vger.kernel.org
In-Reply-To: <195d492b-c674-e096-4f84-d37ca5448db2@arm.com>
On Wed, Nov 23, 2016 at 4:25 AM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 22/11/16 21:35, Rob Herring wrote:
>>
>> On Tue, Nov 22, 2016 at 12:44 PM, Frank Rowand <frowand.list@gmail.com>
>> wrote:
>
>
> [...]
>
>>>
>>> This patch adds a function that leads to conflating the "model" property
>>> and the "compatible" property. This leads to opaque, confusing and
>>> unclear
>>> code where ever it is used. I think it is not good for the device tree
>>> framework to contribute to writing unclear code.
>>>
>>> Further, only two of the proposed users of this new function appear to
>>> be proper usage. I do not think that the small amount of reduced lines
>>> of code is a good trade off for the reduced code clarity and for the
>>> potential for future mis-use of this function.
>>>
>>> Can I convince you to revert this patch?
>>
>>
>> Yes, I will revert.
I looked at this again and the users. They are all informational, so
I'm not worried if a compatible string could be returned with this
change. The function returns the best name for the machine and having
consistency is a good thing.
I was considering not reverting (as I'd not yet gotten around to it),
but I'm still going to revert for the naming.
>>
>>> If not, will you accept a patch to change the function name to more
>>> clearly indicate what it does? (One possible name would be
>>> of_model_or_1st_compatible().)
>>
>>
>> I took it as there's already the FDT equivalent function.
>
>
> Yes it was mainly for non of_flat_* replacement for
> of_flat_dt_get_machine_name
I would suggest just of_get_machine_name().
You might also add a fallback to return "unknown", and drop some of
the custom strings. I don't think anyone should care about the actual
string. However, it's an error to have a DT with no model or top level
compatible, so maybe a WARN.
Rob
^ permalink raw reply
* Re: [PATCH v2 1/2] devicetree: i2c-hid: Add Wacom digitizer + regulator support
From: Doug Anderson @ 2016-12-09 16:05 UTC (permalink / raw)
To: Rob Herring
Cc: Benjamin Tissoires, Brian Norris, Jiri Kosina, Caesar Wang,
open list:ARM/Rockchip SoC..., linux-input@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Dmitry Torokhov, Mark Rutland
In-Reply-To: <CAL_JsqK8ruinQC0pzWLWDLVcTmPdn4ZpejWUAQ0UD7H2MhLyvA@mail.gmail.com>
Hi,
On Thu, Dec 8, 2016 at 8:01 AM, Rob Herring <robh@kernel.org> wrote:
>> Just my $0.02. Feel free to ignore.
>>
>> One thought is that I would say that the need to power on the device
>> explicitly seems more like a board level difference and less like a
>> difference associated with a particular digitizer. Said another way,
>> it seems likely there will be boards with a w9013 without explicit
>> control of the regulator in software and it seems like there will be
>> boards with other digitizers where suddenly a new board will come out
>> that needs explicit control of the regulator.
>
> Then either the regulator is optional or you don't say it is a w9013
> for that board. But if you do need to initialize the device and
> therefore know what type of device it is, then you need a compatible
> for the device. It's when things really vary by board that we add DT
> properties.
>
>> In this particular case I feel like we can draw a lot of parallels to
>> an SDIO bus.
>>
>> When you specify an SDIO bus you don't specify what kind of card will
>> be present, you just say "I've got an SDIO bus" and then the specific
>> device underneath is probed. Here we've say "I've got an i2c
>> connection intended for HID" and then you probe for the HID device
>> that's on the connection.
>
> No, the soldered down devices require all sorts of extra non-SDIO
> connections and we do specify the device in those cases.
We have never specified the device on boards I've worked with.
On rk3288-veyron, for instance, we might have stuffed a Broadcom 4354
WiFi chip or a Marvell 8897 WiFi chip. Some veyron boards have one
chip and some have the other. ...and during bringup we even had some
of the exact same boards where half were stuffed with one chip and
half with the other.
Nothing in the device tree says which chip is stuffed. In both cases
the board uses the same power on sequence for the WiFi chip. Once
that is done, we dynamically probe which actual WiFi part is stuffed.
Certainly not all users that have these WiFi chips use the same power
on sequence. I have certainly seen development boards for these chips
where you just insert them into a regular SD card slot. This is a
more expensive solution because you need more logic on the board, but
it shows that the power on sequence is not associated with these
chips.
>> Also for an SDIO bus, you've possibly got a regulators / GPIOs /
>> resets that need to be controlled, but the specific details of these
>> regulator / GPIOs / resets are specific to a given board and not
>> necessarily a given SDIO device.
>
> It's both. The device defines what is needed and the specs to control
> them (active states of GPIOs, de/assertion times of resets, supply
> voltages, etc.). The board only determines what the connections are
> and if you can control them.
It's not always that simple. The device says that it needs power and
resets to happen. How power is provided and how resets happen is
awfully board specific. As per above it is possible that the board
wouldn't need to be involved above is you want to spend more money /
power.
-Doug
^ permalink raw reply
* Re: [PATCH v2 1/2] devicetree: i2c-hid: Add Wacom digitizer + regulator support
From: Doug Anderson @ 2016-12-09 16:16 UTC (permalink / raw)
To: Rob Herring
Cc: Jiri Kosina, Dmitry Torokhov, Benjamin Tissoires, Brian Norris,
Caesar Wang, open list:ARM/Rockchip SoC...,
linux-input@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Mark Rutland
In-Reply-To: <CAL_JsqLpjhHeeKq3PmNToux1Rgkg0M84-dv9HGCOws223ima4w@mail.gmail.com>
Hi,
On Fri, Dec 9, 2016 at 7:01 AM, Rob Herring <robh@kernel.org> wrote:
> On Fri, Dec 9, 2016 at 8:36 AM, Jiri Kosina <jikos@kernel.org> wrote:
>> On Thu, 8 Dec 2016, Rob Herring wrote:
>>
>>> > And if tomorrow there is Elan device that is drop-in compatible (same
>>> > connector, etc) with Wacom i2c-hid, will you ask for Elan-specific
>>> > binding? Atmel? Weida? They all need to be powered up ultimately.
>>>
>>> Yes, I will.
>>
>> What advantage does that bring?
>>
>>> That in no way means the OS driver has to know about each and every one.
>>> If they can all claim compatibility with Wacom (including power
>>> control), then they can have a Wacom compatible string too. Or you can
>>> just never tell me that there's a different manufacturer and I won't
>>> care as long you don't need different control. But soon as a device
>>> needs another power rail, GPIO or different timing, then you'd better
>>> have a new compatible string.
>>
>> Again, I simply don't understand what advantage does the aproach you are
>> trying to use bring.
>
> This is simply how DT works. HID-over-I2C devices are no different
> than any other I2C device or any other component. You are not special.
...but once you say that it's HID over I2C then it becomes probe-able,
right? Said another way: we need to specify just enough to power the
device up properly and then we can ask it what kind of device it is
and then we can make quirk decisions based on that.
So specifying what kind of device it is in the device tree is somewhat
redundant and it also means that you make it needlessly difficult to
build a system with dual-sourced components.
One of the major points of probe-able connections is that you could
put anything you want there and the kernel _doesn't_ need to describe
it. ...and the whole point of device tree (I thought) was to
specifically handle connections that _aren't_ probe-able.
For instance, if a board has a USB bus on it but you need to assert a
special reset or turn on a special regulator (besides vbus) before you
can probe the USB bus, you wouldn't think that the board should
specify exactly what device was stuffed in the connection, would you?
>> HID over I2C is a generic protocol.
>
> DT describes h/w, not protocols.
Isn't it a little of each, though? When you say that there's a USB
port or an SDIO port or a serial port on the board, you're saying more
than just that there are 2, 4, or 8 wires coming out of the board.
You're saying that you're expecting to talk a certain protocol over
those wires.
-Doug
^ permalink raw reply
* Re: [PATCH] devicetree: bindings: Add vendor prefix for Andes Technology Corporation
From: Rob Herring @ 2016-12-09 16:20 UTC (permalink / raw)
To: Greentime Hu
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1479798905-21671-1-git-send-email-green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Tue, Nov 22, 2016 at 03:15:05PM +0800, Greentime Hu wrote:
> Add vendor-prefix for Andes Technology Corporation
>
> Signed-off-by: Greentime Hu <green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> .../devicetree/bindings/vendor-prefixes.txt | 1 +
> 1 file changed, 1 insertion(+)
Applied, thanks.
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 v2] of/irq: improve error report on irq discovery process failure
From: Rob Herring @ 2016-12-09 16:25 UTC (permalink / raw)
To: Guilherme G. Piccoli
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linuxppc-dev,
Mark Rutland, Benjamin Herrenschmidt, Frank Rowand, Marc Zyngier
In-Reply-To: <5845B980.2030609-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
On Mon, Dec 5, 2016 at 1:01 PM, Guilherme G. Piccoli
<gpiccoli-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> On 12/05/2016 12:28 PM, Rob Herring wrote:
>> On Mon, Dec 5, 2016 at 7:59 AM, Guilherme G. Piccoli
>> <gpiccoli-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
>>> On PowerPC machines some PCI slots might not have level triggered
>>> interrupts capability (also know as level signaled interrupts),
>>> leading of_irq_parse_pci() to complain by presenting error messages
>>> on the kernel log - in this case, the properties "interrupt-map" and
>>> "interrupt-map-mask" are not present on device's node in the device
>>> tree.
>>>
>>> This patch introduces a different message for this specific case,
>>> and also reduces its level from error to warning. Besides, we warn
>>> (once) that possibly some PCI slots on the system have no level
>>> triggered interrupts available.
>>> We changed some error return codes too on function of_irq_parse_raw()
>>> in order other failure's cases can be presented in a more precise way.
>>>
>>> Before this patch, when an adapter was plugged in a slot without level
>>> interrupts capabilitiy on PowerPC, we saw a generic error message
>>> like this:
>>>
>>> [54.239] pci 002d:70:00.0: of_irq_parse_pci() failed with rc=-22
>>>
>>> Now, with this applied, we see the following specific message:
>>>
>>> [16.154] pci 0014:60:00.1: of_irq_parse_pci: no interrupt-map found,
>>> INTx interrupts not available
>>>
>>> Finally, we standardize the error path in of_irq_parse_raw() by always
>>> taking the fail path instead of returning directly from the loop.
>>>
>>> Signed-off-by: Guilherme G. Piccoli <gpiccoli-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
>>> ---
>>>
>>> v2:
>>> * Changed function return code to always return negative values;
>>
>> Are you sure this is safe? This is tricky because of differing values
>> of NO_IRQ (0 or -1).
>
> Thanks Rob, but this is purely bad wording from myself. I'm sorry - I
> meant to say that I changed only my positive return code (that was
> suggested to be removed in the prior revision) to negative return code!
>
> So, I changed only code I added myself in v1 =)
>
>
>>
>>> * Improved/simplified warning outputs;
>>> * Changed some return codes and some error paths in of_irq_parse_raw()
>>> in order to be more precise/consistent;
>>
>> This too could have some side effects on callers.
>>
>> Not saying don't do these changes, just need some assurances this has
>> been considered.
>
> Thanks for your attention. I performed a quick investigation before
> changing this, all the places that use the return values are just
> getting "true/false" information from that, meaning they just are
> comparing to 0 basically. So change -EINVAL to -ENOENT wouldn't hurt any
> user of these return values, it'll only become more informative IMHO.
>
> Now, regarding the only error path that was changed: for some reason,
> this was the only place in which we didn't goto fail label in case of
> failure - it was added by a legacy commit from Ben, dated from 2006:
> 006b64de60 ("[POWERPC] Make OF irq map code detect more error cases").
> Then it was carried by Grant Likely's commit 7dc2e1134a ("of/irq: merge
> irq mapping code"), 6-year old commit.
> I wasn't able to imagine a scenario in which changing this would break
> something; I believe the change improve consistency, but I'd remove it
> if you or somebody else thinks it worth be removed.
Okay. It's a bit late for 4.10 now and want this to be in -next for a
while, so I'll queue it after the merge window.
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] devicetree: bindings: Add vendor prefix for Oki
From: Rob Herring @ 2016-12-09 16:28 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1480068945-29822-1-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
On Fri, Nov 25, 2016 at 11:15:45AM +0100, Geert Uytterhoeven wrote:
> Already in use for "oki,ml86v7667".
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
> ---
> Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
> 1 file changed, 1 insertion(+)
Applied, thanks.
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] drivers/of: fix missing pr_cont()s in of_print_phandle_args
From: Rob Herring @ 2016-12-09 16:32 UTC (permalink / raw)
To: Marcin Nowakowski; +Cc: Frank Rowand, devicetree, linux-kernel
In-Reply-To: <1480579255-28446-1-git-send-email-marcin.nowakowski@imgtec.com>
On Thu, Dec 01, 2016 at 09:00:55AM +0100, Marcin Nowakowski wrote:
> Since the KERN_CONT changes, the current debug printks have a lot of
> empty lines making the log messages very hard to read.
>
> Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
> ---
> drivers/of/base.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
Applied, thanks.
Rob
^ permalink raw reply
* Re: [PATCH v4] of: Fix issue where code would fall through to error case.
From: Rob Herring @ 2016-12-09 16:33 UTC (permalink / raw)
To: Moritz Fischer
Cc: devicetree, linux-kernel, frowand.list, pantelis.antoniou,
Moritz Fischer
In-Reply-To: <1480659025-18836-1-git-send-email-moritz.fischer@ettus.com>
On Thu, Dec 01, 2016 at 10:10:25PM -0800, Moritz Fischer wrote:
> From: Moritz Fischer <mdf@kernel.org>
>
> No longer fall through into the error case that prints out
> an error if no error (err = 0) occurred.
>
> Fixes d9181b20a83(of: Add back an error message, restructured)
> Signed-off-by: Moritz Fischer <mdf@kernel.org>
> Reviewed-by: Frank Rowand <frank.rowand@am.sony.com>
> ---
Applied, thanks.
Rob
^ permalink raw reply
* RE: [RFC] New Device Tree property - "bonding"
From: Ramesh Shanmugasundaram @ 2016-12-09 16:45 UTC (permalink / raw)
To: Rob Herring
Cc: Laurent Pinchart, frowand.list@gmail.com, mark.rutland@arm.com,
pantelis.antoniou@konsulko.com, Chris Paterson,
Geert Uytterhoeven, laurent.pinchart+renesas@ideasonboard.com,
devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
Maxime Ripard
In-Reply-To: <CAL_JsqKJcEmNUzOm-3j3FODkN1faXMAMmURRxfRpHfiGs_a+qA@mail.gmail.com>
Hello Rob,
> > >> On Monday 05 Dec 2016 09:57:32 Rob Herring wrote:
> > >> > On Mon, Dec 5, 2016 at 8:40 AM, Laurent Pinchart wrote:
> > >> > > On Monday 05 Dec 2016 08:18:34 Rob Herring wrote:
> > >> > >> On Fri, Nov 25, 2016 at 10:55 AM, Ramesh Shanmugasundaram wrote:
> > >> > >>> Hello DT maintainers,
> > >> > >>>
> > >> > >>> In one of the Renesas SoCs we have a device called DRIF
> > >> > >>> (Digital Radio
> > >> > >>> Interface) controller. A DRIF channel contains 4 external
> > >> > >>> pins
> > >> > >>> - SCK, SYNC, Data pins D0 & D1.
> > >> > >>>
> > >> > >>> Internally a DRIF channel is made up of two SPI slave devices
> > >> > >>> (also called sub-channels here) that share common CLK & SYNC
> > >> > >>> signals but have their own resource set. The DRIF channel can
> > >> > >>> have either one of the sub-channel active at a time or both.
> > >> > >>> When both sub-channels are active, they need to be managed
> > >> > >>> together as one device as they share same CLK & SYNC. We plan
> > >> > >>> to tie these two sub-channels together with a new property
> > >> > >>> called
> > "renesas,bonding".
> > >> > >>
> > >> > >> Is there no need to describe the master device? No GPIOs,
> > >> > >> regulators or other sideband controls needed? If that's never
> > >> > >> needed (which seems doubtful), then I would do something
> > >> > >> different here probably with the master device as a child of
> > >> > >> one DRIF and then phandles to master from the other DRIFs.
> > >> > >> Otherwise, this looks
> > >> fine to me.
> > >> > >
> > >> > > Here's a bit of background.
> > >> > >
> > >> > > The DRIF is an SPI receiver. It has three input pins, a clock
> > >> > > line, a data line and a sync signal. The device is designed to
> > >> > > be connected to a variety of data sources, usually plain SPI (1
> > >> > > data line), IIS (1 data
> > >> > > line) but also radio tuners that output I/Q data
> > >> > > (http://www.ni.com/tutorial/4805/en/) over two data lines.
> > >> > >
> > >> > > In the case of IQ each data sample is split in two I and Q
> > >> > > values (typically 16 to 20 bits each in this case), and the
> > >> > > values are transmitted serially over one data line each. The
> > >> > > synchronization and clock signals are common to both data
> > >> > > lines. The DRIF is optimized for this use case as the DRIF
> > >> > > instances in the SoC (each of them having independent clocks,
> > >> > > interrupts and control
> > >> > > registers) are grouped by two, and the two instances in a group
> > >> > > handle a single data line each but share the same clock and
> > >> > > sync
> > input.
> > >> > >
> > >> > > On the software side we need to group the I and Q values, which
> > >> > > are DMA'ed to memory by the two DRIF instances, and make them
> > >> > > available to userspace. The V4L2 API used here in SDR (Software
> > >> > > Defined Radio) mode supports such use cases and exposes a
> > >> > > single device node to userspace that allows control of the two
> > >> > > DRIF instances as a single device. To be able to implement this
> > >> > > we need kernel code to be aware of DRIF groups and, while
> > >> > > binding to the DRIF instances separately, expose only one V4L2
> > >> > > device to
> > userspace for each group.
> > >> > >
> > >> > > There's no master or slave instance from a hardware point of
> > >> > > view, but the two instances are not interchangeable as they
> > >> > > carry separate
> > >> information.
> > >> > > They must thus be identified at the driver level.
> > >> >
> > >> > By master, I meant the external master device that generates the
> > >> > IQ data, not which of the internal DRIF blocks is a master of the
> other.
> > >> > So back to my question, does the external master device need to
> > >> > be described? I worry the answer now for a simple case is no, but
> > >> > then later people are going to have cases needing to describe
> > >> > more. We need to answer this question first before we can decide
> > >> > what this binding should look like.
> > >>
> > >> Oh yes the external device certainly needs to be described. As it
> > >> is controlled through a separate, general-purpose I2C or SPI
> > >> controller, it should be a child node of that controller. The DRIF
> > >> handles the data interface only, not the control interface of the
> external device.
> > >
> > > Yes, as Laurent mentioned, the external master will be described
> > separately. The data interface with the master is described through
> > port nodes. E.g.
> > >
> > > port {
> > > drif0_ep: endpoint {
> > > remote-endpoint = <&tuner_ep>;
> > > };
> > > };
> > >
> > > Do we agree on this model please?
> >
> > Well, that's not complete as you should have both DRIF0 and DRIF1
> > having connections to the tuner. Then you can walk the graph and find
> > everything, and you then don't need the bonding property.
>
> Assuming the third party tuner exposes it's two data lines as two
> endpoints, it seems possible with of_graph.h apis to walk through tuner
> end points and get the phandle of the other DRIF device. However, there
> are couple of points coming to mind.
>
> - The ctrl pins shared between two DRIFs needs to be enabled in one of the
> DRIF device. Do we choose this device arbitrarily? Do we expose the CTRL
> signal properties (msb/lsb first, polarity etc) on both DRIF devices?
> Should we think about scalability?
>
> - It mandates the third party tuner device to expose it's two data lines
> as two endpoints. It assumes that a single third party master device
> controls both the data lines coming to each DRIF device.
>
> The bonding property looks a bit cleaner on these aspects because it
> describes only the DRIF device.
Shall we please conclude on the model? Are you happy with the use of "renesas,bonding" property if the concern is on pushing this as a generic property?
I would appreciate your feedback.
Thanks,
Ramesh
^ permalink raw reply
* [PATCH v3 0/5] Static memory controllers for the Aspeed SoC
From: Cédric Le Goater @ 2016-12-09 16:49 UTC (permalink / raw)
To: linux-mtd
Cc: Mark Rutland, Boris Brezillon, devicetree, Richard Weinberger,
Marek Vasut, Rob Herring, Joel Stanley, Cyrille Pitchen,
Brian Norris, David Woodhouse, Cédric Le Goater
Hello,
Here is a serie introducing a new driver for the different memory
controllers of the Aspeed AST2500 and AST2400 SoCs. Each SoC has at
least a memory controller for the BMC firmware and another one for the
host firmware. The register set are mostly comptatible but there are
some slight differences on the AST2400.
The driver only support SPI type flash.
Tested on:
* OpenPOWER Palmetto (AST2400) with
FMC controller : n25q256a
SPI controller : mx25l25635e and n25q512ax3
* Evaluation board (AST2500) with
FMC controller : w25q256
SPI controller : w25q256
* OpenPOWER Witherspoon (AST2500) with
FMC controller : mx25l25635e * 2
SPI controller : mx66l1g45g
Changes since v2:
- splitted patch to distinguish AST2400 and AST2500 controllers
- fixed controller names
- introduced prepare/unprepare ops
- introduced a aspeed_smc_setup_flash() routine
- various cleanups
Changes since v1:
- added a set4b ops to handle difference in the controllers
- simplified the IO routines
- prepared for fast read using dummy cycles
Work in progress:
- read optimization using higher SPI clock frequencies
- command mode to direct reads from AHB
- DMA support
Thanks,
C.
Cédric Le Goater (5):
mtd: spi-nor: add memory controllers for the Aspeed AST2500 SoC
mtd: aspeed: add memory controllers for the Aspeed AST2400 SoC
mtd: aspeed: used a label property
mtd: spi-nor: bindings for the Aspeed memory controllers
mtd: spi-nor: add a label property to jedec,spi-nor
.../devicetree/bindings/mtd/aspeed-smc.txt | 51 ++
.../devicetree/bindings/mtd/jedec,spi-nor.txt | 2 +
drivers/mtd/spi-nor/Kconfig | 10 +
drivers/mtd/spi-nor/Makefile | 1 +
drivers/mtd/spi-nor/aspeed-smc.c | 770 +++++++++++++++++++++
5 files changed, 834 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/aspeed-smc.txt
create mode 100644 drivers/mtd/spi-nor/aspeed-smc.c
--
2.7.4
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
* [PATCH v3 1/5] mtd: spi-nor: add memory controllers for the Aspeed AST2500 SoC
From: Cédric Le Goater @ 2016-12-09 16:49 UTC (permalink / raw)
To: linux-mtd
Cc: Mark Rutland, Boris Brezillon, devicetree, Richard Weinberger,
Marek Vasut, Rob Herring, Joel Stanley, Cyrille Pitchen,
Brian Norris, David Woodhouse, Cédric Le Goater
In-Reply-To: <1481302167-28044-1-git-send-email-clg@kaod.org>
This driver adds mtd support for the Aspeed AST2500 SoC static memory
controllers :
* Firmware SPI Memory Controller (FMC)
. BMC firmware
. 3 chip select pins (CE0 ~ CE2)
. supports SPI type flash memory (CE0-CE1)
. CE2 can be of NOR type flash but this is not supported by the
driver
* SPI Flash Controller (SPI1 and SPI2)
. host firmware
. 2 chip select pins (CE0 ~ CE1)
. supports SPI type flash memory
Each controller has a memory range on which it maps its flash module
slaves. Each slave is assigned a memory window for its mapping that
can be changed at bootime with the Segment Address Register.
Each SPI flash slave can then be accessed in two modes: Command and
User. When in User mode, accesses to the memory segment of the slaves
are translated in SPI transfers. When in Command mode, the HW
generates the SPI commands automatically and the memory segment is
accessed as if doing a MMIO.
Currently, only the User mode is supported. Command mode needs a
little more work to check that the memory window on the AHB bus fits
the module size.
Based on previous work from Milton D. Miller II <miltonm@us.ibm.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
drivers/mtd/spi-nor/Kconfig | 10 +
drivers/mtd/spi-nor/Makefile | 1 +
drivers/mtd/spi-nor/aspeed-smc.c | 735 +++++++++++++++++++++++++++++++++++++++
3 files changed, 746 insertions(+)
create mode 100644 drivers/mtd/spi-nor/aspeed-smc.c
diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 4a682ee0f632..5c0efbd9dd89 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -29,6 +29,16 @@ config MTD_SPI_NOR_USE_4K_SECTORS
Please note that some tools/drivers/filesystems may not work with
4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum).
+config SPI_ASPEED
+ tristate "Aspeed flash controllers in SPI mode"
+ depends on ARCH_ASPEED || COMPILE_TEST
+ depends on HAS_IOMEM && OF
+ help
+ This enables support for the Firmware Memory controller (FMC)
+ in the Aspeed AST2500 SoC when attached to SPI NOR chips,
+ and support for the SPI flash memory controller (SPI) for
+ the host firmware. The implementation only supports SPI NOR.
+
config SPI_ATMEL_QUADSPI
tristate "Atmel Quad SPI Controller"
depends on ARCH_AT91 || (ARM && COMPILE_TEST)
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 121695e83542..d73d772c689c 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o
+obj-$(CONFIG_SPI_ASPEED) += aspeed-smc.o
obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o
obj-$(CONFIG_SPI_CADENCE_QUADSPI) += cadence-quadspi.o
obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o
diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
new file mode 100644
index 000000000000..6f9244f07aef
--- /dev/null
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -0,0 +1,735 @@
+/*
+ * ASPEED Static Memory Controller driver
+ *
+ * Copyright (c) 2015-2016, IBM Corporation.
+ *
+ * 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; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/sysfs.h>
+
+#define DEVICE_NAME "aspeed-smc"
+
+/*
+ * In user mode all data bytes read or written to the chip decode address
+ * range are transferred to or from the SPI bus. The range is treated as a
+ * fifo of arbitratry 1, 2, or 4 byte width but each write has to be aligned
+ * to its size. The address within the multiple 8kB range is ignored when
+ * sending bytes to the SPI bus.
+ *
+ * On the arm architecture, as of Linux version 4.3, memcpy_fromio and
+ * memcpy_toio on little endian targets use the optimized memcpy routines
+ * that were designed for well behavied memory storage. These routines
+ * have a stutter if the source and destination are not both word aligned,
+ * once with a duplicate access to the source after aligning to the
+ * destination to a word boundary, and again with a duplicate access to
+ * the source when the final byte count is not word aligned.
+ *
+ * When writing or reading the fifo this stutter discards data or sends
+ * too much data to the fifo and can not be used by this driver.
+ *
+ * While the low level io string routines that implement the insl family do
+ * the desired accesses and memory increments, the cross architecture io
+ * macros make them essentially impossible to use on a memory mapped address
+ * instead of a a token from the call to iomap of an io port.
+ *
+ * These fifo routines use readl and friends to a constant io port and update
+ * the memory buffer pointer and count via explicit code. The final updates
+ * to len are optimistically suppressed.
+ */
+static int aspeed_smc_read_from_ahb(void *buf, const void __iomem *src,
+ size_t len)
+{
+ if (IS_ALIGNED((u32)src, sizeof(u32)) &&
+ IS_ALIGNED((u32)buf, sizeof(u32)) &&
+ IS_ALIGNED(len, sizeof(u32))) {
+ while (len > 3) {
+ *(u32 *)buf = readl(src);
+ buf += 4;
+ src += 4;
+ len -= 4;
+ }
+ }
+
+ while (len--) {
+ *(u8 *)buf = readb(src);
+ buf += 1;
+ src += 1;
+ }
+ return 0;
+}
+
+static int aspeed_smc_write_to_ahb(void __iomem *dst, const void *buf,
+ size_t len)
+{
+ if (IS_ALIGNED((u32)dst, sizeof(u32)) &&
+ IS_ALIGNED((u32)buf, sizeof(u32)) &&
+ IS_ALIGNED(len, sizeof(u32))) {
+ while (len > 3) {
+ u32 val = *(u32 *)buf;
+
+ writel(val, dst);
+ buf += 4;
+ dst += 4;
+ len -= 4;
+ }
+ }
+
+ while (len--) {
+ u8 val = *(u8 *)buf;
+
+ writeb(val, dst);
+ buf += 1;
+ dst += 1;
+ }
+ return 0;
+}
+
+/*
+ * The driver only support SPI flash
+ */
+enum aspeed_smc_flash_type {
+ smc_type_nor = 0,
+ smc_type_nand = 1,
+ smc_type_spi = 2,
+};
+
+struct aspeed_smc_chip;
+
+struct aspeed_smc_info {
+ u32 maxsize; /* maximum size of chip window */
+ u8 nce; /* number of chip enables */
+ bool hastype; /* flash type field exists in config reg */
+ u8 we0; /* shift for write enable bit for CE0 */
+ u8 ctl0; /* offset in regs of ctl for CE0 */
+
+ void (*set_4b)(struct aspeed_smc_chip *chip);
+};
+
+static void aspeed_smc_chip_set_4b(struct aspeed_smc_chip *chip);
+
+static const struct aspeed_smc_info fmc_2500_info = {
+ .maxsize = 256 * 1024 * 1024,
+ .nce = 3,
+ .hastype = true,
+ .we0 = 16,
+ .ctl0 = 0x10,
+ .set_4b = aspeed_smc_chip_set_4b,
+};
+
+static const struct aspeed_smc_info spi_2500_info = {
+ .maxsize = 128 * 1024 * 1024,
+ .nce = 2,
+ .hastype = false,
+ .we0 = 16,
+ .ctl0 = 0x10,
+ .set_4b = aspeed_smc_chip_set_4b,
+};
+
+enum aspeed_smc_ctl_reg_value {
+ smc_base, /* base value without mode for other commands */
+ smc_read, /* command reg for (maybe fast) reads */
+ smc_write, /* command reg for writes */
+ smc_max,
+};
+
+struct aspeed_smc_controller;
+
+struct aspeed_smc_chip {
+ int cs;
+ struct aspeed_smc_controller *controller;
+ void __iomem *ctl; /* control register */
+ void __iomem *ahb_base; /* base of chip window */
+ u32 ctl_val[smc_max]; /* control settings */
+ enum aspeed_smc_flash_type type; /* what type of flash */
+ struct spi_nor nor;
+};
+
+struct aspeed_smc_controller {
+ struct device *dev;
+
+ struct mutex mutex; /* controller access mutex */
+ const struct aspeed_smc_info *info; /* type info of controller */
+ void __iomem *regs; /* controller registers */
+ void __iomem *ahb_base; /* per-chip windows resource */
+
+ struct aspeed_smc_chip *chips[0]; /* pointers to attached chips */
+};
+
+/*
+ * SPI Flash Configuration Register (AST2500 SPI)
+ * or
+ * Type setting Register (AST2500 FMC).
+ * CE0 and CE1 can only be of type SPI. CE2 can be of type NOR but the
+ * driver does not support it.
+ */
+#define CONFIG_REG 0x0
+#define CONFIG_DISABLE_LEGACY BIT(31) /* 1 */
+
+#define CONFIG_CE2_WRITE BIT(18)
+#define CONFIG_CE1_WRITE BIT(17)
+#define CONFIG_CE0_WRITE BIT(16)
+
+#define CONFIG_CE2_TYPE BIT(4) /* AST2500 FMC only */
+#define CONFIG_CE1_TYPE BIT(2) /* AST2500 FMC only */
+#define CONFIG_CE0_TYPE BIT(0) /* AST2500 FMC only */
+
+/*
+ * CE Control Register
+ */
+#define CE_CONTROL_REG 0x4
+
+/*
+ * CEx Control Register
+ */
+#define CONTROL_AAF_MODE BIT(31)
+#define CONTROL_IO_MODE_MASK GENMASK(30, 28)
+#define CONTROL_IO_DUAL_DATA BIT(29)
+#define CONTROL_IO_DUAL_ADDR_DATA (BIT(29) | BIT(28))
+#define CONTROL_IO_QUAD_DATA BIT(30)
+#define CONTROL_IO_QUAD_ADDR_DATA (BIT(30) | BIT(28))
+#define CONTROL_CE_INACTIVE_SHIFT 24
+#define CONTROL_CE_INACTIVE_MASK GENMASK(27, \
+ CONTROL_CE_INACTIVE_SHIFT)
+/* 0 = 16T ... 15 = 1T T=HCLK */
+#define CONTROL_COMMAND_SHIFT 16
+#define CONTROL_DUMMY_COMMAND_OUT BIT(15)
+#define CONTROL_IO_DUMMY_HI BIT(14)
+#define CONTROL_IO_DUMMY_HI_SHIFT 14
+#define CONTROL_CLK_DIV4 BIT(13) /* others */
+#define CONTROL_RW_MERGE BIT(12)
+#define CONTROL_IO_DUMMY_LO_SHIFT 6
+#define CONTROL_IO_DUMMY_LO GENMASK(7, \
+ CONTROL_IO_DUMMY_LO_SHIFT)
+#define CONTROL_IO_DUMMY_MASK (CONTROL_IO_DUMMY_HI | \
+ CONTROL_IO_DUMMY_LO)
+#define CONTROL_IO_DUMMY_SET(dummy) \
+ (((((dummy) >> 2) & 0x1) << CONTROL_IO_DUMMY_HI_SHIFT) | \
+ (((dummy) & 0x3) << CONTROL_IO_DUMMY_LO_SHIFT))
+
+#define CONTROL_CLOCK_FREQ_SEL_SHIFT 8
+#define CONTROL_CLOCK_FREQ_SEL_MASK GENMASK(11, \
+ CONTROL_CLOCK_FREQ_SEL_SHIFT)
+#define CONTROL_LSB_FIRST BIT(5)
+#define CONTROL_CLOCK_MODE_3 BIT(4)
+#define CONTROL_IN_DUAL_DATA BIT(3)
+#define CONTROL_CE_STOP_ACTIVE_CONTROL BIT(2)
+#define CONTROL_COMMAND_MODE_MASK GENMASK(1, 0)
+#define CONTROL_COMMAND_MODE_NORMAL (0)
+#define CONTROL_COMMAND_MODE_FREAD (1)
+#define CONTROL_COMMAND_MODE_WRITE (2)
+#define CONTROL_COMMAND_MODE_USER (3)
+
+#define CONTROL_KEEP_MASK \
+ (CONTROL_AAF_MODE | CONTROL_CE_INACTIVE_MASK | CONTROL_CLK_DIV4 | \
+ CONTROL_IO_DUMMY_MASK | CONTROL_CLOCK_FREQ_SEL_MASK | \
+ CONTROL_LSB_FIRST | CONTROL_CLOCK_MODE_3)
+
+/*
+ * Segment Address Registers. Start and end addresses are encoded
+ * using 8MB units
+ */
+#define SEGMENT_ADDR_REG0 0x30
+#define SEGMENT_ADDR_START(_r) ((((_r) >> 16) & 0xFF) << 23)
+#define SEGMENT_ADDR_END(_r) ((((_r) >> 24) & 0xFF) << 23)
+
+static inline u32 aspeed_smc_chip_write_bit(struct aspeed_smc_chip *chip)
+{
+ return BIT(chip->controller->info->we0 + chip->cs);
+}
+
+static void aspeed_smc_chip_check_config(struct aspeed_smc_chip *chip)
+{
+ struct aspeed_smc_controller *controller = chip->controller;
+ u32 reg;
+
+ reg = readl(controller->regs + CONFIG_REG);
+
+ if (reg & aspeed_smc_chip_write_bit(chip))
+ return;
+
+ dev_dbg(controller->dev, "config write is not set ! @%p: 0x%08x\n",
+ controller->regs + CONFIG_REG, reg);
+ reg |= aspeed_smc_chip_write_bit(chip);
+ writel(reg, controller->regs + CONFIG_REG);
+}
+
+static void aspeed_smc_start_user(struct spi_nor *nor)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+ u32 ctl = chip->ctl_val[smc_base];
+
+ /*
+ * When the chip is controlled in user mode, we need write
+ * access to send the opcodes to it. So check the config.
+ */
+ aspeed_smc_chip_check_config(chip);
+
+ ctl |= CONTROL_COMMAND_MODE_USER |
+ CONTROL_CE_STOP_ACTIVE_CONTROL;
+ writel(ctl, chip->ctl);
+
+ ctl &= ~CONTROL_CE_STOP_ACTIVE_CONTROL;
+ writel(ctl, chip->ctl);
+}
+
+static void aspeed_smc_stop_user(struct spi_nor *nor)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+
+ u32 ctl = chip->ctl_val[smc_read];
+ u32 ctl2 = ctl | CONTROL_COMMAND_MODE_USER |
+ CONTROL_CE_STOP_ACTIVE_CONTROL;
+
+ writel(ctl2, chip->ctl); /* stop user CE control */
+ writel(ctl, chip->ctl); /* default to fread or read mode */
+}
+
+static int aspeed_smc_prep(struct spi_nor *nor, enum spi_nor_ops ops)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+
+ mutex_lock(&chip->controller->mutex);
+ return 0;
+}
+
+static void aspeed_smc_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+
+ mutex_unlock(&chip->controller->mutex);
+}
+
+static int aspeed_smc_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+
+ aspeed_smc_start_user(nor);
+ aspeed_smc_write_to_ahb(chip->ahb_base, &opcode, 1);
+ aspeed_smc_read_from_ahb(buf, chip->ahb_base, len);
+ aspeed_smc_stop_user(nor);
+ return 0;
+}
+
+static int aspeed_smc_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+ int len)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+
+ aspeed_smc_start_user(nor);
+ aspeed_smc_write_to_ahb(chip->ahb_base, &opcode, 1);
+ aspeed_smc_write_to_ahb(chip->ahb_base, buf, len);
+ aspeed_smc_stop_user(nor);
+ return 0;
+}
+
+static void aspeed_smc_send_cmd_addr(struct spi_nor *nor, u8 cmd, u32 addr)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+ __be32 temp;
+ u32 cmdaddr;
+
+ switch (nor->addr_width) {
+ default:
+ WARN_ONCE(1, "Unexpected address width %u, defaulting to 3\n",
+ nor->addr_width);
+ /* FALLTHROUGH */
+ case 3:
+ cmdaddr = addr & 0xFFFFFF;
+ cmdaddr |= cmd << 24;
+
+ temp = cpu_to_be32(cmdaddr);
+ aspeed_smc_write_to_ahb(chip->ahb_base, &temp, 4);
+ break;
+ case 4:
+ temp = cpu_to_be32(addr);
+ aspeed_smc_write_to_ahb(chip->ahb_base, &cmd, 1);
+ aspeed_smc_write_to_ahb(chip->ahb_base, &temp, 4);
+ break;
+ }
+}
+
+static ssize_t aspeed_smc_read_user(struct spi_nor *nor, loff_t from,
+ size_t len, u_char *read_buf)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+
+ aspeed_smc_start_user(nor);
+ aspeed_smc_send_cmd_addr(nor, nor->read_opcode, from);
+ aspeed_smc_read_from_ahb(read_buf, chip->ahb_base, len);
+ aspeed_smc_stop_user(nor);
+ return len;
+}
+
+static ssize_t aspeed_smc_write_user(struct spi_nor *nor, loff_t to,
+ size_t len, const u_char *write_buf)
+{
+ struct aspeed_smc_chip *chip = nor->priv;
+
+ aspeed_smc_start_user(nor);
+ aspeed_smc_send_cmd_addr(nor, nor->program_opcode, to);
+ aspeed_smc_write_to_ahb(chip->ahb_base, write_buf, len);
+ aspeed_smc_stop_user(nor);
+ return len;
+}
+
+static int aspeed_smc_unregister(struct aspeed_smc_controller *controller)
+{
+ struct aspeed_smc_chip *chip;
+ int n;
+
+ for (n = 0; n < controller->info->nce; n++) {
+ chip = controller->chips[n];
+ if (chip)
+ mtd_device_unregister(&chip->nor.mtd);
+ }
+
+ return 0;
+}
+
+static int aspeed_smc_remove(struct platform_device *dev)
+{
+ return aspeed_smc_unregister(platform_get_drvdata(dev));
+}
+
+static const struct of_device_id aspeed_smc_matches[] = {
+ { .compatible = "aspeed,ast2500-fmc", .data = &fmc_2500_info },
+ { .compatible = "aspeed,ast2500-spi", .data = &spi_2500_info },
+ { }
+};
+MODULE_DEVICE_TABLE(of, aspeed_smc_matches);
+
+/*
+ * Each chip has a mapping window defined by a segment address
+ * register defining a start and an end address on the AHB bus. These
+ * addresses can be configured to fit the chip size and offer a
+ * contiguous memory region across chips. For the moment, we only
+ * check that each chip segment is valid.
+ */
+static void __iomem *aspeed_smc_chip_base(struct aspeed_smc_chip *chip,
+ struct resource *res)
+{
+ struct aspeed_smc_controller *controller = chip->controller;
+ u32 offset = 0;
+ u32 reg;
+
+ if (controller->info->nce > 1) {
+ reg = readl(controller->regs + SEGMENT_ADDR_REG0 +
+ chip->cs * 4);
+
+ if (SEGMENT_ADDR_START(reg) >= SEGMENT_ADDR_END(reg))
+ return NULL;
+
+ offset = SEGMENT_ADDR_START(reg) - res->start;
+ }
+
+ return controller->ahb_base + offset;
+}
+
+static void aspeed_smc_chip_enable_write(struct aspeed_smc_chip *chip)
+{
+ struct aspeed_smc_controller *controller = chip->controller;
+ u32 reg;
+
+ reg = readl(controller->regs + CONFIG_REG);
+
+ reg |= aspeed_smc_chip_write_bit(chip);
+ writel(reg, controller->regs + CONFIG_REG);
+}
+
+static void aspeed_smc_chip_set_type(struct aspeed_smc_chip *chip, int type)
+{
+ struct aspeed_smc_controller *controller = chip->controller;
+ u32 reg;
+
+ chip->type = type;
+
+ reg = readl(controller->regs + CONFIG_REG);
+ reg &= ~(3 << (chip->cs * 2));
+ reg |= chip->type << (chip->cs * 2);
+ writel(reg, controller->regs + CONFIG_REG);
+}
+
+/*
+ * The AST2500 FMC flash controller should be strapped by hardware, or
+ * autodetected, but the AST2500 SPI flash needs to be set.
+ */
+static void aspeed_smc_chip_set_4b(struct aspeed_smc_chip *chip)
+{
+ struct aspeed_smc_controller *controller = chip->controller;
+ u32 reg;
+
+ if (chip->controller->info == &spi_2500_info) {
+ reg = readl(controller->regs + CE_CONTROL_REG);
+ reg |= 1 << chip->cs;
+ writel(reg, controller->regs + CE_CONTROL_REG);
+ }
+}
+
+static int aspeed_smc_chip_setup_init(struct aspeed_smc_chip *chip,
+ struct resource *res)
+{
+ struct aspeed_smc_controller *controller = chip->controller;
+ const struct aspeed_smc_info *info = controller->info;
+ u32 reg, base_reg;
+
+ /*
+ * Always turn on the write enable bit to allow opcodes to be
+ * sent in user mode.
+ */
+ aspeed_smc_chip_enable_write(chip);
+
+ /* The driver only supports SPI type flash */
+ if (info->hastype)
+ aspeed_smc_chip_set_type(chip, smc_type_spi);
+
+ /*
+ * Configure chip base address in memory
+ */
+ chip->ahb_base = aspeed_smc_chip_base(chip, res);
+ if (!chip->ahb_base) {
+ dev_warn(chip->nor.dev, "CE segment window closed.\n");
+ return -1;
+ }
+
+ /*
+ * Get value of the inherited control register. U-Boot usually
+ * does some timing calibration on the FMC chip, so it's good
+ * to keep them. In the future, we should handle calibration
+ * from Linux.
+ */
+ reg = readl(chip->ctl);
+ dev_dbg(controller->dev, "control register: %08x\n", reg);
+
+ base_reg = reg & CONTROL_KEEP_MASK;
+ if (base_reg != reg) {
+ dev_info(controller->dev,
+ "control register changed to: %08x\n",
+ base_reg);
+ }
+ chip->ctl_val[smc_base] = base_reg;
+
+ /*
+ * Retain the prior value of the control register as the
+ * default if it was normal access mode. Otherwise start with
+ * the sanitized base value set to read mode.
+ */
+ if ((reg & CONTROL_COMMAND_MODE_MASK) ==
+ CONTROL_COMMAND_MODE_NORMAL)
+ chip->ctl_val[smc_read] = reg;
+ else
+ chip->ctl_val[smc_read] = chip->ctl_val[smc_base] |
+ CONTROL_COMMAND_MODE_NORMAL;
+
+ dev_dbg(controller->dev, "default control register: %08x\n",
+ chip->ctl_val[smc_read]);
+ return 0;
+}
+
+static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip)
+{
+ struct aspeed_smc_controller *controller = chip->controller;
+ const struct aspeed_smc_info *info = controller->info;
+ u32 cmd;
+
+ if (chip->nor.addr_width == 4 && info->set_4b)
+ info->set_4b(chip);
+
+ /*
+ * base mode has not been optimized yet. use it for writes.
+ */
+ chip->ctl_val[smc_write] = chip->ctl_val[smc_base] |
+ chip->nor.program_opcode << CONTROL_COMMAND_SHIFT |
+ CONTROL_COMMAND_MODE_WRITE;
+
+ dev_dbg(controller->dev, "write control register: %08x\n",
+ chip->ctl_val[smc_write]);
+
+ /*
+ * TODO: Adjust clocks if fast read is supported and interpret
+ * SPI-NOR flags to adjust controller settings.
+ */
+ switch (chip->nor.flash_read) {
+ case SPI_NOR_NORMAL:
+ cmd = CONTROL_COMMAND_MODE_NORMAL;
+ break;
+ case SPI_NOR_FAST:
+ cmd = CONTROL_COMMAND_MODE_FREAD;
+ break;
+ default:
+ dev_err(chip->nor.dev, "unsupported SPI read mode\n");
+ return -EINVAL;
+ }
+
+ chip->ctl_val[smc_read] |= cmd |
+ CONTROL_IO_DUMMY_SET(chip->nor.read_dummy / 8);
+
+ dev_dbg(controller->dev, "base control register: %08x\n",
+ chip->ctl_val[smc_read]);
+ return 0;
+}
+
+static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
+ struct device_node *np, struct resource *r)
+{
+ const struct aspeed_smc_info *info = controller->info;
+ struct device *dev = controller->dev;
+ struct device_node *child;
+ unsigned int cs;
+ int ret = -ENODEV;
+
+ for_each_available_child_of_node(np, child) {
+ struct aspeed_smc_chip *chip;
+ struct spi_nor *nor;
+ struct mtd_info *mtd;
+
+ /* This driver does not support NAND or NOR flash devices. */
+ if (!of_device_is_compatible(child, "jedec,spi-nor"))
+ continue;
+
+ ret = of_property_read_u32(child, "reg", &cs);
+ if (ret) {
+ dev_err(dev, "Couldn't not read chip select.\n");
+ break;
+ }
+
+ if (cs >= info->nce) {
+ dev_err(dev, "Chip select %d out of range.\n",
+ cs);
+ ret = -ERANGE;
+ break;
+ }
+
+ if (controller->chips[cs]) {
+ dev_err(dev, "Chip select %d already in use by %s\n",
+ cs, dev_name(controller->chips[cs]->nor.dev));
+ ret = -EBUSY;
+ break;
+ }
+
+ chip = devm_kzalloc(controller->dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ chip->controller = controller;
+ chip->ctl = controller->regs + info->ctl0 + cs * 4;
+ chip->cs = cs;
+
+ nor = &chip->nor;
+ mtd = &nor->mtd;
+
+ nor->dev = dev;
+ nor->priv = chip;
+ spi_nor_set_flash_node(nor, child);
+ nor->read = aspeed_smc_read_user;
+ nor->write = aspeed_smc_write_user;
+ nor->read_reg = aspeed_smc_read_reg;
+ nor->write_reg = aspeed_smc_write_reg;
+ nor->prepare = aspeed_smc_prep;
+ nor->unprepare = aspeed_smc_unprep;
+
+ ret = aspeed_smc_chip_setup_init(chip, r);
+ if (ret)
+ break;
+
+ /*
+ * TODO: Add support for SPI_NOR_QUAD and SPI_NOR_DUAL
+ * attach when board support is present as determined
+ * by of property.
+ */
+ ret = spi_nor_scan(nor, NULL, SPI_NOR_NORMAL);
+ if (ret)
+ break;
+
+ ret = aspeed_smc_chip_setup_finish(chip);
+ if (ret)
+ break;
+
+ ret = mtd_device_register(mtd, NULL, 0);
+ if (ret)
+ break;
+
+ controller->chips[cs] = chip;
+ }
+
+ if (ret)
+ aspeed_smc_unregister(controller);
+
+ return ret;
+}
+
+static int aspeed_smc_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ struct aspeed_smc_controller *controller;
+ const struct of_device_id *match;
+ const struct aspeed_smc_info *info;
+ struct resource *res;
+ int ret;
+
+ match = of_match_device(aspeed_smc_matches, &pdev->dev);
+ if (!match || !match->data)
+ return -ENODEV;
+ info = match->data;
+
+ controller = devm_kzalloc(&pdev->dev, sizeof(*controller) +
+ info->nce * sizeof(controller->chips[0]), GFP_KERNEL);
+ if (!controller)
+ return -ENOMEM;
+ controller->info = info;
+ controller->dev = dev;
+
+ mutex_init(&controller->mutex);
+ platform_set_drvdata(pdev, controller);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ controller->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(controller->regs)) {
+ dev_err(dev, "Cannot remap controller address.\n");
+ return PTR_ERR(controller->regs);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ controller->ahb_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(controller->ahb_base)) {
+ dev_err(dev, "Cannot remap controller address.\n");
+ return PTR_ERR(controller->ahb_base);
+ }
+
+ ret = aspeed_smc_setup_flash(controller, np, res);
+ if (ret)
+ dev_err(dev, "Aspeed SMC probe failed %d\n", ret);
+
+ return ret;
+}
+
+static struct platform_driver aspeed_smc_driver = {
+ .probe = aspeed_smc_probe,
+ .remove = aspeed_smc_remove,
+ .driver = {
+ .name = DEVICE_NAME,
+ .of_match_table = aspeed_smc_matches,
+ }
+};
+
+module_platform_driver(aspeed_smc_driver);
+
+MODULE_DESCRIPTION("ASPEED Static Memory Controller Driver");
+MODULE_AUTHOR("Milton Miller");
+MODULE_LICENSE("GPL v2");
--
2.7.4
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related
* [PATCH v3 2/5] mtd: aspeed: add memory controllers for the Aspeed AST2400 SoC
From: Cédric Le Goater @ 2016-12-09 16:49 UTC (permalink / raw)
To: linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
Joel Stanley, Cédric Le Goater
In-Reply-To: <1481302167-28044-1-git-send-email-clg-Bxea+6Xhats@public.gmane.org>
This driver adds mtd support for the Aspeed AST2400 SoC static memory
controllers:
* New Static Memory Controller (referred as FMC)
. BMC firmware
. AST2500 compatible register set
. 5 chip select pins (CE0 ∼ CE4)
. supports NOR flash, NAND flash and SPI flash memory.
* SPI Flash Controller (SPI)
. host Firmware
. slightly different register set, between AST2500 and the legacy
controller
. supports SPI flash memory
. 1 chip select pin (CE0)
The legacy static memory controller (referred as SMC) is not
supported, as well as types other than SPI.
Signed-off-by: Cédric Le Goater <clg-Bxea+6Xhats@public.gmane.org>
---
drivers/mtd/spi-nor/Kconfig | 2 +-
drivers/mtd/spi-nor/aspeed-smc.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 5c0efbd9dd89..22bea563f9bc 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -35,7 +35,7 @@ config SPI_ASPEED
depends on HAS_IOMEM && OF
help
This enables support for the Firmware Memory controller (FMC)
- in the Aspeed AST2500 SoC when attached to SPI NOR chips,
+ in the Aspeed AST2500/AST2400 SoCs when attached to SPI NOR chips,
and support for the SPI flash memory controller (SPI) for
the host firmware. The implementation only supports SPI NOR.
diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index 6f9244f07aef..99302b0d7786 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -119,8 +119,27 @@ struct aspeed_smc_info {
void (*set_4b)(struct aspeed_smc_chip *chip);
};
+static void aspeed_smc_chip_set_4b_spi_2400(struct aspeed_smc_chip *chip);
static void aspeed_smc_chip_set_4b(struct aspeed_smc_chip *chip);
+static const struct aspeed_smc_info fmc_2400_info = {
+ .maxsize = 64 * 1024 * 1024,
+ .nce = 5,
+ .hastype = true,
+ .we0 = 16,
+ .ctl0 = 0x10,
+ .set_4b = aspeed_smc_chip_set_4b,
+};
+
+static const struct aspeed_smc_info spi_2400_info = {
+ .maxsize = 64 * 1024 * 1024,
+ .nce = 1,
+ .hastype = false,
+ .we0 = 0,
+ .ctl0 = 0x04,
+ .set_4b = aspeed_smc_chip_set_4b_spi_2400,
+};
+
static const struct aspeed_smc_info fmc_2500_info = {
.maxsize = 256 * 1024 * 1024,
.nce = 3,
@@ -210,6 +229,7 @@ struct aspeed_smc_controller {
#define CONTROL_IO_DUMMY_HI BIT(14)
#define CONTROL_IO_DUMMY_HI_SHIFT 14
#define CONTROL_CLK_DIV4 BIT(13) /* others */
+#define CONTROL_IO_ADDRESS_4B BIT(13) /* AST2400 SPI */
#define CONTROL_RW_MERGE BIT(12)
#define CONTROL_IO_DUMMY_LO_SHIFT 6
#define CONTROL_IO_DUMMY_LO GENMASK(7, \
@@ -406,6 +426,8 @@ static int aspeed_smc_remove(struct platform_device *dev)
}
static const struct of_device_id aspeed_smc_matches[] = {
+ { .compatible = "aspeed,ast2400-fmc", .data = &fmc_2400_info },
+ { .compatible = "aspeed,ast2400-spi", .data = &spi_2400_info },
{ .compatible = "aspeed,ast2500-fmc", .data = &fmc_2500_info },
{ .compatible = "aspeed,ast2500-spi", .data = &spi_2500_info },
{ }
@@ -479,6 +501,17 @@ static void aspeed_smc_chip_set_4b(struct aspeed_smc_chip *chip)
}
}
+/*
+ * The AST2400 SPI flash controller does not have a CE Control
+ * register. It uses the CE0 control register to set 4Byte mode at the
+ * controller level.
+ */
+static void aspeed_smc_chip_set_4b_spi_2400(struct aspeed_smc_chip *chip)
+{
+ chip->ctl_val[smc_base] |= CONTROL_IO_ADDRESS_4B;
+ chip->ctl_val[smc_read] |= CONTROL_IO_ADDRESS_4B;
+}
+
static int aspeed_smc_chip_setup_init(struct aspeed_smc_chip *chip,
struct resource *res)
{
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 3/5] mtd: aspeed: used a label property
From: Cédric Le Goater @ 2016-12-09 16:49 UTC (permalink / raw)
To: linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
Joel Stanley, Cédric Le Goater
In-Reply-To: <1481302167-28044-1-git-send-email-clg-Bxea+6Xhats@public.gmane.org>
This can be used to easily identify a chip on a system with multiple
chips.
Signed-off-by: Cédric Le Goater <clg-Bxea+6Xhats@public.gmane.org>
---
drivers/mtd/spi-nor/aspeed-smc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index 99302b0d7786..9119c0ca86b6 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -676,6 +676,8 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
nor->prepare = aspeed_smc_prep;
nor->unprepare = aspeed_smc_unprep;
+ mtd->name = of_get_property(child, "label", NULL);
+
ret = aspeed_smc_chip_setup_init(chip, r);
if (ret)
break;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 4/5] mtd: spi-nor: bindings for the Aspeed memory controllers
From: Cédric Le Goater @ 2016-12-09 16:49 UTC (permalink / raw)
To: linux-mtd
Cc: Mark Rutland, Boris Brezillon, devicetree, Richard Weinberger,
Marek Vasut, Rob Herring, Joel Stanley, Cyrille Pitchen,
Brian Norris, David Woodhouse, Cédric Le Goater
In-Reply-To: <1481302167-28044-1-git-send-email-clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
.../devicetree/bindings/mtd/aspeed-smc.txt | 51 ++++++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/aspeed-smc.txt
diff --git a/Documentation/devicetree/bindings/mtd/aspeed-smc.txt b/Documentation/devicetree/bindings/mtd/aspeed-smc.txt
new file mode 100644
index 000000000000..e2c88cea38f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/aspeed-smc.txt
@@ -0,0 +1,51 @@
+* Aspeed Firmware Memory controller
+* Aspeed SPI Flash Memory Controller
+
+The Firmware Memory Controller in the Aspeed AST2500 SoC supports
+three chip selects, two of which are always of SPI type and the third
+can be SPI or NOR type flash, but the driver only supports SPI.
+
+The two SPI flash memory controllers in the AST2500 each support two
+chip selects.
+
+Required properties:
+ - compatible : Should be one of
+ "aspeed,ast2400-fmc" for the AST2400 Firmware Memory Controller
+ "aspeed,ast2400-spi" for the AST2400 SPI Flash memory Controller
+ "aspeed,ast2500-fmc" for the AST2500 Firmware Memory Controller
+ "aspeed,ast2500-spi" for the AST2500 SPI flash memory controllers
+
+ - reg : the first contains the control register location and length,
+ the second contains the memory window mapping address and length
+ - #address-cells : must be 1 corresponding to chip select child binding
+ - #size-cells : must be 0 corresponding to chip select child binding
+
+Optional properties:
+ - interrupts : Should contain the interrupt for the dma device if an
+ FMC
+
+The child nodes are the SPI flash modules which must have a compatible
+property as specified in bindings/mtd/jedec,spi-nor.txt
+
+Optionally, the child node can contain properties for SPI mode (may be
+ignored):
+ - spi-max-frequency - max frequency of spi bus
+
+
+Example:
+fmc: fmc@1e620000 {
+ compatible = "aspeed,ast2500-fmc";
+ reg = < 0x1e620000 0x94
+ 0x20000000 0x02000000 >;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <19>;
+ flash@0 {
+ reg = < 0 >;
+ compatible = "jedec,spi-nor";
+ /* spi-max-frequency = <>; */
+ /* m25p,fast-read; */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
--
2.7.4
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related
* [PATCH v3 5/5] mtd: spi-nor: add a label property to jedec,spi-nor
From: Cédric Le Goater @ 2016-12-09 16:49 UTC (permalink / raw)
To: linux-mtd
Cc: Mark Rutland, Boris Brezillon, devicetree, Richard Weinberger,
Marek Vasut, Rob Herring, Joel Stanley, Cyrille Pitchen,
Brian Norris, David Woodhouse, Cédric Le Goater
In-Reply-To: <1481302167-28044-1-git-send-email-clg@kaod.org>
This can be used to easily identify a chip on a system with multiple
chips.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
index 2c91c03e7eb0..b7cd02a3ebe8 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
@@ -65,6 +65,7 @@ Optional properties:
all chips and support for it can not be detected at runtime.
Refer to your chips' datasheet to check if this is supported
by your chip.
+- label : name to assign to mtd. If omitted, the label is the MTD device name.
Example:
@@ -75,4 +76,5 @@ Example:
reg = <0>;
spi-max-frequency = <40000000>;
m25p,fast-read;
+ label = "System-firmware";
};
--
2.7.4
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related
* [PATCH v2 0/7] Add support for Video Data Order Adapter
From: Michael Tretter @ 2016-12-09 16:58 UTC (permalink / raw)
To: linux-media-u79uwXL29TY76Z2rM5mHXA
Cc: Philipp Zabel, devicetree-u79uwXL29TY76Z2rM5mHXA, Hans Verkuil,
Mauro Carvalho Chehab, Michael Tretter
Hello,
This is v2 of a patch series that adds support for the Video Data Order
Adapter (VDOA) that can be found on Freescale i.MX6. It converts the
macroblock tiled format produced by the CODA 960 video decoder to a
raster-ordered format for scanout.
Changes since v1:
- Dropped patch 8/9 of v1
- Patch 1/7: Add devicetree binding documentation for fsl-vdoa
- Patch 6/7: I merged patch 5/9 and patch 8/9 of v1 into a single patch
- Patch 6/7: Use dt compatible instead of a phandle to find VDOA device
- Patch 6/7: Always check VDOA availability even if disabled via module
parameter and do not print a message if VDOA cannot be found
- Patch 6/7: Do not change the CODA context in coda_try_fmt()
- Patch 6/7: Allocate an additional internal frame if the VDOA is in use
Michael
Michael Tretter (3):
[media] coda: fix frame index to returned error
[media] coda: use VDOA for un-tiling custom macroblock format
[media] coda: support YUYV output if VDOA is used
Philipp Zabel (4):
ARM: dts: imx6qdl: Add VDOA compatible and clocks properties
[media] coda: add i.MX6 VDOA driver
[media] coda: correctly set capture compose rectangle
[media] coda: add debug output about tiling
.../devicetree/bindings/media/fsl-vdoa.txt | 21 ++
arch/arm/boot/dts/imx6qdl.dtsi | 2 +
drivers/media/platform/Kconfig | 3 +
drivers/media/platform/coda/Makefile | 1 +
drivers/media/platform/coda/coda-bit.c | 93 ++++--
drivers/media/platform/coda/coda-common.c | 175 ++++++++++-
drivers/media/platform/coda/coda.h | 3 +
drivers/media/platform/coda/imx-vdoa.c | 335 +++++++++++++++++++++
drivers/media/platform/coda/imx-vdoa.h | 58 ++++
9 files changed, 649 insertions(+), 42 deletions(-)
create mode 100644 Documentation/devicetree/bindings/media/fsl-vdoa.txt
create mode 100644 drivers/media/platform/coda/imx-vdoa.c
create mode 100644 drivers/media/platform/coda/imx-vdoa.h
--
2.10.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 1/7] ARM: dts: imx6qdl: Add VDOA compatible and clocks properties
From: Michael Tretter @ 2016-12-09 16:58 UTC (permalink / raw)
To: linux-media
Cc: Philipp Zabel, devicetree, Hans Verkuil, Mauro Carvalho Chehab,
Philipp Zabel, Michael Tretter
In-Reply-To: <20161209165903.1293-1-m.tretter@pengutronix.de>
From: Philipp Zabel <philipp.zabel@gmail.com>
This adds a compatible property and the correct clock for the
i.MX6Q Video Data Order Adapter.
Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
.../devicetree/bindings/media/fsl-vdoa.txt | 21 +++++++++++++++++++++
arch/arm/boot/dts/imx6qdl.dtsi | 2 ++
2 files changed, 23 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/fsl-vdoa.txt
diff --git a/Documentation/devicetree/bindings/media/fsl-vdoa.txt b/Documentation/devicetree/bindings/media/fsl-vdoa.txt
new file mode 100644
index 0000000..5e45f9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/fsl-vdoa.txt
@@ -0,0 +1,21 @@
+Freescale Video Data Order Adapter
+==================================
+
+The Video Data Order Adapter (VDOA) is present on the i.MX6q. Its sole purpose
+it to to reorder video data from the macroblock tiled order produced by the
+CODA 960 VPU to the conventional raster-scan order for scanout.
+
+Required properties:
+- compatible: must be "fsl,imx6q-vdoa"
+- reg: the register base and size for the device registers
+- interrupts: the VDOA interrupt
+- clocks: the vdoa clock
+
+Example:
+
+vdoa@021e4000 {
+ compatible = "fsl,imx6q-vdoa";
+ reg = <0x021e4000 0x4000>;
+ interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_VDOA>;
+};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index b13b0b2..69e3668 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1153,8 +1153,10 @@
};
vdoa@021e4000 {
+ compatible = "fsl,imx6q-vdoa";
reg = <0x021e4000 0x4000>;
interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_VDOA>;
};
uart2: serial@021e8000 {
--
2.10.2
^ permalink raw reply related
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