* [PATCH v3 00/18] FSI device driver introduction
From: christopher.lee.bostic-Re5JQEeQqe8AvxtiuMwx3w @ 2017-01-16 21:22 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linux-I+IVW8TIWO2tmTQ+vhA3Yw,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
mturquette-rdvid1DuHRBWk0Htik3J/w,
geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
joel-U3u1mxZcP9KHXe+LvDLADg, jk-mnsaURCQ41sdnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, andrew-zrmu5oMJ5Fs,
alistair-Y4h6yKqj69EXC2x5gXVKYQ,
benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r
Cc: Chris Bostic
From: Chris Bostic <cbostic-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Introduction of the IBM 'Flexible Support Interface' (FSI) bus device
driver. FSI is a high fan out serial bus consisting of a clock and a serial
data line capable of running at speeds up to 166 MHz.
This set provides the basic framework to add FSI extensions to the
Linux bus and device models. Master specific implementations are
defined to utilize the core FSI function.
In Linux, we have a core FSI "bus type", along with drivers for FSI
masters and engines.
The FSI master drivers expose a read/write interface to the bus address
space. The master drivers are under drivers/fsi/fsi-master-*.c.
The core handles probing and discovery of slaves and slave
engines, using those read/write interfaces. It is responsible for
creating the endpoint Linux devices corresponding to the discovered
engines on each slave.
Slave engines are identified by an 'engine' type, and an optional
version. Engine, a.k.a. client, drivers are matched and bound to these
engines during discovery.
This patch set does not include extended FSI function such as:
* Hub master support
* Cascaded master support
* Application layer hot plug notification
* Application layer FSI bus status interface
Common FSI terminology:
* Master
Controller of the FSI bus. Only the master is allowed to control the
clock line and is the initiator of all transactions on a bus.
* Slave
The receiver or target of a master initiated transaction. The slave
cannot initiate communications on a bus and must respond to any
master requests for data.
* CFAM
Stands for Common Field replaceable unit Access Macro. A CFAM is an
ASIC residing in any device requiring FSI communications. CFAMs
consist of an array of hardware 'engines' used for various purposes.
I2C masters, UARTs, General Purpose IO hardware are common types of
these engines.
* Configuration Space / Table
A table contained at the beginning of each CFAM address space.
This table lists information such as the CFAM's ID, which engine types
and versions it has available, as well as its addressing range.
* FSI Engine driver
A device driver that registers with the FSI core so that it can access
devices it owns on an FSI bus.
Chris Bostic (8):
drivers/fsi: Kick off master scan via sysfs
drivers/fsi: Set up links for slave communication
drivers/fsi: Set slave SMODE to init communication
drivers/fsi: Remove all scanned devices during master unregister
drivers/fsi: Add FSI bus documentation
drivers/fsi: Add documentation for GPIO based FSI master
drivers/fsi: Document FSI master sysfs files in ABI
drivers/fsi: Add GPIO based FSI master
Jeremy Kerr (10):
drivers/fsi: Add empty fsi bus definitions
drivers/fsi: Add device & driver definitions
drivers/fsi: add driver to device matches
drivers/fsi: Add fsi master definition
drivers/fsi: Add slave definition
drivers/fsi: Add empty master scan
drivers/fsi: Add FSI crc calculators to library
drivers/fsi: Implement slave initialisation
drivers/fsi: scan slaves & register devices
drivers/fsi: Add device read/write/peek functions
Changes for v3:
- Patch set contained an invalid 18/18 test patch not
meant for community review, corrected.
Changes for v2:
- Change from atomic global for master number to ida simple
interface.
- Add valid pointer checks on register and unregister utils.
- Move CRC calculation utilities out of driver to lib path.
- Clean up white space issues.
- Remove added list management of master devices and use
instead the device_for_each_child method available in the
bus.
- Add new patch to document FSI bus functionality.
- Add new patch documenting FSI gpio master.
- Rearrage patch set to have documentation earlier than code
implementing it.
- Document all comptible strings used in device tree bindings.
- Elaborate documentation definition of FSI GPIO master.
- Describe in more detail what each GPIO FSI master pin is for.
- Re-order compatible strings in example binding so that most
specific device comes first.
- Indicate proper activation order of all FSI GPIO master pins.
- Fix an unmatched '>' bracket in the example for binding.
- Bracket each element of the example bindings individually.
- Add new patch documenting sysfs-bus-fsi attributes.
- Merge FSI GPIO master init into probe function.
- Set pin initial values at time of pin request.
- Assign value of master->master.dev at probe time.
- Use get_optional interfac for all optional GPIO pins.
Documentation/ABI/testing/sysfs-bus-fsi | 6 +
.../devicetree/bindings/fsi/fsi-master-gpio.txt | 71 +++
Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/fsi/Kconfig | 23 +
drivers/fsi/Makefile | 3 +
drivers/fsi/fsi-core.c | 494 +++++++++++++++++++
drivers/fsi/fsi-master-gpio.c | 530 +++++++++++++++++++++
drivers/fsi/fsi-master.h | 39 ++
include/linux/crc-fsi.h | 29 ++
include/linux/fsi.h | 60 +++
lib/Makefile | 1 +
lib/crc-fsi.c | 39 ++
14 files changed, 1352 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-fsi
create mode 100644 Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt
create mode 100644 Documentation/devicetree/bindings/fsi/fsi.txt
create mode 100644 drivers/fsi/Kconfig
create mode 100644 drivers/fsi/Makefile
create mode 100644 drivers/fsi/fsi-core.c
create mode 100644 drivers/fsi/fsi-master-gpio.c
create mode 100644 drivers/fsi/fsi-master.h
create mode 100644 include/linux/crc-fsi.h
create mode 100644 include/linux/fsi.h
create mode 100644 lib/crc-fsi.c
--
1.8.2.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 v3 02/18] drivers/fsi: Add device & driver definitions
From: christopher.lee.bostic-Re5JQEeQqe8AvxtiuMwx3w @ 2017-01-16 21:23 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linux-I+IVW8TIWO2tmTQ+vhA3Yw,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
mturquette-rdvid1DuHRBWk0Htik3J/w,
geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
joel-U3u1mxZcP9KHXe+LvDLADg, jk-mnsaURCQ41sdnm+yROfE0A,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, andrew-zrmu5oMJ5Fs,
alistair-Y4h6yKqj69EXC2x5gXVKYQ,
benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r
Cc: Chris Bostic
From: Jeremy Kerr <jk-mnsaURCQ41sdnm+yROfE0A@public.gmane.org>
Add structs for fsi devices & drivers, and struct device conversion
functions.
Signed-off-by: Jeremy Kerr <jk-mnsaURCQ41sdnm+yROfE0A@public.gmane.org>
Signed-off-by: Chris Bostic <cbostic-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
---
include/linux/fsi.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/linux/fsi.h b/include/linux/fsi.h
index 47aa181..f73886a 100644
--- a/include/linux/fsi.h
+++ b/include/linux/fsi.h
@@ -17,6 +17,17 @@
#include <linux/device.h>
+struct fsi_device {
+ struct device dev;
+};
+
+struct fsi_driver {
+ struct device_driver drv;
+};
+
+#define to_fsi_dev(devp) container_of(devp, struct fsi_device, dev)
+#define to_fsi_drv(drvp) container_of(drvp, struct fsi_driver, drv)
+
extern struct bus_type fsi_bus_type;
#endif /* LINUX_FSI_H */
--
1.8.2.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 related
* Re: [PATCH v2] mtd: spi-nor: add dt support for Everspin MRAMs
From: Marek Vasut @ 2017-01-16 21:24 UTC (permalink / raw)
To: Uwe Kleine-König, Masahiko Iwamoto, Jagan Teki,
Cyrille Pitchen
Cc: linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Rafał Miłecki,
Geert Uytterhoeven, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170116210039.25267-1-u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
On 01/16/2017 10:00 PM, Uwe Kleine-König wrote:
> The MR25 family doesn't support JEDEC, so they need explicit mentioning
> in the list of supported spi IDs. This makes it possible to add these
> using for example:
>
> compatible = "everspin,mr25h40";
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Acked-by: Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> Changes since (implicit) v1:
> - use Kib instead of kib
>
> drivers/mtd/devices/m25p80.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 9cf7fcd28034..aa50bd96de3a 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -305,6 +305,11 @@ static const struct spi_device_id m25p_ids[] = {
> {"m25p40-nonjedec"}, {"m25p80-nonjedec"}, {"m25p16-nonjedec"},
> {"m25p32-nonjedec"}, {"m25p64-nonjedec"}, {"m25p128-nonjedec"},
>
> + /* Everspin MRAMs */
> + { "mr25h256" }, /* 256 Kib, 40 MHz */
> + { "mr25h10" }, /* 1 Mib, 40 MHz */
> + { "mr25h40" }, /* 4 Mib, 40 MHz */
> +
> { },
> };
> MODULE_DEVICE_TABLE(spi, m25p_ids);
>
--
Best regards,
Marek Vasut
--
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] pcie: ti: Provide patch to force GEN1 PCIe operation
From: Lukasz Majewski @ 2017-01-16 21:44 UTC (permalink / raw)
To: Joao Pinto
Cc: Kishon Vijay Abraham I, jingoohan1@gmail.com, Bjorn Helgaas,
Rob Herring, Mark Rutland, linux-omap, linux-pci, devicetree,
linux-kernel
In-Reply-To: <76d18446-78c9-87f2-22ad-f7ea38771285@synopsys.com>
Hi Joao,
>
> Hi,
>
> Às 10:13 AM de 1/16/2017, Kishon Vijay Abraham I escreveu:
> > + Joao, Jingoo
> >
> > Hi,
> >
> > On Monday 16 January 2017 03:01 PM, Lukasz Majewski wrote:
> >> Hi Kishon,
> >>
> >>> Hi Łukasz,
> >>>
> >>> On Monday 16 January 2017 12:19 PM, Lukasz Majewski wrote:
> >>>> Hi Kishon,
> >>>>
> >>>>> Hi,
> >>>>>
> >>>>> On Sunday 15 January 2017 06:49 PM, Lukasz Majewski wrote:
> >>>>>> Some devices (due to e.g. bad PCIe signal integrity) require to
> >>>>>> run with forced GEN1 speed on PCIe bus.
> >>>>>>
> >>>>>> This patch changes the speed explicitly on dra7 based devices
> >>>>>> when proper device tree attribute is defined for the PCIe
> >>>>>> controller.
> >>>>>>
> >>>>>> Signed-off-by: Lukasz Majewski <lukma@denx.de>
> >>>>>
> >>>>> Bjorn has already queued a patch to do the same thing
> >>>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_cgit_linux_kernel_git_helgaas_pci.git_log_-3Fh-3Dpci_host-2Ddra7xx&d=DwIDaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=zD82T5n4WcL7Ga-NSY2NI7KE75xQ99hN-mW2yX46wQk&s=E8zk1CbKxGH-f3fw_WpXxFU-A8BLkgA8NusCaxk1SvA&e=
> >>>>
> >>>> It seems like Bjorn only modifies CAP registers.
> >>>
> >>> The patch also modifies the LNKCTL2 register.
> >>>>
> >>>> He also needs to change register with 0x080C offset to actually
> >>>> ( PCIECTRL_PL_WIDTH_SPEED_CTL )
> >>>
> >>> This bit is used to initiate speed change (after the link is
> >>> initialized in GEN1). Resetting the bit (like what you have done
> >>> here) prevents speed change.
> >>
> >> This is strange, but e2e advised me to do things as I did in the
> >> patch to _force_ GEN1 operation on PCIe2 port [1] (AM5728)
> >>
> >> Link:
> >> [1]
> >> https://urldefense.proofpoint.com/v2/url?u=https-3A__e2e.ti.com_support_arm_sitara-5Farm_f_791_t_566421&d=DwIDaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=s2fO0hii0OGNOv9qQy_HRXy-xAJUD1NNoEcc3io_kx0&m=zD82T5n4WcL7Ga-NSY2NI7KE75xQ99hN-mW2yX46wQk&s=uXLwglyRYqKpwp1JSxkOWmKpQ2wjfhgofpm8DCfquNw&e=
> >>
> >> Both patches modify 0x5180 007C register to set GEN1 capability
> >> (PCI_EXP_LNKCAP_SLS_2_5GB)
> >>
> >> The problem is with second register (in your patch):
> >>
> >> From SPRUHZ6G TRM:
> >>
> >> PCIECTRL_EP_DBICS_LNK_CAS_2 (0x5180 00A0)
> >> - TRGT_LINK_SPEED (Reset 0x1) - "Target Link Speed" - no more
> >> description in TRM
> >>
> >> It is set to PCI_EXP_LNKCAP_SLS_2_5GB = 0x1, which is the same as
> >> default /reset value.
> >
> > The default value is 0x2 (or else none of the cards would have
> > enumerated in GEN2)
> >>
> >>
> >> Could you clarify which way to _force_ PCIe GEN1 operation is
> >> correct? Mine shows differences in lspci output (as posted in [1]).
> >
> > You'll see the difference even with the patch in Bjorn's tree ;-)
> >
> > I think these are 2 different approaches to keep the link at GEN1.
> > Joao or Jingoo, do you have any suggestion here?
>
> I studied the Databook,
Could you reveal which databook do you have in mind? Is that the TRM for
AM5728?
> and both approaches seem to be right,
> dependently of the Core configuration and setup.
>
> The standard manual speed change sequence is:
> a) Write to PCIE_CAP_TARGET_LINK_SPEED (indicating desired speed)
Do you mean TRGT_LINK_SPEED @ 0x5180 00A0 ?
> b) Clear "Directed Speed Change"
CFG_DIRECTED_SPEED_CHANGE @ 0x5180 080C
> c) Set "Directed Speed Change"
>
> If "Directed Speed Change" is set (DEFAULT_GEN2_SPEED_CHANGE is the
> default value), it will execute LTSSM to initiate speed change to
> Gen2 or Gen3, after link is started in Gen1, and then the bit is
> automatically cleared.
Ok, so with default settings (after reset) we do have Gen1 speed link
and when we enable LTSSM (with LTSSM_EN bit setting) we negotiate to
Gen2/Gen3.
>
> Lukasz is reseting this bit, in order to avoid the LTSSM to be
> executed, which is correct.
So with CFG_DIRECTED_SPEED_CHANGE = 0, when I start LTSSM (with
LTSSM_EN) the state machine returns immediately and leaves link in the
Gen1?
The pci-dra7 driver always sets LTSSM_EN bit to start link negotiation.
> There is another way to prevent this
> automatic speed change, which is to set GEN1 speed before link up
> which might be difficult in some setups, so Kishon's also right.
>
> In my opinion Lukasz approach would be the one that might be more
> universal and more "secure".
The robustness is the key here since there are some devices, which on
particular HW must only work with Gen1 speed. When we start LTSSM state
machine and hence start negotiation to Gen2, not always the result of
LTSSM is correct and device is properly recognized.
>
> Joao
>
>
> >
> >>
> >>>
> >>> IMO the better way is to set the LNKCTL2 to GEN1 instead of
> >>> hacking the IP register.
> >>
> >> From the original patch description:
> >>
> >> "Add support to force Root Complex to work in GEN1 mode if so
> >> desired, but don't force GEN1 mode on any board just yet."
> >>
> >> Are there any (floating around) patches allowing forcing GEN1
> >> operation on any board (I would like to reuse/port them to my
> >> current solution)?
> >
> > For setting to GEN1 mode, "max-link-speed" should be set to 1 in dt
> > with the patch in Bjorn's tree.
> >
> > Thanks
> > Kishon
> >
>
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
^ permalink raw reply
* Re: [PATCH 2/2] power_supply: Add support for MAX14656 USB charger detector
From: Sebastian Reichel @ 2017-01-16 22:09 UTC (permalink / raw)
To: Alexander Kurz
Cc: Dmitry Eremin-Solenikov, David Woodhouse,
linux-pm-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1476893089-7233-2-git-send-email-akurz-3EoFODjbY6Q@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1103 bytes --]
Hi Alexander,
On Wed, Oct 19, 2016 at 06:04:49PM +0200, Alexander Kurz wrote:
> The MAX14656 USB charger detector, also known as "AL32" is used to detect
> the presence and capabilities of attached USB chargers. The device is
> attached via I2C plus one interrupt line to signalize events.
>
> The device can be found in LG smartphones like LS665 and LS770, compatible
> devices are present in 4th/5th generation Amazon Kindle readers referenced
> in source code packages as "Maxim AL32".
>
> The initial version of this driver has been extracted from LG source code
> package LGLS665_Android_Lollipop_LS665ZV3, enriched with information from
> the Kindle_src_4.1.3 source code package and adapted to the current power
> class sysfs interface. Non-Standard Apple chargers which the device may
> detect are mapped to the USB Battery Charging Specification Revision 1.2
> class USB_DCP.
>
> Signed-off-by: Alexander Kurz <akurz-3EoFODjbY6Q@public.gmane.org>
Sorry for the delay, this fell between the cracks. The driver looks
fine and I have queued it for 4.11.
-- Sebastian
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v3 2/4] dt-bindings: Add TI SCI PM Domains
From: Dave Gerlach @ 2017-01-16 22:12 UTC (permalink / raw)
To: Rob Herring
Cc: Ulf Hansson, Rafael J . Wysocki, Kevin Hilman,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
devicetree@vger.kernel.org, Nishanth Menon, Keerthy, Russell King,
Tero Kristo, Sudeep Holla, Santosh Shilimkar, Lokesh Vutla
In-Reply-To: <CAL_JsqJ9RitNC7ihC8ckJgV+49kaHk=W9tgdNBSjEfydhQS46A@mail.gmail.com>
On 01/13/2017 08:40 PM, Rob Herring wrote:
> On Fri, Jan 13, 2017 at 2:28 PM, Dave Gerlach <d-gerlach@ti.com> wrote:
>> On 01/13/2017 01:25 PM, Rob Herring wrote:
>>>
>>> On Thu, Jan 12, 2017 at 9:27 AM, Dave Gerlach <d-gerlach@ti.com> wrote:
>>>>
>>>> Rob,
>>>>
>>>> On 01/11/2017 03:34 PM, Rob Herring wrote:
>>>>>
>>>>>
>>>>> On Mon, Jan 9, 2017 at 11:57 AM, Dave Gerlach <d-gerlach@ti.com> wrote:
>>>>>>
>>>>>>
>>>>>> Rob,
>>>>>>
>>>>>> On 01/09/2017 11:50 AM, Rob Herring wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Jan 04, 2017 at 02:55:34PM -0600, Dave Gerlach wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Add a generic power domain implementation, TI SCI PM Domains, that
>>>>>>>> will hook into the genpd framework and allow the TI SCI protocol to
>>>>>>>> control device power states.
>>>>>>>>
>>>>>>>> Also, provide macros representing each device index as understood
>>>>>>>> by TI SCI to be used in the device node power-domain references.
>>>>>>>> These are identifiers for the K2G devices managed by the PMMC.
>>>>>>>>
>>>>>>>> Signed-off-by: Nishanth Menon <nm@ti.com>
>>>>>>>> Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
>>>>>>>> ---
>>>>>>>> v2->v3:
>>>>>>>> Update k2g_pds node docs to show it should be a child of pmmc
>>>>>>>> node.
>>>>>>>> In early versions a phandle was used to point to pmmc and
>>>>>>>> docs
>>>>>>>> still
>>>>>>>> incorrectly showed this.
>>>>>>>>
>>>>>>>> .../devicetree/bindings/soc/ti/sci-pm-domain.txt | 59
>>>>>>>> ++++++++++++++
>>>>>>>> MAINTAINERS | 2 +
>>>>>>>> include/dt-bindings/genpd/k2g.h | 90
>>>>>>>> ++++++++++++++++++++++
>>>>>>>> 3 files changed, 151 insertions(+)
>>>>>>>> create mode 100644
>>>>>>>> Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>> create mode 100644 include/dt-bindings/genpd/k2g.h
>>>>>>>>
>>>>>>>> diff --git
>>>>>>>> a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>> b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>> new file mode 100644
>>>>>>>> index 000000000000..4c9064e512cb
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>> @@ -0,0 +1,59 @@
>>>>>>>> +Texas Instruments TI-SCI Generic Power Domain
>>>>>>>> +---------------------------------------------
>>>>>>>> +
>>>>>>>> +Some TI SoCs contain a system controller (like the PMMC, etc...)
>>>>>>>> that
>>>>>>>> is
>>>>>>>> +responsible for controlling the state of the IPs that are present.
>>>>>>>> +Communication between the host processor running an OS and the
>>>>>>>> system
>>>>>>>> +controller happens through a protocol known as TI-SCI [1]. This pm
>>>>>>>> domain
>>>>>>>> +implementation plugs into the generic pm domain framework and makes
>>>>>>>> use
>>>>>>>> of
>>>>>>>> +the TI SCI protocol power on and off each device when needed.
>>>>>>>> +
>>>>>>>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>>>>>>>> +
>>>>>>>> +PM Domain Node
>>>>>>>> +==============
>>>>>>>> +The PM domain node represents the global PM domain managed by the
>>>>>>>> PMMC,
>>>>>>>> +which in this case is the single implementation as documented by the
>>>>>>>> generic
>>>>>>>> +PM domain bindings in
>>>>>>>> Documentation/devicetree/bindings/power/power_domain.txt.
>>>>>>>> +Because this relies on the TI SCI protocol to communicate with the
>>>>>>>> PMMC
>>>>>>>> it
>>>>>>>> +must be a child of the pmmc node.
>>>>>>>> +
>>>>>>>> +Required Properties:
>>>>>>>> +--------------------
>>>>>>>> +- compatible: should be "ti,sci-pm-domain"
>>>>>>>> +- #power-domain-cells: Must be 0.
>>>>>>>> +
>>>>>>>> +Example (K2G):
>>>>>>>> +-------------
>>>>>>>> + pmmc: pmmc {
>>>>>>>> + compatible = "ti,k2g-sci";
>>>>>>>> + ...
>>>>>>>> +
>>>>>>>> + k2g_pds: k2g_pds {
>>>>>>>> + compatible = "ti,sci-pm-domain";
>>>>>>>> + #power-domain-cells = <0>;
>>>>>>>> + };
>>>>>>>> + };
>>>>>>>> +
>>>>>>>> +PM Domain Consumers
>>>>>>>> +===================
>>>>>>>> +Hardware blocks that require SCI control over their state must
>>>>>>>> provide
>>>>>>>> +a reference to the sci-pm-domain they are part of and a unique
>>>>>>>> device
>>>>>>>> +specific ID that identifies the device.
>>>>>>>> +
>>>>>>>> +Required Properties:
>>>>>>>> +--------------------
>>>>>>>> +- power-domains: phandle pointing to the corresponding PM domain
>>>>>>>> node.
>>>>>>>> +- ti,sci-id: index representing the device id to be passed oevr SCI
>>>>>>>> to
>>>>>>>> + be used for device control.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> As I've already stated before, this goes in power-domain cells. When
>>>>>>> you
>>>>>>> have a single thing (i.e. node) that controls multiple things, then
>>>>>>> you
>>>>>>> you need to specify the ID for each of them in phandle args. This is
>>>>>>> how
>>>>>>> irqs, gpio, clocks, *everything* in DT works.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> You think the reasoning for doing it this way provided by both Ulf and
>>>>>> myself on v2 [1] is not valid then?
>>>>>>
>>>>>> From Ulf:
>>>>>>
>>>>>> To me, the TI SCI ID, is similar to a "conid" for any another "device
>>>>>> resource" (like clock, pinctrl, regulator etc) which we can describe
>>>>>> in DT and assign to a device node. The only difference here, is that
>>>>>> we don't have common API to fetch the resource (like clk_get(),
>>>>>> regulator_get()), but instead we fetches the device's resource from
>>>>>> SoC specific code, via genpd's device ->attach() callback.
>>>>>
>>>>>
>>>>>
>>>>> Sorry, but that sounds like a kernel problem to me and has nothing to
>>>>> do with DT bindings.
>>>>>
>>>>>> From me:
>>>>>>
>>>>>> Yes, you've pretty much hit it on the head. It is not an index into a
>>>>>> list
>>>>>> of genpds but rather identifies the device *within* a single genpd. It
>>>>>> is
>>>>>> a
>>>>>> property specific to each device that resides in a ti-sci-genpd, not a
>>>>>> mapping describing which genpd the device belongs to. The generic power
>>>>>> domain binding is concerned with mapping the device to a specific
>>>>>> genpd,
>>>>>> which is does fine for us, but we have a sub mapping for devices that
>>>>>> exist
>>>>>> inside a genpd which, we must describe as well, hence the ti,sci-id.
>>>>>>
>>>>>>
>>>>>> So to summarize, the genpd framework does interpret the phandle arg as
>>>>>> an
>>>>>> index into multiple genpds, just as you've said other frameworks do,
>>>>>> but
>>>>>> this is not what I am trying to do, we have multiple devices within
>>>>>> this
>>>>>> *single* genpd, hence the need for the ti,sci-id property.
>>>>>
>>>>>
>>>>>
>>>>> Fix the genpd framework rather than work around it in DT.
>>>>
>>>>
>>>>
>>>> I still disagree that this has nothing to do with DT bindings, as the
>>>> current DT binding represents something different already. I am trying to
>>>> extend it to give me additional information needed for our platforms. Are
>>>> you saying that we should break what the current DT binding already
>>>> represents to mean something else?
>>>
>>>
>>> No idea because what's the current binding? From the patch, looks like
>>> a new binding to me.
>>
>>
>> Yes, ti,sci-id is a new binding. I am referring to the current meaning of
>> the "power-domains" binding, which is where you are asking this property to
>> be added, in "power-domains" cells. This is documented here [1] in the
>> kernel, although looking at it I must admit it is not very clear.
>>
>> The power-domains cell represents an offset into an array of power domains,
>> if you choose to use it. That's what the genpd framework is hard coded to
>> interpret it as. This is correct, as it is an index into a static list of
>> power domains, used to identify which power domain a device belongs to,
>> which is exactly what the genpd framework itself is concerned with. This is
>> already how it is used in the kernel today.
>
> Strictly speaking, the cells are purely for the interpretation of the
> phandle they are associated with. If some controller wants to have 20
> cells, then it could assuming a good reason. The reality is we tend to
> align the meaning of the cells. If genpd is interpreting the cells and
> not letting the driver for the power domain controller interpret them,
> then still, genpd needs to be fixed.
Ok, perhaps the genpd folks on the thread can jump in here with any
thoughts that they have.
>
> IIRC, initially it was said genpd required 0 cells, hence my confusion.
>
>> My ti,sci-id is not an index into a list of power domains, so it should not
>> go in the power-domains cells and go against what the power-domains binding
>> says that the cell expects. We have one single power domain, and the new
>> ti,sci-id binding is not something the genpd framework itself is concerned
>> with as it's our property to identify a device inside a power domain, not to
>> identify which power domain it is associated with.
>
> What is the id used for? I can understand why you need to know what
> power domain a device is in (as power-domains identifies), but not
> what devices are in a power domain.
We have a system control processor that provides power management
services to the OS and it responsible for handling the power state of
each device. This control happens over a communication interface we have
called TI SCI (implemented at drivers/firmware/ti-sci.c). The
communication protocol uses these ids to identify each device within the
power domain so that the control processor can do what is necessary to
enable that device.
Regards,
Dave
>
> Rob
>
^ permalink raw reply
* Re: [PATCH 1/4] phy: sun4i-usb: support PHY0 on H3 in MUSB mode
From: Ondřej Jirman @ 2017-01-16 22:57 UTC (permalink / raw)
To: icenowy-ymACFijhrKM, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
Kishon Vijay Abraham I, Greg Kroah-Hartman, Bin Liu
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20170116191449.50397-2-icenowy-ymACFijhrKM@public.gmane.org>
Dne 16.1.2017 v 20:14 Icenowy Zheng napsal(a):
> The PHY0 on H3 can be wired either to MUSB controller or OHCI/EHCI
> controller.
>
> The original driver wired it to OHCI/EHCI controller; however, as the
> code to use PHY0 as OHCI/EHCI is missing, it makes the PHY fully
> unusable.
>
> Rename the register (according to its function and the name in BSP
> driver), and remove the code which wires the PHY0 to OHCI/EHCI, as MUSB
> can support both peripheral and host mode (although the host mode of
> MUSB is buggy).
>
> The register that is renamed is now unused, as its initial value is just
> MUSB mode. However, when OHCI/EHCI mode support is added, the register
> can be used again.
>
> Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> ---
> drivers/phy/phy-sun4i-usb.c | 25 +++++++++----------------
> 1 file changed, 9 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> index bf28a0fdd569..6b193a635c6b 100644
> --- a/drivers/phy/phy-sun4i-usb.c
> +++ b/drivers/phy/phy-sun4i-usb.c
> @@ -49,7 +49,7 @@
> #define REG_PHYBIST 0x08
> #define REG_PHYTUNE 0x0c
> #define REG_PHYCTL_A33 0x10
> -#define REG_PHY_UNK_H3 0x20
> +#define REG_PHY_OTGCTL 0x20
You have added REG_PHY_OTGCTL, but it is not used below.
regards,
o.
> #define REG_PMU_UNK1 0x10
>
> @@ -269,23 +269,16 @@ static int sun4i_usb_phy_init(struct phy *_phy)
> writel(val & ~2, phy->pmu + REG_PMU_UNK1);
> }
>
> - if (data->cfg->type == sun8i_h3_phy) {
> - if (phy->index == 0) {
> - val = readl(data->base + REG_PHY_UNK_H3);
> - writel(val & ~1, data->base + REG_PHY_UNK_H3);
> - }
> - } else {
> - /* Enable USB 45 Ohm resistor calibration */
> - if (phy->index == 0)
> - sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
> + /* Enable USB 45 Ohm resistor calibration */
> + if (phy->index == 0)
> + sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
>
> - /* Adjust PHY's magnitude and rate */
> - sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
> + /* Adjust PHY's magnitude and rate */
> + sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
>
> - /* Disconnect threshold adjustment */
> - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
> - data->cfg->disc_thresh, 2);
> - }
> + /* Disconnect threshold adjustment */
> + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
> + data->cfg->disc_thresh, 2);
>
> sun4i_usb_phy_passby(phy, 1);
>
>
^ permalink raw reply
* Re: [PATCH] i2c: core: helper function to detect slave mode
From: Vladimir Zapolskiy @ 2017-01-16 23:14 UTC (permalink / raw)
To: Luis Oliveira, Andy Shevchenko, Andy Shevchenko
Cc: Wolfram Sang, Rob Herring, Mark Rutland, Jarkko Nikula,
Mika Westerberg, linux-i2c-u79uwXL29TY76Z2rM5mHXA, devicetree,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Ramiro.Oliveira-HKixBCOQz3hWk0Htik3J/w, Joao Pinto,
CARLOS.PALMINHA-HKixBCOQz3hWk0Htik3J/w
In-Reply-To: <7fdf5d3c-d0ea-ec45-6b18-4573fff6dd11-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>
Hello Luis,
On 01/16/2017 12:32 PM, Luis Oliveira wrote:
> On 12-Jan-17 17:01, Andy Shevchenko wrote:
>> On Sat, 2017-01-07 at 03:24 +0200, Vladimir Zapolskiy wrote:
>>> On 01/07/2017 02:19 AM, Andy Shevchenko wrote:
>>>> On Sat, Jan 7, 2017 at 1:43 AM, Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
>>>> wrote:
>>>>> On 01/07/2017 12:45 AM, Andy Shevchenko wrote:
>>
>>>>>> + }
>>>>>>>> + } else if (IS_BUILTIN(CONFIG_ACPI) &&
>>>>>>>> ACPI_HANDLE(dev)) {
>>>>>>>> + dev_dbg(dev, "ACPI slave is not supported
>>>>>>>> yet\n");
>>>>>>>> + }
>>>>>>>
>>>>>>> If so, then it might be better to drop else-if stub for now.
>>>>>>
>>>>>> Please, don't.
>>>>>>
>>>>>
>>>>> Why do you ask for this stub to be added?
>>>>
>>>> 1. Exactly the reason you asked above. Here is the code which has
>>>> built differently on different platforms. x86 usually is not using
>>>> CONFIG_OF, ARM doesn't ACPI (versus ARM64). Check GPIO library for
>>>> existing examples.
>>>
>>> From the context by the stub I mean dev_dbg() in
>>> i2c_slave_mode_detect()
>>> function, I don't see a connection to GPIO library, please clarify.
>>
>> I agree that is not good proof for using IS_ENABLED/IS_BUILTIN macro.
>
> I can prepare a V3 and remove it if that's the decision.
>
from my review comments you may find that your v2 change contains a bug
plus it misses a minor but desirable code optimization. You may get more
review comments then, for example it is not obvious that on a platform
with both CONFIG_ACPI and CONFIG_OF enabled there should be an exclusive
selection of only one of two possible branches as in your code etc.
The discussed IS_BUILTIN() and dev_dbg() code chunks are other ones, for
both of them you may find my review comments and Andy's responses, it's
up to you as the author to make any updates or keep the code as is,
taking into account any expressed concerns and concerns about concerns
the maintainer will make a decision.
--
With best wishes,
Vladimir
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 2/3] MAINTAINERS: add zx2967 reset controller driver to ARM ZTE architecture
From: Baoyou Xie @ 2017-01-17 0:49 UTC (permalink / raw)
To: Philipp Zabel
Cc: Jun Nie, Rob Herring, mark.rutland, linux-arm-kernel, devicetree,
Linux Kernel Mailing List, Shawn Guo, xie.baoyou, chen.chaokai,
wang.qiang01
In-Reply-To: <1484577528.8415.147.camel@pengutronix.de>
[-- Attachment #1: Type: text/plain, Size: 1407 bytes --]
On 16 January 2017 at 22:38, Philipp Zabel <p.zabel@pengutronix.de> wrote:
> On Mon, 2017-01-16 at 18:56 +0800, Baoyou Xie wrote:
> > Add the zx2967 reset controller driver as maintained by ARM ZTE
> > architecture maintainers, as they're parts of the core IP.
> >
> > Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> > ---
> > MAINTAINERS | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 2793808..08f8155 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1980,10 +1980,12 @@ L: linux-arm-kernel@lists.infradead.org
> (moderated for non-subscribers)
> > S: Maintained
> > F: arch/arm/mach-zx/
> > F: drivers/clk/zte/
> > +F: drivers/reset/reset-zx2967.c
> > F: drivers/soc/zte/
> > F: drivers/thermal/zx*
> > F: Documentation/devicetree/bindings/arm/zte.txt
> > F: Documentation/devicetree/bindings/clock/zx296702-clk.txt
> > +F: Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
> > F: Documentation/devicetree/bindings/soc/zte/
> > F: Documentation/devicetree/bindings/thermal/zx*
> > F: include/dt-bindings/soc/zx*.h
>
> This patch doesn't apply on top of reset/next. I can rebase it, but it
> will cause a trivial merge conflict with the soc/thermal additions.
>
> I will send v3 patch, it base on linux/next branch and conflict without
the soc/thermal additions
> regards
> Philipp
>
>
[-- Attachment #2: Type: text/html, Size: 2339 bytes --]
^ permalink raw reply
* [PATCH V2 0/4] Enable onboard SDHCI for Nexus 5X (msm8992)
From: Jeremy McNicoll @ 2017-01-17 0:58 UTC (permalink / raw)
To: linux-arm-msm, linux-soc, devicetree, linux-mmc
Cc: andy.gross, sboyd, robh, arnd, bjorn.andersson, riteshh, git,
ulf.hansson, jszhang, jeremymc
V2->V1
------
* Removed SMD macro to define packet size
* Dropped "sdhci: dump vendor state and regs" as Ritesh has agreed to deal
with it as part of [https://lkml.org/lkml/2016/12/30/102] .
* Didn't include RobH's ACK as I stripped out the smd_rpm node from
msm8992-bullhead-rev-101.dts and created msm8994-smd-rpm.dtsi to share
between 8992 & 8994. All feedback from RobH was applied prior to making
this change.
All testing was performed with the inclusion of:
RESEND v1 -> http://www.spinics.net/lists/linux-arm-msm/msg25484.html
RESEND RFC -> http://www.spinics.net/lists/linux-arm-msm/msg25481.html
In V1 it was stated that
"Without the workaround (patch 5/5) mmc/sdhci didn't get detected 8/20
times. When including the afore mentioned workaround MMC detection is
100% (35 boots) ."
It turns out we weren't waiting long enough for detection. (see statement
below)
The following test results were obtained upon removing
the SDHCI workaround (patch 2/4):
-50 iterations
-100% successfully detected onboard storage
-2 times SDHCI detection took over 4+ min
-Sample size 1 (I only have 1 Nexus 5X)
General observations regarding workaround removal:
-detection of onboard storage is generally slower without
the workaround. No hard numbers to back this up just
a general observation. It may be because the author has
consumed far more caffeinated beverages compared to the
previous time V1.
-the failures observed in V1 were because my test script
did not wait long enough to declare failure. Previously
I was waiting 4 min to declare the SDHCI as missing.
This round I increased the duration to 10min.
NOTE to SDHCI maintainers:
"sdhci: Add quirk for delayed IRQ ACK" (patch 2/4) was
included, if there is no interest in including this change
feel free to drop it or provide guidance on how this type
of issue is generally dealt with.
Jeremy McNicoll (4):
clk: gcc: Updates for SDHCI enablement
sdhci: Add quirk for delayed IRQ ACK
arm64: dts: Enable SDHCI for Nexus 5X (msm8992)
dts: doc: rename rpm_requests to respect DT naming conventions
.../devicetree/bindings/clock/qcom,rpmcc.txt | 2 +-
.../bindings/regulator/qcom,smd-rpm-regulator.txt | 42 +++-
.../devicetree/bindings/soc/qcom/qcom,smd-rpm.txt | 6 +-
.../devicetree/bindings/soc/qcom/qcom,smd.txt | 2 +-
arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 2 +-
arch/arm/boot/dts/qcom-apq8084.dtsi | 2 +-
.../dts/qcom-msm8974-lge-nexus5-hammerhead.dts | 2 +-
.../boot/dts/qcom-msm8974-sony-xperia-honami.dts | 2 +-
arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
.../boot/dts/qcom/msm8992-bullhead-rev-101.dts | 2 +
arch/arm64/boot/dts/qcom/msm8992-pins.dtsi | 82 ++++++
arch/arm64/boot/dts/qcom/msm8992.dtsi | 153 ++++++++++++
arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi | 276 +++++++++++++++++++++
drivers/clk/qcom/gcc-msm8994.c | 108 ++++++--
drivers/mmc/host/sdhci-msm.c | 7 +
drivers/mmc/host/sdhci.c | 12 +-
drivers/mmc/host/sdhci.h | 2 +
drivers/regulator/qcom_smd-regulator.c | 49 ++++
include/dt-bindings/clock/qcom,gcc-msm8994.h | 32 ++-
20 files changed, 739 insertions(+), 48 deletions(-)
create mode 100644 arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
--
2.6.1
^ permalink raw reply
* [PATCH V2 1/4] clk: gcc: Updates for SDHCI enablement
From: Jeremy McNicoll @ 2017-01-17 0:58 UTC (permalink / raw)
To: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: andy.gross-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
robh-DgEjT+Ai2ygdnm+yROfE0A, arnd-r2nGTMty4D4,
bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
riteshh-sgV2jX0FEOL9JmXXK+q4OQ, git-LJ92rlH3Dns,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
jszhang-eYqpPyKDWXRBDgjK7y7TUQ, jeremymc-H+wXaHxf7aLQT0dZR+AlfA
In-Reply-To: <1484614729-26751-1-git-send-email-jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Global clock updates to enable onboard SDHCI / MMC.
Re-tabify dt-bindings to align correctly in vim.
Signed-off-by: Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/clk/qcom/gcc-msm8994.c | 108 +++++++++++++++++++++------
include/dt-bindings/clock/qcom,gcc-msm8994.h | 32 ++++----
2 files changed, 106 insertions(+), 34 deletions(-)
diff --git a/drivers/clk/qcom/gcc-msm8994.c b/drivers/clk/qcom/gcc-msm8994.c
index 8afd830..2bf8d1b 100644
--- a/drivers/clk/qcom/gcc-msm8994.c
+++ b/drivers/clk/qcom/gcc-msm8994.c
@@ -24,6 +24,7 @@
#include "common.h"
#include "clk-regmap.h"
+#include "clk-pll.h"
#include "clk-alpha-pll.h"
#include "clk-rcg.h"
#include "clk-branch.h"
@@ -54,7 +55,7 @@ static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
static const char * const gcc_xo_gpll0_gpll4[] = {
"xo",
"gpll0",
- "gpll4",
+ "gpll4_vote",
};
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
@@ -97,29 +98,65 @@ static struct clk_alpha_pll_postdiv gpll0 = {
},
};
-static struct clk_alpha_pll gpll4_early = {
- .offset = 0x1dc0,
- .clkr = {
- .enable_reg = 0x1480,
- .enable_mask = BIT(4),
- .hw.init = &(struct clk_init_data)
- {
- .name = "gpll4_early",
- .parent_names = (const char *[]) { "xo" },
- .num_parents = 1,
- .ops = &clk_alpha_pll_ops,
- },
+
+static struct clk_rcg2 config_noc_clk_src = {
+ .cmd_rcgr = 0x0150,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "config_noc_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 periph_noc_clk_src = {
+ .cmd_rcgr = 0x0190,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "periph_noc_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 system_noc_clk_src = {
+ .cmd_rcgr = 0x0120, //TODO
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "system_noc_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
},
};
-static struct clk_alpha_pll_postdiv gpll4 = {
- .offset = 0x1dc0,
+static struct clk_pll gpll4 = {
+ .status_reg = 0x1dc0,
+ .status_bit = 30,
.clkr.hw.init = &(struct clk_init_data)
{
.name = "gpll4",
- .parent_names = (const char *[]) { "gpll4_early" },
+ .parent_names = (const char *[]) { "xo" },
.num_parents = 1,
- .ops = &clk_alpha_pll_postdiv_ops,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll4_vote = {
+ .enable_reg = 0x1480,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gpll4_vote",
+ .parent_names = (const char *[]) { "gpll4" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
},
};
@@ -896,8 +933,8 @@ static struct freq_tbl ftbl_sdcc1_apps_clk_src[] = {
F(25000000, P_GPLL0, 12, 1, 2),
F(50000000, P_GPLL0, 12, 0, 0),
F(100000000, P_GPLL0, 6, 0, 0),
- F(192000000, P_GPLL4, 2, 0, 0),
- F(384000000, P_GPLL4, 1, 0, 0),
+ F(172000000, P_GPLL4, 2, 0, 0),
+ F(344000000, P_GPLL4, 1, 0, 0),
{ }
};
@@ -1057,6 +1094,10 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
.hw.init = &(struct clk_init_data)
{
.name = "gcc_blsp1_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -1872,6 +1913,7 @@ static struct clk_branch gcc_pdm2_clk = {
static struct clk_branch gcc_sdcc1_apps_clk = {
.halt_reg = 0x04c4,
+ .halt_check = BRANCH_HALT_VOTED,
.clkr = {
.enable_reg = 0x04c4,
.enable_mask = BIT(0),
@@ -1888,6 +1930,26 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
},
};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+ .halt_reg = 0x04c8,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x04c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc1_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+
static struct clk_branch gcc_sdcc2_apps_clk = {
.halt_reg = 0x0504,
.clkr = {
@@ -2123,10 +2185,13 @@ static struct clk_branch gcc_usb_hs_system_clk = {
};
static struct clk_regmap *gcc_msm8994_clocks[] = {
- [GPLL0_EARLY] = &gpll0_early.clkr,
+ [GPLL0_VOTE] = &gpll0_early.clkr,
[GPLL0] = &gpll0.clkr,
- [GPLL4_EARLY] = &gpll4_early.clkr,
+ [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr,
+ [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr,
+ [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr,
[GPLL4] = &gpll4.clkr,
+ [GPLL4_VOTE] = &gpll4_vote,
[UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr,
[USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
[BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
@@ -2231,6 +2296,7 @@ static struct clk_regmap *gcc_msm8994_clocks[] = {
[GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
[GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr,
[GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
+ [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
[GCC_SYS_NOC_UFS_AXI_CLK] = &gcc_sys_noc_ufs_axi_clk.clkr,
[GCC_SYS_NOC_USB3_AXI_CLK] = &gcc_sys_noc_usb3_axi_clk.clkr,
[GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8994.h b/include/dt-bindings/clock/qcom,gcc-msm8994.h
index 8fa535b..e4063d5 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8994.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8994.h
@@ -15,10 +15,10 @@
#ifndef _DT_BINDINGS_CLK_MSM_GCC_8994_H
#define _DT_BINDINGS_CLK_MSM_GCC_8994_H
-#define GPLL0_EARLY 0
#define GPLL0 1
-#define GPLL4_EARLY 2
-#define GPLL4 3
+#define GPLL0_VOTE 0
+#define GPLL4 2
+#define GPLL4_VOTE 3
#define UFS_AXI_CLK_SRC 4
#define USB30_MASTER_CLK_SRC 5
#define BLSP1_QUP1_I2C_APPS_CLK_SRC 6
@@ -123,15 +123,21 @@
#define GCC_SDCC2_APPS_CLK 105
#define GCC_SDCC3_APPS_CLK 106
#define GCC_SDCC4_APPS_CLK 107
-#define GCC_SYS_NOC_UFS_AXI_CLK 108
-#define GCC_SYS_NOC_USB3_AXI_CLK 109
-#define GCC_TSIF_REF_CLK 110
-#define GCC_UFS_AXI_CLK 111
-#define GCC_UFS_RX_CFG_CLK 112
-#define GCC_UFS_TX_CFG_CLK 113
-#define GCC_USB30_MASTER_CLK 114
-#define GCC_USB30_MOCK_UTMI_CLK 115
-#define GCC_USB3_PHY_AUX_CLK 116
-#define GCC_USB_HS_SYSTEM_CLK 117
+#define GCC_SDCC1_AHB_CLK 108
+#define GCC_SDCC2_AHB_CLK 109
+
+#define GCC_SYS_NOC_UFS_AXI_CLK 110
+#define GCC_SYS_NOC_USB3_AXI_CLK 111
+#define GCC_TSIF_REF_CLK 112
+#define GCC_UFS_AXI_CLK 113
+#define GCC_UFS_RX_CFG_CLK 114
+#define GCC_UFS_TX_CFG_CLK 115
+#define GCC_USB30_MASTER_CLK 116
+#define GCC_USB30_MOCK_UTMI_CLK 117
+#define GCC_USB3_PHY_AUX_CLK 118
+#define GCC_USB_HS_SYSTEM_CLK 119
+#define SYSTEM_NOC_CLK_SRC 120
+#define PERIPH_NOC_CLK_SRC 121
+#define CONFIG_NOC_CLK_SRC 122
#endif
--
2.6.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V2 2/4] sdhci: Add quirk for delayed IRQ ACK
From: Jeremy McNicoll @ 2017-01-17 0:58 UTC (permalink / raw)
To: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: andy.gross-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
robh-DgEjT+Ai2ygdnm+yROfE0A, arnd-r2nGTMty4D4,
bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
riteshh-sgV2jX0FEOL9JmXXK+q4OQ, git-LJ92rlH3Dns,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
jszhang-eYqpPyKDWXRBDgjK7y7TUQ, jeremymc-H+wXaHxf7aLQT0dZR+AlfA
In-Reply-To: <1484614729-26751-1-git-send-email-jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On msm8992 it has been observed that IRQs were not getting
ACK'd correctly when clocked at speeds greater than 400KHz.
Signed-off-by: Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/mmc/host/sdhci-msm.c | 7 +++++++
drivers/mmc/host/sdhci.c | 12 ++++++++++--
drivers/mmc/host/sdhci.h | 2 ++
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index ee01d95..25dc9cb 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1224,6 +1224,13 @@ static int sdhci_msm_probe(struct platform_device *pdev)
CORE_VENDOR_SPEC_CAPABILITIES0);
}
+ /* Enable delayed IRQ handling workaround on 8992 */
+ if (core_major == 1 && core_minor == 0x3e) {
+ /* Add 40us delay in interrupt handler when operating
+ * at initialization frequency of 400KHz. */
+ host->quirks2 |= SDHCI_QUIRK2_SLOW_INT_CLR;
+ }
+
/* Setup IRQ for handling power/voltage tasks with PMIC */
msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq");
if (msm_host->pwr_irq < 0) {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 71654b9..b685b2a 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2678,11 +2678,19 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
result = IRQ_WAKE_THREAD;
}
- if (intmask & SDHCI_INT_CMD_MASK)
+ if (intmask & SDHCI_INT_CMD_MASK) {
+ if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
+ udelay(40);
+ }
sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
+ }
- if (intmask & SDHCI_INT_DATA_MASK)
+ if (intmask & SDHCI_INT_DATA_MASK) {
+ if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) && (host->clock <= 400000)) {
+ udelay(40);
+ }
sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
+ }
if (intmask & SDHCI_INT_BUS_POWER)
pr_err("%s: Card is consuming too much power!\n",
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 766df17..89a10e7 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -24,6 +24,8 @@
* Controller registers
*/
+#define SDHCI_QUIRK2_SLOW_INT_CLR (1<<5)
+
#define SDHCI_DMA_ADDRESS 0x00
#define SDHCI_ARGUMENT2 SDHCI_DMA_ADDRESS
--
2.6.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V2 3/4] arm64: dts: Enable SDHCI for Nexus 5X (msm8992)
From: Jeremy McNicoll @ 2017-01-17 0:58 UTC (permalink / raw)
To: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: andy.gross-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
robh-DgEjT+Ai2ygdnm+yROfE0A, arnd-r2nGTMty4D4,
bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
riteshh-sgV2jX0FEOL9JmXXK+q4OQ, git-LJ92rlH3Dns,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
jszhang-eYqpPyKDWXRBDgjK7y7TUQ, jeremymc-H+wXaHxf7aLQT0dZR+AlfA
In-Reply-To: <1484614729-26751-1-git-send-email-jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Add Nexus 5X (msm8992) SDHCI support, including initial regulator
entries to support enabling the main SDHCI/MMC.
The RPM is common between 8992 & 8994 simply reflect reality with
a shared DT entry.
The msm8994 RPM regulator talks over SMD to the APPS processor.
Signed-off-by: Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
Dropped RobH's ACK explicitly after addressing all feedback.
The reason is that msm8994-smd-rpm.dtsi was created to allow
for sharing between 8992 & 8994 as the RPM is common between
the two.
.../bindings/regulator/qcom,smd-rpm-regulator.txt | 40 +++
.../boot/dts/qcom/msm8992-bullhead-rev-101.dts | 2 +
arch/arm64/boot/dts/qcom/msm8992-pins.dtsi | 82 ++++++
arch/arm64/boot/dts/qcom/msm8992.dtsi | 153 ++++++++++++
arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi | 276 +++++++++++++++++++++
drivers/regulator/qcom_smd-regulator.c | 49 ++++
6 files changed, 602 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt
index 1f8d6f8..126989b 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt
@@ -23,6 +23,7 @@ Regulator nodes are identified by their compatible:
"qcom,rpm-pm8916-regulators"
"qcom,rpm-pm8941-regulators"
"qcom,rpm-pma8084-regulators"
+ "qcom,rpm-pm8994-regulators"
- vdd_s1-supply:
- vdd_s2-supply:
@@ -97,6 +98,40 @@ Regulator nodes are identified by their compatible:
Definition: reference to regulator supplying the input pin, as
described in the data sheet
+- vdd_s1-supply:
+- vdd_s2-supply:
+- vdd_s3-supply:
+- vdd_s4-supply:
+- vdd_s5-supply:
+- vdd_s6-supply:
+- vdd_s7-supply:
+- vdd_l1_l11-supply:
+- vdd_l2_l3_l4_l27-supply:
+- vdd_l5_l7-supply:
+- vdd_l6_l12_l14_l15_l26-supply:
+- vdd_l8-supply:
+- vdd_l9_l10_l13_l20_l23_l24-supply:
+- vdd_l1_l11-supply:
+- vdd_l6_l12_l14_l15_l26-supply:
+- vdd_l16_l25-supply:
+- vdd_l17-supply:
+- vdd_l18-supply:
+- vdd_l19-supply:
+- vdd_l21-supply:
+- vdd_l22-supply:
+- vdd_l16_l25-supply:
+- vdd_l27-supply:
+- vdd_l28-supply:
+- vdd_l29-supply:
+- vdd_l30-supply:
+- vdd_l31-supply:
+- vdd_l32-supply:
+ Usage: optional (pm8994 only)
+ Value type: <phandle>
+ Definition: reference to regulator supplying the input pin, as
+ described in the data sheet.
+
+
The regulator node houses sub-nodes for each regulator within the device. Each
sub-node is identified using the node's name, with valid values listed for each
of the pmics below.
@@ -118,6 +153,11 @@ pma8084:
l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20,
l21, l22, l23, l24, l25, l26, l27, lvs1, lvs2, lvs3, lvs4, 5vs1
+pm8994:
+ s1, s2, s3, s4, s5, s6, s7, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
+ l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, l25, l26,
+ l27, l28, l29, l30, l31, l32, lvs1, lvs2
+
The content of each sub-node is defined by the standard binding for regulators -
see regulator.txt.
diff --git a/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts
index 4542133..3fc9a33 100644
--- a/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts
+++ b/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts
@@ -39,3 +39,5 @@
};
};
};
+
+#include "msm8994-smd-rpm.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/msm8992-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8992-pins.dtsi
index d2a26f0..d3ae5ab 100644
--- a/arch/arm64/boot/dts/qcom/msm8992-pins.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8992-pins.dtsi
@@ -35,4 +35,86 @@
bias-pull-down;
};
};
+
+ /* 0-3 for sdc1 4-6 for sdc2 */
+ /* Order of pins */
+ /* SDC1: CLK -> 0, CMD -> 1, DATA -> 2, RCLK -> 3 */
+ /* SDC2: CLK -> 4, CMD -> 5, DATA -> 6 */
+ pmx-sdc1-clk {
+ sdc1_clk_on: clk-on {
+ pinmux {
+ pins = "sdc1_clk";
+ };
+ pinconf {
+ pins = "sdc1_clk";
+ bias-disable = <0>; /* No pull */
+ drive-strength = <16>; /* 16mA */
+ };
+ };
+ sdc1_clk_off: clk-off {
+ pinmux {
+ pins = "sdc1_clk";
+ };
+ pinconf {
+ pins = "sdc1_clk";
+ bias-disable = <0>; /* No pull */
+ drive-strength = <2>; /* 2mA */
+ };
+ };
+ };
+
+ pmx-sdc1-cmd {
+ sdc1_cmd_on: cmd-on {
+ pinmux {
+ pins = "sdc1_cmd";
+ };
+ pinconf {
+ pins = "sdc1_cmd";
+ bias-pull-up;
+ drive-strength = <8>;
+ };
+ };
+ sdc1_cmd_off: cmd-off {
+ pinmux {
+ pins = "sdc1_cmd";
+ };
+ pinconf {
+ pins = "sdc1_cmd";
+ bias-pull-up = <0x3>; /* same as 3.10 ?? */
+ drive-strength = <2>; /* 2mA */
+ };
+ };
+ };
+
+ pmx-sdc1-data {
+ sdc1_data_on: data-on {
+ pinmux {
+ pins = "sdc1_data";
+ };
+ pinconf {
+ pins = "sdc1_data";
+ bias-pull-up;
+ drive-strength = <8>; /* 8mA */
+ };
+ };
+ sdc1_data_off: data-off {
+ pinmux {
+ pins = "sdc1_data";
+ };
+ pinconf {
+ pins = "sdc1_data";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+ };
+ };
+
+ pmx-sdc1-rclk {
+ sdc1_rclk_on: rclk-on {
+ bias-pull-down; /* pull down */
+ };
+ sdc1_rclk_off: rclk-off {
+ bias-pull-down; /* pull down */
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi
index 44b2d37..77edffc 100644
--- a/arch/arm64/boot/dts/qcom/msm8992.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi
@@ -82,6 +82,12 @@
<0xf9002000 0x1000>;
};
+ apcs: syscon@f900d000 {
+ compatible = "syscon";
+ reg = <0xf900d000 0x2000>;
+ };
+
+
timer@f9020000 {
#address-cells = <1>;
#size-cells = <1>;
@@ -172,12 +178,159 @@
#power-domain-cells = <1>;
reg = <0xfc400000 0x2000>;
};
+
+ sdhci1: mmc@f9824900 {
+ compatible = "qcom,sdhci-msm-v4";
+ reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+
+ interrupts = <GIC_SPI 123 IRQ_TYPE_NONE>,
+ <GIC_SPI 138 IRQ_TYPE_NONE>;
+ interrupt-names = "hc_irq", "pwr_irq";
+
+ clocks = <&clock_gcc GCC_SDCC1_APPS_CLK>,
+ <&clock_gcc GCC_SDCC1_AHB_CLK>;
+ clock-names = "core", "iface";
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on
+ &sdc1_rclk_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off
+ &sdc1_rclk_off>;
+
+ vdd-supply = <&pm8994_l20>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <200 570000>;
+
+ vdd-io-supply = <&pm8994_s4>;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <200 325000>;
+
+ regulator-always-on;
+ bus-width = <8>;
+ mmc-hs400-1_8v;
+ status = "okay";
+ };
+
+ vreg_vph_pwr: vreg-vph-pwr {
+ compatible = "regulator-fixed";
+ status = "okay";
+ regulator-name = "vph-pwr";
+
+ regulator-min-microvolt = <3600000>;
+ regulator-max-microvolt = <3600000>;
+
+ regulator-always-on;
+ };
+
+ rpm_msg_ram: memory@fc428000 {
+ compatible = "qcom,rpm-msg-ram";
+ reg = <0xfc428000 0x4000>;
+ };
+
+ sfpb_mutex_regs: syscon@fd484000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "syscon";
+ reg = <0xfd484000 0x400>;
+ };
+
+ sfpb_mutex: hwmutex {
+ compatible = "qcom,sfpb-mutex";
+ syscon = <&sfpb_mutex_regs 0x0 0x100>;
+ #hwlock-cells = <1>;
+ };
+
+ smem {
+ compatible = "qcom,smem";
+ memory-region = <&smem_region>;
+ qcom,rpm-msg-ram = <&rpm_msg_ram>;
+ hwlocks = <&sfpb_mutex 3>;
+ };
};
memory {
device_type = "memory";
reg = <0 0 0 0>; // bootloader will update
};
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ smem_region: smem@6a00000 {
+ reg = <0x0 0x6a00000 0x0 0x200000>;
+ no-map;
+ };
+ };
+
+ smd_rpm: smd {
+ compatible = "qcom,smd";
+
+ rpm {
+ interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <6>;
+
+ rpm-requests {
+ compatible = "qcom,rpm-msm8994";
+ qcom,smd-channels = "rpm_requests";
+
+ rpmcc: qcom,rpmcc {
+ /* TODO: update when rpmcc-msm8994 support added */
+ compatible = "qcom,rpmcc-msm8916",
+ "qcom,rpmcc";
+ #clock-cells = <1>;
+ };
+
+ smd_rpm_regulators: pm8994-regulators {
+ compatible = "qcom,rpm-pm8994-regulators";
+
+ pm8994_s1: s1 {};
+ pm8994_s2: s2 {};
+ pm8994_s3: s3 {};
+ pm8994_s4: s4 {};
+ pm8994_s5: s5 {};
+ pm8994_s6: s6 {};
+ pm8994_s7: s7 {};
+
+ pm8994_l1: l1 {};
+ pm8994_l2: l2 {};
+ pm8994_l3: l3 {};
+ pm8994_l4: l4 {};
+ pm8994_l6: l6 {};
+ pm8994_l8: l8 {};
+ pm8994_l9: l9 {};
+ pm8994_l10: l10 {};
+ pm8994_l11: l11 {};
+ pm8994_l12: l12 {};
+ pm8994_l13: l13 {};
+ pm8994_l14: l14 {};
+ pm8994_l15: l15 {};
+ pm8994_l16: l16 {};
+ pm8994_l17: l17 {};
+ pm8994_l18: l18 {};
+ pm8994_l19: l19 {};
+ pm8994_l20: l20 {};
+ pm8994_l21: l21 {};
+ pm8994_l22: l22 {};
+ pm8994_l23: l23 {};
+ pm8994_l24: l24 {};
+ pm8994_l25: l25 {};
+ pm8994_l26: l26 {};
+ pm8994_l27: l27 {};
+ pm8994_l28: l28 {};
+ pm8994_l29: l29 {};
+ pm8994_l30: l30 {};
+ pm8994_l31: l31 {};
+ pm8994_l32: l32 {};
+ };
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi b/arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
new file mode 100644
index 0000000..d556aae
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
@@ -0,0 +1,276 @@
+/* Copyright (c) 2015, LGE Inc. All rights reserved.
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&smd_rpm {
+ rpm {
+ rpm_requests {
+ pm8994-regulators {
+
+ vdd_l1-supply = <&pm8994_s1>;
+ vdd_l2_26_28-supply = <&pm8994_s3>;
+ vdd_l3_11-supply = <&pm8994_s3>;
+ vdd_l4_27_31-supply = <&pm8994_s3>;
+ vdd_l5_7-supply = <&pm8994_s3>;
+ vdd_l6_12_32-supply = <&pm8994_s5>;
+ vdd_l8_16_30-supply = <&vreg_vph_pwr>;
+ vdd_l9_10_18_22-supply = <&vreg_vph_pwr>;
+ vdd_l13_19_23_24-supply = <&vreg_vph_pwr>;
+ vdd_l14_15-supply = <&pm8994_s5>;
+ vdd_l17_29-supply = <&vreg_vph_pwr>;
+ vdd_l20_21-supply = <&vreg_vph_pwr>;
+ vdd_l25-supply = <&pm8994_s5>;
+ /*vin_lvs1_2 = <&pm8994_s4>; */
+
+ s1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ };
+
+ s2 {
+ /* TODO */
+ };
+
+ s3 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ };
+
+ s4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-allow-set-load;
+ regulator-system-load = <325000>;
+ };
+
+ s5 {
+ regulator-min-microvolt = <2150000>;
+ regulator-max-microvolt = <2150000>;
+ };
+
+ s7 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ l1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ l2 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ };
+
+ l3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ l4 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ l5 {
+ /* TODO */
+ };
+
+ l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ l7 {
+ /* TODO */
+ };
+
+ l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ l9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ l10 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ };
+
+ l11 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ qcom,init-voltage = <1200000>;
+ };
+
+ l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ proxy-supply = <&pm8994_l12>;
+ qcom,proxy-consumer-enable;
+ qcom,proxy-consumer-current = <10000>;
+ status = "okay";
+ };
+
+ l13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,init-voltage = <2950000>;
+ status = "okay";
+ };
+
+ l14 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ qcom,init-voltage = <1200000>;
+ proxy-supply = <&pm8994_l14>;
+ qcom,proxy-consumer-enable;
+ qcom,proxy-consumer-current = <10000>;
+ status = "okay";
+ };
+
+ l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+
+ l16 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ qcom,init-voltage = <2700000>;
+ status = "okay";
+ };
+
+ l17 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ qcom,init-voltage = <2700000>;
+ status = "okay";
+ };
+
+ l18 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ qcom,init-voltage = <3000000>;
+ qcom,init-ldo-mode = <1>;
+ };
+
+ l19 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+
+ l20 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-allow-set-load;
+ regulator-system-load = <570000>;
+ };
+
+ l21 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ qcom,init-voltage = <1800000>;
+ };
+
+ l22 {
+ regulator-min-microvolt = <3100000>;
+ regulator-max-microvolt = <3100000>;
+ qcom,init-voltage = <3100000>;
+ };
+
+ l23 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ qcom,init-voltage = <2800000>;
+ };
+
+ l24 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3150000>;
+ qcom,init-voltage = <3075000>;
+ };
+
+ l25 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ };
+
+ l26 {
+ /* TODO: value from downstream
+ regulator-min-microvolt = <987500>;
+ fails to apply */
+ };
+
+ l27 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,init-voltage = <1050000>;
+ };
+
+ l28 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ qcom,init-voltage = <1000000>;
+ proxy-supply = <&pm8994_l28>;
+ qcom,proxy-consumer-enable;
+ qcom,proxy-consumer-current = <10000>;
+ };
+
+ l29 {
+ /* TODO: Unsupported voltage range.
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ qcom,init-voltage = <2800000>;
+ */
+ };
+
+ l30 {
+ /* TODO: get this verified
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ */
+ };
+
+ l31 {
+ regulator-min-microvolt = <1262500>;
+ regulator-max-microvolt = <1262500>;
+ qcom,init-voltage = <1262500>;
+ };
+
+ l32 {
+ /* TODO: get this verified
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ */
+ };
+ };
+ };
+ };
+};
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
index 8ed46a9..a7e8ce7 100644
--- a/drivers/regulator/qcom_smd-regulator.c
+++ b/drivers/regulator/qcom_smd-regulator.c
@@ -443,11 +443,60 @@ static const struct rpm_regulator_data rpm_pma8084_regulators[] = {
{}
};
+static const struct rpm_regulator_data rpm_pm8994_regulators[] = {
+ { "s1", QCOM_SMD_RPM_SMPA, 1, &pma8084_ftsmps, "vdd_s1" },
+ { "s2", QCOM_SMD_RPM_SMPA, 2, &pma8084_ftsmps, "vdd_s2" },
+ { "s3", QCOM_SMD_RPM_SMPA, 3, &pma8084_hfsmps, "vdd_s3" },
+ { "s4", QCOM_SMD_RPM_SMPA, 4, &pma8084_hfsmps, "vdd_s4" },
+ { "s5", QCOM_SMD_RPM_SMPA, 5, &pma8084_hfsmps, "vdd_s5" },
+ { "s6", QCOM_SMD_RPM_SMPA, 6, &pma8084_ftsmps, "vdd_s6" },
+ { "s7", QCOM_SMD_RPM_SMPA, 7, &pma8084_ftsmps, "vdd_s7" },
+
+ { "l1", QCOM_SMD_RPM_LDOA, 1, &pma8084_nldo, "vdd_l1_l11" },
+ { "l2", QCOM_SMD_RPM_LDOA, 2, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
+ { "l3", QCOM_SMD_RPM_LDOA, 3, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
+ { "l4", QCOM_SMD_RPM_LDOA, 4, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
+ { "l5", QCOM_SMD_RPM_LDOA, 5, &pma8084_pldo, "vdd_l5_l7" },
+ { "l6", QCOM_SMD_RPM_LDOA, 6, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
+ { "l7", QCOM_SMD_RPM_LDOA, 7, &pma8084_pldo, "vdd_l5_l7" },
+ { "l8", QCOM_SMD_RPM_LDOA, 8, &pma8084_pldo, "vdd_l8" },
+ { "l9", QCOM_SMD_RPM_LDOA, 9, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
+ { "l10", QCOM_SMD_RPM_LDOA, 10, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
+ { "l11", QCOM_SMD_RPM_LDOA, 11, &pma8084_nldo, "vdd_l1_l11" },
+ { "l12", QCOM_SMD_RPM_LDOA, 12, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
+ { "l13", QCOM_SMD_RPM_LDOA, 13, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
+ { "l14", QCOM_SMD_RPM_LDOA, 14, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
+ { "l15", QCOM_SMD_RPM_LDOA, 15, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
+ { "l16", QCOM_SMD_RPM_LDOA, 16, &pma8084_pldo, "vdd_l16_l25" },
+ { "l17", QCOM_SMD_RPM_LDOA, 17, &pma8084_pldo, "vdd_l17" },
+ { "l18", QCOM_SMD_RPM_LDOA, 18, &pma8084_pldo, "vdd_l18" },
+ { "l19", QCOM_SMD_RPM_LDOA, 19, &pma8084_pldo, "vdd_l19" },
+ { "l20", QCOM_SMD_RPM_LDOA, 20, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
+ { "l21", QCOM_SMD_RPM_LDOA, 21, &pma8084_pldo, "vdd_l21" },
+ { "l22", QCOM_SMD_RPM_LDOA, 22, &pma8084_pldo, "vdd_l22" },
+ { "l23", QCOM_SMD_RPM_LDOA, 23, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
+ { "l24", QCOM_SMD_RPM_LDOA, 24, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
+ { "l25", QCOM_SMD_RPM_LDOA, 25, &pma8084_pldo, "vdd_l16_l25" },
+ { "l26", QCOM_SMD_RPM_LDOA, 26, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
+ { "l27", QCOM_SMD_RPM_LDOA, 27, &pma8084_nldo, "vdd_l27" },
+ { "l28", QCOM_SMD_RPM_LDOA, 28, &pma8084_nldo, "vdd_l28" },
+ { "l29", QCOM_SMD_RPM_LDOA, 29, &pma8084_nldo, "vdd_l29" },
+ { "l30", QCOM_SMD_RPM_LDOA, 30, &pma8084_nldo, "vdd_l30" },
+ { "l31", QCOM_SMD_RPM_LDOA, 31, &pma8084_nldo, "vdd_l31" },
+ { "l32", QCOM_SMD_RPM_LDOA, 32, &pma8084_nldo, "vdd_l32" },
+
+ { "lvs1", QCOM_SMD_RPM_VSA, 1, &pma8084_switch },
+ { "lvs2", QCOM_SMD_RPM_VSA, 2, &pma8084_switch },
+
+ {}
+};
+
static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators },
{ .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators },
{ .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators },
{ .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators },
+ { .compatible = "qcom,rpm-pm8994-regulators", .data = &rpm_pm8994_regulators },
{}
};
MODULE_DEVICE_TABLE(of, rpm_of_match);
--
2.6.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V2 4/4] dts: doc: rename rpm_requests to respect DT naming conventions
From: Jeremy McNicoll @ 2017-01-17 0:58 UTC (permalink / raw)
To: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: andy.gross-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
robh-DgEjT+Ai2ygdnm+yROfE0A, arnd-r2nGTMty4D4,
bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
riteshh-sgV2jX0FEOL9JmXXK+q4OQ, git-LJ92rlH3Dns,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
jszhang-eYqpPyKDWXRBDgjK7y7TUQ, jeremymc-H+wXaHxf7aLQT0dZR+AlfA
In-Reply-To: <1484614729-26751-1-git-send-email-jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Node names cannot have an underscore '_' in the name.
Simply rename 'rpm_request' nodes to 'rpm-request'.
Signed-off-by: Jeremy McNicoll <jeremymc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
Documentation/devicetree/bindings/clock/qcom,rpmcc.txt | 2 +-
.../devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt | 2 +-
Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt | 6 +++---
Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt | 2 +-
arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 2 +-
arch/arm/boot/dts/qcom-apq8084.dtsi | 2 +-
arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts | 2 +-
arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts | 2 +-
arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi | 2 +-
11 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
index a7235e9..845dd57 100644
--- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
@@ -25,7 +25,7 @@ Example:
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
- rpm_requests {
+ rpm-requests {
compatible = "qcom,rpm-msm8916";
qcom,smd-channels = "rpm_requests";
diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt
index 126989b..e4799a4 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt
@@ -171,7 +171,7 @@ see regulator.txt.
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
- rpm_requests {
+ rpm-requests {
compatible = "qcom,rpm-msm8974";
qcom,smd-channels = "rpm_requests";
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt
index a48049c..30e1c75 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt
@@ -11,7 +11,7 @@ RPM node itself.
= SUBDEVICES
-The RPM exposes resources to its subnodes. The rpm_requests node must be
+The RPM exposes resources to its subnodes. The rpm-requests node must be
present and this subnode may contain children that designate regulator
resources.
@@ -29,7 +29,7 @@ resources.
Definition: must be "rpm_requests"
Refer to Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt
-for information on the regulator subnodes that can exist under the rpm_requests.
+for information on the regulator subnodes that can exist under the rpm-requests.
Example:
@@ -48,7 +48,7 @@ Example:
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
- rpm_requests {
+ rpm-requests {
compatible = "qcom,rpm-msm8974";
qcom,smd-channels = "rpm_requests";
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
index 97d9b3e..34b05c3 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
@@ -75,7 +75,7 @@ The following example represents a smd node, with one edge representing the
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
- rpm_requests {
+ rpm-requests {
compatible = "qcom,rpm-msm8974";
qcom,smd-channels = "rpm_requests";
diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
index ad51df2..ccae434 100644
--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
@@ -126,7 +126,7 @@
smd {
rpm {
- rpm_requests {
+ rpm-requests {
pm8841-regulators {
s1 {
regulator-min-microvolt = <675000>;
diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index 39eb7a4..ac3ec7d 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -457,7 +457,7 @@
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
- rpm_requests {
+ rpm-requests {
compatible = "qcom,rpm-apq8084";
qcom,smd-channels = "rpm_requests";
diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
index c0fb4a6..890566b 100644
--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
@@ -19,7 +19,7 @@
smd {
rpm {
- rpm_requests {
+ rpm-requests {
pm8841-regulators {
s1 {
regulator-min-microvolt = <675000>;
diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
index e7c1577..ec937c9 100644
--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
@@ -60,7 +60,7 @@
smd {
rpm {
- rpm_requests {
+ rpm-requests {
pm8841-regulators {
s1 {
regulator-min-microvolt = <675000>;
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index d210947..cb9cd53 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -668,7 +668,7 @@
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
- rpm_requests {
+ rpm-requests {
compatible = "qcom,rpm-msm8974";
qcom,smd-channels = "rpm_requests";
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index ed15e87..247fc51 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -812,7 +812,7 @@
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
- rpm_requests {
+ rpm-requests {
compatible = "qcom,rpm-msm8916";
qcom,smd-channels = "rpm_requests";
diff --git a/arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi b/arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
index d556aae..36fc582 100644
--- a/arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
@@ -13,7 +13,7 @@
&smd-rpm {
rpm {
- rpm_requests {
+ rpm-requests {
pm8994-regulators {
vdd_l1-supply = <&pm8994_s1>;
--
2.6.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v3 6/7] devicetree: power: bq27xxx: add monitored battery documentation
From: Sebastian Reichel @ 2017-01-17 0:59 UTC (permalink / raw)
To: Matt Ranostay
Cc: Rob Herring, linux-pm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren
In-Reply-To: <CAJ_EiSRnU1q8QPKO43hk3ajS=RaAtQ2tVJ-060GcmPoPA6Ranw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2878 bytes --]
Hi Matt,
On Fri, Jan 13, 2017 at 10:07:32PM -0800, Matt Ranostay wrote:
> On Fri, Jan 13, 2017 at 9:28 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> > On Tue, Jan 10, 2017 at 10:20:02PM -0800, Matt Ranostay wrote:
> >> Depends-On: http://marc.info/?l=linux-pm&m=148392292830015&w=2
> >> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> >> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
> >> ---
> >> Documentation/devicetree/bindings/power/supply/bq27xxx.txt | 8 ++++++++
> >> 1 file changed, 8 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/power/supply/bq27xxx.txt b/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
> >> index b0c95ef63e68..0472a2db0f13 100644
> >> --- a/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
> >> +++ b/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
> >> @@ -28,9 +28,17 @@ Required properties:
> >> * "ti,bq27621" - BQ27621
> >> - reg: integer, i2c address of the device.
> >>
> >> +Optional properties:
> >> +- monitored-battery: phandle of battery information devicetree node
> >
> > We need a common way to describe charger/monitor to battery connections,
> > not yet another way. The battery and power supply related bindings are a
> > bit of a mess from what I've looked at.
>
> Sebastian, your thoughts here?
On what part? Did you receive my comment on patch 1 from this
patchset? There I wrote basically the same:
> I think we should mandate the property name of the phandle in the
> generic binding instead of each potential fuel-gauge/charger.
> Maybe something like the following paragraph:
>
> Batteries are supposed to be referenced by chargers and/or
> fuel-gauges using a phandle. The phandle's property should
> be named "monitored-battery".
If you mean the second sentence: Yes, DT bindings for the
power-supply subsystem are a mess unfortunately. It's partially
my fault, but the (IMHO) really bad ones were already there when
I took over the power-supply subsystem (e.g. charger-manager,
which does not even describe real HW).
One of the problems is, that the power-supply subsystem does not
know about the difference between a fuel-gauge and a battery, since
smart batteries contain a fuel-gauge.
Regarding the phandles: We do have a standard property for the
battery <-> charger connection, which is described in
Documentation/devicetree/bindings/power/supply/power_supply.txt
Like most of the power-supply subsystem it expects, that battery
is a smart-battery with fuel-gauge. It does not really fit for
the battery <-> fuel-gauge connection, though.
TLDR: I suggest you implement the changes suggested by me and Rob
in patch 1 and resend the patch series. Then let's see if Rob is
ok with it.
-- Sebastian
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/2] devicetree: add Garmin vendor prefix
From: Marek Vasut @ 2017-01-17 1:07 UTC (permalink / raw)
To: Matt Ranostay, linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: jic23-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring
In-Reply-To: <20161229051306.28547-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
On 12/29/2016 06:13 AM, Matt Ranostay wrote:
Some commit message / description of the company would be useful.
> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
> ---
> Changes from v1:
> * switch to stock ticker for Garmin Limited
>
> Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 16d3b5e7f5d1..5749bfc5fc5b 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -107,6 +107,7 @@ firefly Firefly
> focaltech FocalTech Systems Co.,Ltd
> friendlyarm Guangzhou FriendlyARM Computer Tech Co., Ltd
> fsl Freescale Semiconductor
> +grmn Garmin Limited
Why grmn ? Why not 'garmin' ? Also, the rest uses Ltd. , so make it
consistent ?
> ge General Electric Company
> geekbuying GeekBuying
> gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
>
--
Best regards,
Marek Vasut
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] ARM64: dts: meson-gxbb-vega-s95: Add LED
From: Andreas Färber @ 2017-01-17 1:17 UTC (permalink / raw)
To: linux-amlogic
Cc: Carlo Caione, linux-arm-kernel, Andreas Färber, Rob Herring,
Mark Rutland, Catalin Marinas, Will Deacon, Kevin Hilman,
devicetree, linux-kernel
There is one blue LED on the front of the device. Keep it lit and
configure it as panic indicator.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index ab497126c9a3..b3937b72d102 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -53,6 +53,17 @@
stdout-path = "serial0:115200n8";
};
+ leds {
+ compatible = "gpio-leds";
+
+ blue {
+ label = "vega-s95:blue:on";
+ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ panic-indicator;
+ };
+ };
+
usb_vbus: regulator-usb0-vbus {
compatible = "regulator-fixed";
--
2.10.2
^ permalink raw reply related
* [PATCH v1] ARM: dts: imx: add fsl, imx35-wdt compatible to all relevant watchdog nodes
From: Vladimir Zapolskiy @ 2017-01-17 1:23 UTC (permalink / raw)
To: Shawn Guo, Fabio Estevam, Rob Herring, Uwe Kleine-König
Cc: devicetree, linux-watchdog, Russell King, Stefan Agner,
Wim Van Sebroeck, linux-arm-kernel, Sascha Hauer, Guenter Roeck
Watchdog device controller found on all modern SoCs from i.MX series
and firstly introduced in i.MX35 is not one in one compatible with the
watchdog controllers on i.MX21, i.MX27 and i.MX31, the latter
controlles don't have WICR (and pretimeout notification support) and
WMCR registers. To get benefit from the more advanced watchdog device
and to avoid operations over non-existing registers on legacy SoCs add
fsl,imx35-wdt compatible to descriptions of all i.MX35 compatible
watchdog controllers.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
RFC change is found at https://patchwork.kernel.org/patch/9350007
Changes from RFC to v1:
* added the same change to devicetree bindings documentation, thanks
to Baruch Siach for review,
* replaced a new shared compatible derived from i.MX25 with an earlier
from i.MX35 SoC one, thanks to Uwe Kleine-König for review.
Compatible "fsl,imx21-wdt" is preserved as a generic one, because
interface to a watchdog controller on i.MX35 is a superset of the
interface to a i.MX21 watchdog controller.
Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt | 2 +-
arch/arm/boot/dts/imx25.dtsi | 3 ++-
arch/arm/boot/dts/imx50.dtsi | 3 ++-
arch/arm/boot/dts/imx51.dtsi | 6 ++++--
arch/arm/boot/dts/imx53.dtsi | 6 ++++--
arch/arm/boot/dts/imx6qdl.dtsi | 6 ++++--
arch/arm/boot/dts/imx6sl.dtsi | 6 ++++--
arch/arm/boot/dts/imx6sx.dtsi | 9 ++++++---
arch/arm/boot/dts/imx6ul.dtsi | 6 ++++--
arch/arm/boot/dts/imx7s.dtsi | 12 ++++++++----
arch/arm/boot/dts/ls1021a.dtsi | 2 +-
arch/arm/boot/dts/vfxxx.dtsi | 3 ++-
12 files changed, 42 insertions(+), 22 deletions(-)
diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt
index 107280e..9551088 100644
--- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt
@@ -15,7 +15,7 @@ Optional properties:
Examples:
wdt@73f98000 {
- compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx51-wdt", "fsl,imx35-wdt", "fsl,imx21-wdt";
reg = <0x73f98000 0x4000>;
interrupts = <58>;
big-endian;
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
index 213d86e..1194fe2 100644
--- a/arch/arm/boot/dts/imx25.dtsi
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -505,7 +505,8 @@
};
wdog@53fdc000 {
- compatible = "fsl,imx25-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx25-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x53fdc000 0x4000>;
clocks = <&clks 126>;
clock-names = "";
diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
index fe0221e..476f54e 100644
--- a/arch/arm/boot/dts/imx50.dtsi
+++ b/arch/arm/boot/dts/imx50.dtsi
@@ -270,7 +270,8 @@
};
wdog1: wdog@53f98000 {
- compatible = "fsl,imx50-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx50-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x53f98000 0x4000>;
interrupts = <58>;
clocks = <&clks IMX5_CLK_DUMMY>;
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 33526ca..a67870b 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -347,14 +347,16 @@
};
wdog1: wdog@73f98000 {
- compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx51-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x73f98000 0x4000>;
interrupts = <58>;
clocks = <&clks IMX5_CLK_DUMMY>;
};
wdog2: wdog@73f9c000 {
- compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx51-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x73f9c000 0x4000>;
interrupts = <59>;
clocks = <&clks IMX5_CLK_DUMMY>;
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index ca51dc0..4d0c5c8 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -402,14 +402,16 @@
};
wdog1: wdog@53f98000 {
- compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx53-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x53f98000 0x4000>;
interrupts = <58>;
clocks = <&clks IMX5_CLK_DUMMY>;
};
wdog2: wdog@53f9c000 {
- compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx53-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x53f9c000 0x4000>;
interrupts = <59>;
clocks = <&clks IMX5_CLK_DUMMY>;
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 53e6e63..16ee492 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -594,14 +594,16 @@
};
wdog1: wdog@020bc000 {
- compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6q-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x020bc000 0x4000>;
interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_DUMMY>;
};
wdog2: wdog@020c0000 {
- compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6q-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x020c0000 0x4000>;
interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_DUMMY>;
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 4fd6de2..794f44d 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -479,14 +479,16 @@
};
wdog1: wdog@020bc000 {
- compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6sl-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x020bc000 0x4000>;
interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SL_CLK_DUMMY>;
};
wdog2: wdog@020c0000 {
- compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6sl-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x020c0000 0x4000>;
interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SL_CLK_DUMMY>;
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 076a30f..e36ead9 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -534,14 +534,16 @@
};
wdog1: wdog@020bc000 {
- compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6sx-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x020bc000 0x4000>;
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_DUMMY>;
};
wdog2: wdog@020c0000 {
- compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6sx-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x020c0000 0x4000>;
interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_DUMMY>;
@@ -1200,7 +1202,8 @@
};
wdog3: wdog@02288000 {
- compatible = "fsl,imx6sx-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6sx-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x02288000 0x4000>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_DUMMY>;
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 0f69a3f..33d9a2c 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -491,14 +491,16 @@
};
wdog1: wdog@020bc000 {
- compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6ul-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x020bc000 0x4000>;
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_WDOG1>;
};
wdog2: wdog@020c0000 {
- compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx6ul-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x020c0000 0x4000>;
interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_WDOG2>;
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 8db1eb9..ba38b69 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -399,14 +399,16 @@
};
wdog1: wdog@30280000 {
- compatible = "fsl,imx7d-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx7d-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x30280000 0x10000>;
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_WDOG1_ROOT_CLK>;
};
wdog2: wdog@30290000 {
- compatible = "fsl,imx7d-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx7d-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x30290000 0x10000>;
interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_WDOG2_ROOT_CLK>;
@@ -414,7 +416,8 @@
};
wdog3: wdog@302a0000 {
- compatible = "fsl,imx7d-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx7d-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x302a0000 0x10000>;
interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_WDOG3_ROOT_CLK>;
@@ -422,7 +425,8 @@
};
wdog4: wdog@302b0000 {
- compatible = "fsl,imx7d-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,imx7d-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x302b0000 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_WDOG4_ROOT_CLK>;
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 282d854..41f5afa 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -521,7 +521,7 @@
};
wdog0: watchdog@2ad0000 {
- compatible = "fsl,imx21-wdt";
+ compatible = "fsl,imx35-wdt", "fsl,imx21-wdt";
reg = <0x0 0x2ad0000 0x0 0x10000>;
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&platform_clk 1>;
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 5d654b5..360d590 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -326,7 +326,8 @@
};
wdoga5: wdog@4003e000 {
- compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
+ compatible = "fsl,vf610-wdt", "fsl,imx35-wdt",
+ "fsl,imx21-wdt";
reg = <0x4003e000 0x1000>;
interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_WDT>;
--
2.10.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 1/4] phy: sun4i-usb: support PHY0 on H3 in MUSB mode
From: Icenowy Zheng @ 2017-01-17 1:26 UTC (permalink / raw)
To: Ondřej Jirman
Cc: Greg Kroah-Hartman, Rob Herring,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Bin Liu,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA, Kishon Vijay Abraham I,
Maxime Ripard, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Chen-Yu Tsai
2017年1月17日 06:57于 Ondřej Jirman <megous@megous.com>写道:
>
> Dne 16.1.2017 v 20:14 Icenowy Zheng napsal(a):
> > The PHY0 on H3 can be wired either to MUSB controller or OHCI/EHCI
> > controller.
> >
> > The original driver wired it to OHCI/EHCI controller; however, as the
> > code to use PHY0 as OHCI/EHCI is missing, it makes the PHY fully
> > unusable.
> >
> > Rename the register (according to its function and the name in BSP
> > driver), and remove the code which wires the PHY0 to OHCI/EHCI, as MUSB
> > can support both peripheral and host mode (although the host mode of
> > MUSB is buggy).
> >
> > The register that is renamed is now unused, as its initial value is just
> > MUSB mode. However, when OHCI/EHCI mode support is added, the register
> > can be used again.
> >
> > Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> > ---
> > drivers/phy/phy-sun4i-usb.c | 25 +++++++++----------------
> > 1 file changed, 9 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> > index bf28a0fdd569..6b193a635c6b 100644
> > --- a/drivers/phy/phy-sun4i-usb.c
> > +++ b/drivers/phy/phy-sun4i-usb.c
> > @@ -49,7 +49,7 @@
> > #define REG_PHYBIST 0x08
> > #define REG_PHYTUNE 0x0c
> > #define REG_PHYCTL_A33 0x10
> > -#define REG_PHY_UNK_H3 0x20
> > +#define REG_PHY_OTGCTL 0x20
>
> You have added REG_PHY_OTGCTL, but it is not used below.
See the commit message.
I know it's now unused :-) It's just because the default mode is musb.
>
> regards,
> o.
>
> > #define REG_PMU_UNK1 0x10
> >
> > @@ -269,23 +269,16 @@ static int sun4i_usb_phy_init(struct phy *_phy)
> > writel(val & ~2, phy->pmu + REG_PMU_UNK1);
> > }
> >
> > - if (data->cfg->type == sun8i_h3_phy) {
> > - if (phy->index == 0) {
> > - val = readl(data->base + REG_PHY_UNK_H3);
> > - writel(val & ~1, data->base + REG_PHY_UNK_H3);
> > - }
> > - } else {
> > - /* Enable USB 45 Ohm resistor calibration */
> > - if (phy->index == 0)
> > - sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
> > + /* Enable USB 45 Ohm resistor calibration */
> > + if (phy->index == 0)
> > + sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
> >
> > - /* Adjust PHY's magnitude and rate */
> > - sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
> > + /* Adjust PHY's magnitude and rate */
> > + sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
> >
> > - /* Disconnect threshold adjustment */
> > - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
> > - data->cfg->disc_thresh, 2);
> > - }
> > + /* Disconnect threshold adjustment */
> > + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
> > + data->cfg->disc_thresh, 2);
> >
> > sun4i_usb_phy_passby(phy, 1);
> >
> >
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [PATCH v2 0/8] ARM: dts: Switch to new DSA binding
From: Florian Fainelli @ 2017-01-17 1:30 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Mark Rutland, Andrew Lunn, Jason Cooper,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
vivien.didelot, Russell King, open list, Rob Herring,
Gregory Clement, Sebastian Hesselbarth
In-Reply-To: <20170105192957.14304-1-f.fainelli@gmail.com>
On 01/05/2017 11:29 AM, Florian Fainelli wrote:
> Hi all,
>
> This patch series converts the in-tree users to utilize the new (relatively)
> DSA binding that was introduced with commit 8c5ad1d6179d ("net: dsa: Document
> new binding"). The legacy binding node is kept included, but is marked
> disabled.
>
> Changes in v2:
>
> - patch 1: Use an hexadecimal reg property
> - patch 2: fixed the subject
> - patch 3: s/okay/disabled/ for the legacy DSA node
> - patches 7/8: fixed a stray whitespace
>
> In about 2-3 releases we may consider removing the old DSA binding entirely
> from the kernel.
Gregory, are you going to take this for 4.11? Thanks
>
> Thank you!
>
> Florian Fainelli (8):
> ARM: dts: armada-370-rd: Utilize new DSA binding
> ARM: dts: armada-385-linksys: Utilize new DSA binding
> ARM: dts: armada-388-clearfog: Utilize new DSA binding
> ARM: dts: armada-xp-linksys-mamba: Utilize new DSA binding
> ARM: dts: kirkwood-dir665: Utilize new DSA binding
> ARM: dts: kirkwood-linksys-viper: Utilize new DSA binding
> ARM: dts: kirkwood-mv88f6281gtw-ge: Utilize new DSA binding
> ARM: dts: kirkwood-rd88f6281: Utilize new DSA binding
>
> arch/arm/boot/dts/armada-370-rd.dts | 44 +++++++++++++++++
> arch/arm/boot/dts/armada-385-linksys.dtsi | 52 ++++++++++++++++++++-
> arch/arm/boot/dts/armada-388-clearfog.dts | 65 ++++++++++++++++++++++++++
> arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 53 +++++++++++++++++++++
> arch/arm/boot/dts/kirkwood-dir665.dts | 49 +++++++++++++++++++
> arch/arm/boot/dts/kirkwood-linksys-viper.dts | 49 +++++++++++++++++++
> arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 49 +++++++++++++++++++
> arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts | 11 +++++
> arch/arm/boot/dts/kirkwood-rd88f6281.dtsi | 44 +++++++++++++++++
> 9 files changed, 415 insertions(+), 1 deletion(-)
>
--
Florian
^ permalink raw reply
* Re: [PATCH v4 2/2] mtd: spi-nor: add rockchip serial flash controller driver
From: Shawn Lin @ 2017-01-17 1:31 UTC (permalink / raw)
To: Cyrille Pitchen
Cc: David Woodhouse, Brian Norris, shawn.lin-TNX95d0MmH7DzftRWevZcw,
Marek Vasut, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Heiko Stuebner
In-Reply-To: <e5852f21-7aa0-8091-dc85-774e306e6f73-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
Hi Cyrille,
On 2017/1/16 19:10, Cyrille Pitchen wrote:
> Hi Shawn,
>
> Le 15/12/2016 à 10:27, Shawn Lin a écrit :
>> Add rockchip serial flash controller driver
>>
>> Signed-off-by: Shawn Lin <shawn.lin-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>>
>> ---
>>
>> Changes in v4:
>> - simplify the code of get_if_type
>> - use dma_dir to simplify the code
>> - simplify the rockchip_sfc_do_rd_wr
>> - some minor improvements
>> - add reset controller when doing resume
>>
>> Changes in v3:
>> - use io{read32,write32}_rep to simplify the corner cases
>> - remove more unnecessary bit definitions
>> - some minor comment fixes and improvement
>> - fix wrong unregister function
>> - unify more code
>> - use nor to avoid constantly replicating the whole
>> sfc->flash[sfc->num_chip].nor
>> - add email for MODULE_AUTHOR
>> - remove #if 1 --- #endif
>> - extract DMA code to imporve the code structure
>> - reset all when failing to do dma
>> - pass sfc to get_if_type
>> - rename sfc-no-dma to sfc-no-DMA
>>
>> Changes in v2:
>> - fix typos
>> - add some comment for buffer and others operations
>> - rename SFC_MAX_CHIP_NUM to MAX_CHIPSELECT_NUM
>> - use u8 for cs
>> - return -EINVAL for default case of get_if_type
>> - use readl_poll_*() to check timeout cases
>> - simplify and clarify some condition checks
>> - rework the bitshifts to simplify the code
>> - define SFC_CMD_DUMMY(x)
>> - fix ummap for dma read path and finish all the
>> cache maintenance.
>> - rename to rockchip_sfc_chip_priv and embed struct spi_nor
>> in it.
>> - add MODULE_AUTHOR
>> - add runtime PM and general PM support.
>> - Thanks for Marek's comments. Link:
>> http://lists.infradead.org/pipermail/linux-mtd/2016-November/070321.html
>>
>> MAINTAINERS | 8 +
>> drivers/mtd/spi-nor/Kconfig | 7 +
>> drivers/mtd/spi-nor/Makefile | 1 +
>> drivers/mtd/spi-nor/rockchip-sfc.c | 872 +++++++++++++++++++++++++++++++++++++
>> 4 files changed, 888 insertions(+)
>> create mode 100644 drivers/mtd/spi-nor/rockchip-sfc.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 1cd38a7..eb7e06d 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -10266,6 +10266,14 @@ L: linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> S: Odd Fixes
>> F: drivers/tty/serial/rp2.*
>>
>> +ROCKCHIP SERIAL FLASH CONTROLLER DRIVER
>> +M: Shawn Lin <shawn.lin-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>> +L: linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
>> +L: linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
>> +S: Maintained
>> +F: Documentation/devicetree/bindings/mtd/rockchip-sfc.txt
>> +F: drivers/mtd/spi-nor/rockchip-sfc.c
>> +
>> ROSE NETWORK LAYER
>> M: Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>
>> L: linux-hams-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
>> index 4a682ee..bf783a8 100644
>> --- a/drivers/mtd/spi-nor/Kconfig
>> +++ b/drivers/mtd/spi-nor/Kconfig
>> @@ -76,4 +76,11 @@ config SPI_NXP_SPIFI
>> Flash. Enable this option if you have a device with a SPIFI
>> controller and want to access the Flash as a mtd device.
>>
>> +config SPI_ROCKCHIP_SFC
>> + tristate "Rockchip Serial Flash Controller(SFC)"
>> + depends on ARCH_ROCKCHIP || COMPILE_TEST
>> + depends on HAS_IOMEM && HAS_DMA
>> + help
>> + This enables support for rockchip serial flash controller.
>> +
>> endif # MTD_SPI_NOR
>> diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
>> index 121695e..364d4c6 100644
>> --- a/drivers/mtd/spi-nor/Makefile
>> +++ b/drivers/mtd/spi-nor/Makefile
>> @@ -5,3 +5,4 @@ obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o
>> obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o
>> obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o
>> obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o
>> +obj-$(CONFIG_SPI_ROCKCHIP_SFC) += rockchip-sfc.o
>> diff --git a/drivers/mtd/spi-nor/rockchip-sfc.c b/drivers/mtd/spi-nor/rockchip-sfc.c
>> new file mode 100644
>> index 0000000..102c08f
>> --- /dev/null
>> +++ b/drivers/mtd/spi-nor/rockchip-sfc.c
>> @@ -0,0 +1,872 @@
>> +/*
>> + * Rockchip Serial Flash Controller Driver
>> + *
>> + * Copyright (c) 2016, Rockchip Inc.
>> + * Author: Shawn Lin <shawn.lin-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * 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/bitops.h>
>> +#include <linux/clk.h>
>> +#include <linux/completion.h>
>> +#include <linux/dma-mapping.h>
>> +#include <linux/iopoll.h>
>> +#include <linux/module.h>
>> +#include <linux/mtd/mtd.h>
>> +#include <linux/mtd/spi-nor.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/slab.h>
>> +
>> +/* System control */
>> +#define SFC_CTRL 0x0
>> +#define SFC_CTRL_COMMON_BITS_1 0x0
>> +#define SFC_CTRL_COMMON_BITS_2 0x1
>> +#define SFC_CTRL_COMMON_BITS_4 0x2
>> +#define SFC_CTRL_DATA_BITS_SHIFT 12
>> +#define SFC_CTRL_ADDR_BITS_SHIFT 10
>> +#define SFC_CTRL_CMD_BITS_SHIFT 8
>> +#define SFC_CTRL_PHASE_SEL_NEGETIVE BIT(1)
>> +
>> +/* Interrupt mask */
>> +#define SFC_IMR 0x4
>> +#define SFC_IMR_RX_FULL BIT(0)
>> +#define SFC_IMR_RX_UFLOW BIT(1)
>> +#define SFC_IMR_TX_OFLOW BIT(2)
>> +#define SFC_IMR_TX_EMPTY BIT(3)
>> +#define SFC_IMR_TRAN_FINISH BIT(4)
>> +#define SFC_IMR_BUS_ERR BIT(5)
>> +#define SFC_IMR_NSPI_ERR BIT(6)
>> +#define SFC_IMR_DMA BIT(7)
>> +/* Interrupt clear */
>> +#define SFC_ICLR 0x8
>> +#define SFC_ICLR_RX_FULL BIT(0)
>> +#define SFC_ICLR_RX_UFLOW BIT(1)
>> +#define SFC_ICLR_TX_OFLOW BIT(2)
>> +#define SFC_ICLR_TX_EMPTY BIT(3)
>> +#define SFC_ICLR_TRAN_FINISH BIT(4)
>> +#define SFC_ICLR_BUS_ERR BIT(5)
>> +#define SFC_ICLR_NSPI_ERR BIT(6)
>> +#define SFC_ICLR_DMA BIT(7)
>> +/* FIFO threshold level */
>> +#define SFC_FTLR 0xc
>> +#define SFC_FTLR_TX_SHIFT 0
>> +#define SFC_FTLR_TX_MASK 0x1f
>> +#define SFC_FTLR_RX_SHIFT 8
>> +#define SFC_FTLR_RX_MASK 0x1f
>> +/* Reset FSM and FIFO */
>> +#define SFC_RCVR 0x10
>> +#define SFC_RCVR_RESET BIT(0)
>> +/* Enhanced mode */
>> +#define SFC_AX 0x14
>> +/* Address Bit number */
>> +#define SFC_ABIT 0x18
>> +/* Interrupt status */
>> +#define SFC_ISR 0x1c
>> +#define SFC_ISR_RX_FULL_SHIFT BIT(0)
>> +#define SFC_ISR_RX_UFLOW_SHIFT BIT(1)
>> +#define SFC_ISR_TX_OFLOW_SHIFT BIT(2)
>> +#define SFC_ISR_TX_EMPTY_SHIFT BIT(3)
>> +#define SFC_ISR_TX_FINISH_SHIFT BIT(4)
>> +#define SFC_ISR_BUS_ERR_SHIFT BIT(5)
>> +#define SFC_ISR_NSPI_ERR_SHIFT BIT(6)
>> +#define SFC_ISR_DMA_SHIFT BIT(7)
>> +/* FIFO status */
>> +#define SFC_FSR 0x20
>> +#define SFC_FSR_TX_IS_FULL BIT(0)
>> +#define SFC_FSR_TX_IS_EMPTY BIT(1)
>> +#define SFC_FSR_RX_IS_EMPTY BIT(2)
>> +#define SFC_FSR_RX_IS_FULL BIT(3)
>> +/* FSM status */
>> +#define SFC_SR 0x24
>> +#define SFC_SR_IS_IDLE 0x0
>> +#define SFC_SR_IS_BUSY 0x1
>> +/* Raw interrupt status */
>> +#define SFC_RISR 0x28
>> +#define SFC_RISR_RX_FULL BIT(0)
>> +#define SFC_RISR_RX_UNDERFLOW BIT(1)
>> +#define SFC_RISR_TX_OVERFLOW BIT(2)
>> +#define SFC_RISR_TX_EMPTY BIT(3)
>> +#define SFC_RISR_TRAN_FINISH BIT(4)
>> +#define SFC_RISR_BUS_ERR BIT(5)
>> +#define SFC_RISR_NSPI_ERR BIT(6)
>> +#define SFC_RISR_DMA BIT(7)
>> +/* Master trigger */
>> +#define SFC_DMA_TRIGGER 0x80
>> +/* Src or Dst addr for master */
>> +#define SFC_DMA_ADDR 0x84
>> +/* Command */
>> +#define SFC_CMD 0x100
>> +#define SFC_CMD_IDX_SHIFT 0
>> +#define SFC_CMD_DUMMY_SHIFT 8
>> +#define SFC_CMD_DIR_RD 0
>> +#define SFC_CMD_DIR_WR 1
>> +#define SFC_CMD_DIR_SHIFT 12
>> +#define SFC_CMD_ADDR_ZERO (0x0 << 14)
>> +#define SFC_CMD_ADDR_24BITS (0x1 << 14)
>> +#define SFC_CMD_ADDR_32BITS (0x2 << 14)
>> +#define SFC_CMD_ADDR_FRS (0x3 << 14)
>> +#define SFC_CMD_TRAN_BYTES_SHIFT 16
>> +#define SFC_CMD_CS_SHIFT 30
>> +/* Address */
>> +#define SFC_ADDR 0x104
>> +/* Data */
>> +#define SFC_DATA 0x108
>> +
>> +#define SFC_MAX_CHIPSELECT_NUM 4
>> +#define SFC_DMA_MAX_LEN 0x4000
>> +#define SFC_CMD_DUMMY(x) \
>> + ((x) << SFC_CMD_DUMMY_SHIFT)
>> +
>> +enum rockchip_sfc_iftype {
>> + IF_TYPE_STD,
>> + IF_TYPE_DUAL,
>> + IF_TYPE_QUAD,
>> +};
>> +
>> +struct rockchip_sfc;
>> +struct rockchip_sfc_chip_priv {
>> + u8 cs;
>> + u32 clk_rate;
>> + struct spi_nor nor;
>> + struct rockchip_sfc *sfc;
>> +};
>> +
>> +struct rockchip_sfc {
>> + struct device *dev;
>> + struct mutex lock;
>> + void __iomem *regbase;
>> + struct clk *hclk;
>> + struct clk *clk;
>> + /* virtual mapped addr for dma_buffer */
>> + void *buffer;
>> + dma_addr_t dma_buffer;
>> + struct completion cp;
>> + struct rockchip_sfc_chip_priv flash[SFC_MAX_CHIPSELECT_NUM];
>> + u32 num_chip;
>> + bool use_dma;
>> + /* use negative edge of hclk to latch data */
>> + bool negative_edge;
>> +};
>> +
>> +static int get_if_type(struct rockchip_sfc *sfc, enum read_mode flash_read)
>> +{
>> + if (flash_read == SPI_NOR_DUAL)
>> + return IF_TYPE_DUAL;
>> + else if (flash_read == SPI_NOR_QUAD)
>> + return IF_TYPE_QUAD;
>> + else if (flash_read == SPI_NOR_NORMAL ||
>> + flash_read == SPI_NOR_FAST)
>> + return IF_TYPE_STD;
>> +
>> + dev_err(sfc->dev, "unsupported SPI read mode\n");
>> + return -EINVAL;
>> +}
>> +
>> +static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
>> +{
>> + int err;
>> + u32 status;
>> +
>> + writel_relaxed(SFC_RCVR_RESET, sfc->regbase + SFC_RCVR);
>> +
>> + err = readl_poll_timeout(sfc->regbase + SFC_RCVR, status,
>> + !(status & SFC_RCVR_RESET), 20,
>> + jiffies_to_usecs(HZ));
>> + if (err)
>> + dev_err(sfc->dev, "SFC reset never finished\n");
>> +
>> + /* Still need to clear the masked interrupt from RISR */
>> + writel_relaxed(SFC_ICLR_RX_FULL | SFC_ICLR_RX_UFLOW |
>> + SFC_ICLR_TX_OFLOW | SFC_ICLR_TX_EMPTY |
>> + SFC_ICLR_TRAN_FINISH | SFC_ICLR_BUS_ERR |
>> + SFC_ICLR_NSPI_ERR | SFC_ICLR_DMA,
>> + sfc->regbase + SFC_ICLR);
>> + return err;
>> +}
>> +
>> +static int rockchip_sfc_init(struct rockchip_sfc *sfc)
>> +{
>> + int err;
>> +
>> + err = rockchip_sfc_reset(sfc);
>> + if (err)
>> + return err;
>> +
>> + /* Mask all eight interrupts */
>> + writel_relaxed(0xff, sfc->regbase + SFC_IMR);
>> +
>> + /*
>> + * Phase configure for sfc to latch data by using
>> + * ahb clock, and this configuration should be Soc
>> + * specific.
>> + */
>> + if (sfc->negative_edge)
>> + writel_relaxed(SFC_CTRL_PHASE_SEL_NEGETIVE,
>> + sfc->regbase + SFC_CTRL);
>> + else
>> + writel_relaxed(0, sfc->regbase + SFC_CTRL);
>> +
>> + return 0;
>> +}
>> +
>> +static int rockchip_sfc_prep(struct spi_nor *nor, enum spi_nor_ops ops)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> + int ret;
>> +
>> + mutex_lock(&sfc->lock);
>> + pm_runtime_get_sync(sfc->dev);
>> +
>> + ret = clk_set_rate(sfc->clk, priv->clk_rate);
>> + if (ret)
>> + goto out;
>> +
>> + ret = clk_prepare_enable(sfc->clk);
>> + if (ret)
>> + goto out;
>> +
>> + return 0;
>> +
>> +out:
>> + mutex_unlock(&sfc->lock);
>> + return ret;
>> +}
>> +
>> +static void rockchip_sfc_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> +
>> + clk_disable_unprepare(sfc->clk);
>> + mutex_unlock(&sfc->lock);
>> + pm_runtime_mark_last_busy(sfc->dev);
>> + pm_runtime_put_autosuspend(sfc->dev);
>> +}
>> +
>> +static int rockchip_sfc_wait_op_finish(struct rockchip_sfc *sfc)
>> +{
>> + int err;
>> + u32 status;
>> +
>> + /*
>> + * Note: tx and rx share the same fifo, so the rx's water level
>> + * is the same as rx's, which means this function could be reused
>> + * for checking the read operations as well.
>> + */
>> + err = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
>> + status & SFC_FSR_TX_IS_EMPTY,
>> + 20, jiffies_to_usecs(2 * HZ));
>> + if (err)
>> + dev_err(sfc->dev, "SFC fifo never empty\n");
>> +
>> + return err;
>> +}
>> +
>> +static int rockchip_sfc_op_reg(struct spi_nor *nor,
>> + u8 opcode, int len, u8 optype)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> + u32 reg;
>> + bool tx_no_empty, rx_no_empty, is_busy;
>> + int err;
>> +
>> + reg = readl_relaxed(sfc->regbase + SFC_FSR);
>> + tx_no_empty = !(reg & SFC_FSR_TX_IS_EMPTY);
>> + rx_no_empty = !(reg & SFC_FSR_RX_IS_EMPTY);
>> +
>> + is_busy = readl_relaxed(sfc->regbase + SFC_SR);
>> +
>> + if (tx_no_empty || rx_no_empty || is_busy) {
>> + err = rockchip_sfc_reset(sfc);
>> + if (err)
>> + return err;
>> + }
>> +
>> + reg = opcode << SFC_CMD_IDX_SHIFT;
>> + reg |= len << SFC_CMD_TRAN_BYTES_SHIFT;
>> + reg |= priv->cs << SFC_CMD_CS_SHIFT;
>> + reg |= optype << SFC_CMD_DIR_SHIFT;
>> +
>> + writel_relaxed(reg, sfc->regbase + SFC_CMD);
>> +
>> + return rockchip_sfc_wait_op_finish(sfc);
>> +}
>> +
>> +static void rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
>> +{
>> + u32 tmp, i;
>> + int total_len = len;
>> +
>> + /* 32-bit access only */
>> + if (len >= 4 && !((u32)buf & 0x03)) {
>> + ioread32_rep(sfc->regbase + SFC_DATA, buf, len >> 2);
>> + len %= 4;
>> + buf += total_len - len;
>> + }
>> +
>> + /* read the rest bytes */
>> + for (i = 0; i < len; i++) {
>> + if (!(i & 0x03))
>> + tmp = readl_relaxed(sfc->regbase + SFC_DATA);
>> + buf[i] = (tmp >> ((i & 0x03) * 8)) & 0xff;
>> + }
>> +}
>> +
>> +static int rockchip_sfc_read_reg(struct spi_nor *nor, u8 opcode,
>> + u8 *buf, int len)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> + int ret;
>> +
>> + ret = rockchip_sfc_op_reg(nor, opcode, len, SFC_CMD_DIR_RD);
>> + if (ret)
>> + return ret;
>> +
>> + rockchip_sfc_read_fifo(sfc, buf, len);
>> +
>> + return 0;
>> +}
>> +
>> +static int rockchip_sfc_write_reg(struct spi_nor *nor, u8 opcode,
>> + u8 *buf, int len)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> + u32 dwords;
>> +
>> + /* Align bytes to dwords */
>> + dwords = DIV_ROUND_UP(len, sizeof(u32));
>> + iowrite32_rep(sfc->regbase + SFC_DATA, buf, dwords);
>> +
>> + return rockchip_sfc_op_reg(nor, opcode, len, SFC_CMD_DIR_WR);
>> +}
>> +
>> +static inline void rockchip_sfc_setup_transfer(struct spi_nor *nor,
>> + loff_t from_to,
>> + size_t len, u8 op_type)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> + u32 reg;
>> + u8 if_type = 0;
>> +
>> + if_type = get_if_type(sfc, nor->flash_read);
>> + writel_relaxed((if_type << SFC_CTRL_DATA_BITS_SHIFT) |
>> + (if_type << SFC_CTRL_ADDR_BITS_SHIFT) |
>> + (if_type << SFC_CTRL_CMD_BITS_SHIFT) |
>> + (sfc->negative_edge ? SFC_CTRL_PHASE_SEL_NEGETIVE : 0),
>> + sfc->regbase + SFC_CTRL);
>
> Marek rose an issue when commenting v3:
>
> Looking at that code it seems that even if the hardware can support SPI
> 1-1-n protocols, this driver actually allows SPI n-n-n protocols.
>
> However with the current spi-nor framework, the values of the enum
> read_mode must be understood this way:
> SPI_NOR_FAST or SPI_NOR_NORMAL: SPI 1-1-1 protocol
> SPI_NOR_DUAL: SPI 1-1-2 protocol
> SPI_NOR_QUAD: SPI 1-1-4 protocol
>
> Support to other SPI protocols such as SPI 1-4-4 or SPI 4-4-4 as not been
> accepted in mainline yet.
>
> Below in this driver, spi_nor_scan() is called with the value SPI_NOR_QUAD
> hence it asks the spi-nor framework for using the SPI 1-1-4 (and not SPI
> 4-4-4) *when supported by the QSPI memory*.
>
> Also since the driver was tested with a Winbond w25q256 memory, let me warn
> you that currently the SPI_NOR_QUAD_READ flag is *NOT* set in the "w25q256"
> entry of the spi_nor_ids[] array. So this claims this memory is not capable
> of using the SPI 1-1-4 protocol even if the Winbond memory actually
> supports this protocol. Then the spi-nor framework selects the SPI 1-1-1
> protocol as a fallback.
> That's why you have succeeded in using your driver but it would have failed
> with another QSPI memory with its SPI_NOR_QUAD_READ flag due to a protocol
> mismatch.
>
> So with the current spi-nor framework you must set
> SFC_CTRL_{DATA|ADDR}_BITS_SHIFT to IF_TYPE_STD.
>
> Later, once the patch adding support to other SPI protocols would have been
> accepted in mainline, you could update your driver to tell the spi-nor
> framework that the rockchip controller also supports SPI 1-2-2 and SPI
> 1-4-4 protocols.
>
Thanks, I will fix it in v5.
>
>> +
>> + if (op_type == SFC_CMD_DIR_WR)
>> + reg = nor->program_opcode << SFC_CMD_IDX_SHIFT;
>> + else
>> + reg = nor->read_opcode << SFC_CMD_IDX_SHIFT;
>> +
>> + reg |= op_type << SFC_CMD_DIR_SHIFT;
>> + reg |= (nor->addr_width == 4) ?
>> + SFC_CMD_ADDR_32BITS : SFC_CMD_ADDR_24BITS;
>> +
>> + reg |= priv->cs << SFC_CMD_CS_SHIFT;
>> + reg |= len << SFC_CMD_TRAN_BYTES_SHIFT;
>
> Looking at the definitions of SFC_CMD_TRAN_BYTES_SHIFT (16) and
> SFC_CMD_CS_SHIFT (30), I understand that the bitfield for the transfer
> length lays between bits 16 and 30 hence a 14 bit value at most.
> So what if len is greater than 16384? It overflows in the cs bitfield?
>
> You should apply masks to avoid such overflows and also test the len value
> then report the actual number of transferred bytes.
Sure, will fix.
>
>> +
>> + if (op_type == SFC_CMD_DIR_RD)
>> + reg |= SFC_CMD_DUMMY(nor->read_dummy);
>> +
>> + /* Should minus one as 0x0 means 1 bit flash address */
>> + writel_relaxed(nor->addr_width * 8 - 1, sfc->regbase + SFC_ABIT);
>> + writel_relaxed(reg, sfc->regbase + SFC_CMD);
>> + writel_relaxed(from_to, sfc->regbase + SFC_ADDR);
>> +}
>> +
>> +static int rockchip_sfc_do_dma_transfer(struct spi_nor *nor, loff_t from_to,
>> + dma_addr_t dma_buf, size_t len,
>> + u8 op_type)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> + u32 reg;
>> + int err = 0;
>> +
>> + init_completion(&sfc->cp);
>> +
>> + writel_relaxed(SFC_ICLR_RX_FULL | SFC_ICLR_RX_UFLOW |
>> + SFC_ICLR_TX_OFLOW | SFC_ICLR_TX_EMPTY |
>> + SFC_ICLR_TRAN_FINISH | SFC_ICLR_BUS_ERR |
>> + SFC_ICLR_NSPI_ERR | SFC_ICLR_DMA,
>> + sfc->regbase + SFC_ICLR);
>> +
>> + /* Enable transfer complete interrupt */
>> + reg = readl_relaxed(sfc->regbase + SFC_IMR);
>> + reg &= ~SFC_IMR_TRAN_FINISH;
>> + writel_relaxed(reg, sfc->regbase + SFC_IMR);
>> +
>> + rockchip_sfc_setup_transfer(nor, from_to, len, op_type);
>> + writel_relaxed(dma_buf, sfc->regbase + SFC_DMA_ADDR);
>> +
>> + /*
>> + * Start dma but note that the sfc->dma_buffer is derived from
>> + * dmam_alloc_coherent so we don't actually need any sync operations
>> + * for coherent dma memory.
>> + */
>> + writel_relaxed(0x1, sfc->regbase + SFC_DMA_TRIGGER);
>> +
>> + /* Wait for the interrupt. */
>> + if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) {
>> + dev_err(sfc->dev, "DMA wait for transfer finish timeout\n");
>> + err = -ETIMEDOUT;
>> + }
>> +
>> + /* Disable transfer finish interrupt */
>> + reg = readl_relaxed(sfc->regbase + SFC_IMR);
>> + reg |= SFC_IMR_TRAN_FINISH;
>> + writel_relaxed(reg, sfc->regbase + SFC_IMR);
>> +
>> + if (err) {
>> + rockchip_sfc_reset(sfc);
>> + return err;
>> + }
>> +
>> + return rockchip_sfc_wait_op_finish(sfc);
>> +}
>> +
>> +static inline int rockchip_sfc_pio_write(struct rockchip_sfc *sfc, u_char *buf,
>> + size_t len)
>> +{
>> + u32 dwords;
>> +
>> + /*
>> + * Align bytes to dwords, although we will write some extra
>> + * bytes to fifo but the transfer bytes number in SFC_CMD
>> + * register will make sure we just send out the expected
>> + * byte numbers and the extra bytes will be clean before
>> + * setting up the next transfer. We should always round up
>> + * to align to DWORD as the ahb for Rockchip Socs won't
>> + * support non-aligned-to-DWORD transfer.
>> + */
>> + dwords = DIV_ROUND_UP(len, sizeof(u32));
>> + iowrite32_rep(sfc->regbase + SFC_DATA, buf, dwords);
>> +
>> + return rockchip_sfc_wait_op_finish(sfc);
>> +}
>> +
>> +static inline int rockchip_sfc_pio_read(struct rockchip_sfc *sfc, u_char *buf,
>> + size_t len)
>> +{
>> + rockchip_sfc_read_fifo(sfc, buf, len);
>> +
>> + return rockchip_sfc_wait_op_finish(sfc);
>> +}
>> +
>> +static int rockchip_sfc_pio_transfer(struct spi_nor *nor, loff_t from_to,
>> + size_t len, u_char *buf, u8 op_type)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> +
>> + rockchip_sfc_setup_transfer(nor, from_to, len, op_type);
>> +
>> + if (op_type == SFC_CMD_DIR_WR)
>> + return rockchip_sfc_pio_write(sfc, buf, len);
>> + else
>> + return rockchip_sfc_pio_read(sfc, buf, len);
>> +}
>> +
>> +static int rockchip_sfc_dma_transfer(struct spi_nor *nor, loff_t from_to,
>> + size_t len, u_char *buf, u8 op_type)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> + size_t offset;
>> + int ret;
>> + dma_addr_t dma_addr = 0;
>> + int dma_dir;
>> +
>> + dma_dir = (op_type == SFC_CMD_DIR_RD) ?
>> + DMA_FROM_DEVICE : DMA_TO_DEVICE;
>> +
>> + for (offset = 0; offset < len; offset += SFC_DMA_MAX_LEN) {
>> + size_t trans = min_t(size_t, SFC_DMA_MAX_LEN, len - offset);
>> +
>> + dma_addr = dma_map_single(NULL, (void *)buf, trans, dma_dir);
> not good: buf may have been allocated with vmalloc() hence the pages of buf
> are not garanteed to be contiguous in physical memory.
>
> Just write a ubifs image into your QSPI memory and try to mount it. You are
> very likely to notice some issues/crashes.
>
You are right. I wasn't aware that the buf from vmalloc will pass in
here so I need to check the address and if that was coming from vmalloc,
we should use pre-allocated dma buf and do a copy here, although it's
quite low performance. :)
>
>> +
>> + if (dma_mapping_error(sfc->dev, dma_addr)) {
>> + /*
>> + * If we use pre-allocated dma_buffer, we need to
>> + * do a copy here.
>> + */
>> + if (op_type == SFC_CMD_DIR_WR)
>> + memcpy(sfc->buffer, buf + offset, trans);
>> +
>> + dma_addr = 0;
>> + }
>> +
>> + if (op_type == SFC_CMD_DIR_WR)
>> + /*
>> + * Flush the write data from write_buf to dma_addr
>> + * if using dynamic allocated dma buffer before dma
>> + * moves data from dma_addr to fifo.
>> + */
>> + dma_sync_single_for_device(sfc->dev, dma_addr,
>> + trans, DMA_TO_DEVICE);
>> +
>> +
>> + /* If failing to map dma, use pre-allocated area instead */
>> + ret = rockchip_sfc_do_dma_transfer(nor, from_to + offset,
>> + dma_addr ? dma_addr :
>> + sfc->dma_buffer,
>> + trans, op_type);
>> +
>> + if (dma_addr) {
>> + /*
>> + * Invalidate the read data from dma_addr if using
>> + * dynamic allocated dma buffer after dma moves data
>> + * from fifo to dma_addr.
>> + */
>> + if (op_type == SFC_CMD_DIR_RD)
>> + dma_sync_single_for_cpu(sfc->dev, dma_addr,
>> + trans, DMA_FROM_DEVICE);
>> +
>> + dma_unmap_single(NULL, dma_addr,
>> + trans, dma_dir);
>> + }
>> +
>> + if (ret) {
>> + dev_warn(nor->dev, "DMA read timeout\n");
>> + return ret;
>> + }
>> + /*
>> + * If we use pre-allocated dma_buffer for read, we need to
>> + * do a copy here.
>> + */
>> + if (!dma_addr && (op_type == SFC_CMD_DIR_RD))
>> + memcpy(buf + offset, sfc->buffer, trans);
>> + }
>> +
>> + return len;
>> +}
>> +
>> +static ssize_t rockchip_sfc_do_rd_wr(struct spi_nor *nor, loff_t from_to,
>> + size_t len, u_char *buf, u32 op_type)
>> +{
>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>> + struct rockchip_sfc *sfc = priv->sfc;
>> + int ret;
>> +
>> + if (likely(sfc->use_dma))
>> + return rockchip_sfc_dma_transfer(nor, from_to, len,
>> + buf, op_type);
>> +
>> + /* Fall back to PIO mode if DMA isn't present */
>> + ret = rockchip_sfc_pio_transfer(nor, from_to, len,
>> + (u_char *)buf, op_type);
>> + if (ret) {
>> + if (op_type == SFC_CMD_DIR_RD)
>> + dev_warn(nor->dev, "PIO read timeout\n");
>> + else
>> + dev_warn(nor->dev, "PIO write timeout\n");
>> + return ret;
>> + }
>> +
>> + return len;
>> +}
>> +
>> +static ssize_t rockchip_sfc_read(struct spi_nor *nor, loff_t from,
>> + size_t len, u_char *read_buf)
>> +{
>> + return rockchip_sfc_do_rd_wr(nor, from, len,
>> + read_buf, SFC_CMD_DIR_RD);
>> +}
>> +
>> +static ssize_t rockchip_sfc_write(struct spi_nor *nor, loff_t to,
>> + size_t len, const u_char *write_buf)
>> +{
>> + return rockchip_sfc_do_rd_wr(nor, to, len,
>> + (u_char *)write_buf,
>> + SFC_CMD_DIR_WR);
>> +}
>> +
>> +static int rockchip_sfc_register(struct device_node *np,
>> + struct rockchip_sfc *sfc)
>> +{
>> + struct device *dev = sfc->dev;
>> + struct mtd_info *mtd;
>> + struct spi_nor *nor;
>> + int ret;
>> +
>> + nor = &sfc->flash[sfc->num_chip].nor;
>> + nor->dev = dev;
>> + spi_nor_set_flash_node(nor, np);
>> +
>> + ret = of_property_read_u8(np, "reg", &sfc->flash[sfc->num_chip].cs);
>> + if (ret) {
>> + dev_err(dev, "No reg property for %s\n",
>> + np->full_name);
>> + return ret;
>> + }
>> +
>> + ret = of_property_read_u32(np, "spi-max-frequency",
>> + &sfc->flash[sfc->num_chip].clk_rate);
>> + if (ret) {
>> + dev_err(dev, "No spi-max-frequency property for %s\n",
>> + np->full_name);
>> + return ret;
>> + }
>> +
>> + sfc->flash[sfc->num_chip].sfc = sfc;
>> + nor->priv = &(sfc->flash[sfc->num_chip]);
>> +
>> + nor->prepare = rockchip_sfc_prep;
>> + nor->unprepare = rockchip_sfc_unprep;
>> + nor->read_reg = rockchip_sfc_read_reg;
>> + nor->write_reg = rockchip_sfc_write_reg;
>> + nor->read = rockchip_sfc_read;
>> + nor->write = rockchip_sfc_write;
>> + nor->erase = NULL;
>> + ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD);
>> + if (ret)
>> + return ret;
>> +
>> + mtd = &(nor->mtd);
>> + mtd->name = np->name;
>> + ret = mtd_device_register(mtd, NULL, 0);
>> + if (ret)
>> + return ret;
>> +
>> + sfc->num_chip++;
>> + return 0;
>> +}
>> +
>> +static void rockchip_sfc_unregister_all(struct rockchip_sfc *sfc)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < sfc->num_chip; i++)
>> + mtd_device_unregister(&sfc->flash[i].nor.mtd);
>> +}
>> +
>> +static int rockchip_sfc_register_all(struct rockchip_sfc *sfc)
>> +{
>> + struct device *dev = sfc->dev;
>> + struct device_node *np;
>> + int ret;
>> +
>> + for_each_available_child_of_node(dev->of_node, np) {
>> + ret = rockchip_sfc_register(np, sfc);
>> + if (ret)
>> + goto fail;
>> +
>> + if (sfc->num_chip == SFC_MAX_CHIPSELECT_NUM) {
>> + dev_warn(dev, "Exceeds the max cs limitation\n");
>> + break;
>> + }
>> + }
>> +
>> + return 0;
>> +
>> +fail:
>> + dev_err(dev, "Failed to register all chips\n");
>> + /* Unregister all the _registered_ nor flash */
>> + rockchip_sfc_unregister_all(sfc);
>> + return ret;
>> +}
>> +
>> +static irqreturn_t rockchip_sfc_irq_handler(int irq, void *dev_id)
>> +{
>> + struct rockchip_sfc *sfc = dev_id;
>> + u32 reg;
>> +
>> + reg = readl_relaxed(sfc->regbase + SFC_RISR);
>> + dev_dbg(sfc->dev, "Get irq: 0x%x\n", reg);
>> +
>> + /* Clear interrupt */
>> + writel_relaxed(reg, sfc->regbase + SFC_ICLR);
>> +
>> + if (reg & SFC_RISR_TRAN_FINISH)
>> + complete(&sfc->cp);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static int rockchip_sfc_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct resource *res;
>> + struct rockchip_sfc *sfc;
>> + int ret;
>> +
>> + sfc = devm_kzalloc(dev, sizeof(*sfc), GFP_KERNEL);
>> + if (!sfc)
>> + return -ENOMEM;
>> +
>> + platform_set_drvdata(pdev, sfc);
>> + sfc->dev = dev;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + sfc->regbase = devm_ioremap_resource(dev, res);
>> + if (IS_ERR(sfc->regbase))
>> + return PTR_ERR(sfc->regbase);
>> +
>> + sfc->clk = devm_clk_get(&pdev->dev, "sfc");
>> + if (IS_ERR(sfc->clk)) {
>> + dev_err(&pdev->dev, "Failed to get sfc interface clk\n");
>> + return PTR_ERR(sfc->clk);
>> + }
>> +
>> + sfc->hclk = devm_clk_get(&pdev->dev, "hsfc");
>> + if (IS_ERR(sfc->hclk)) {
>> + dev_err(&pdev->dev, "Failed to get sfc ahp clk\n");
>> + return PTR_ERR(sfc->hclk);
>> + }
>> +
>> + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
>> + if (ret) {
>> + dev_warn(dev, "Unable to set dma mask\n");
>> + return ret;
>> + }
>> +
>> + sfc->buffer = dmam_alloc_coherent(dev, SFC_DMA_MAX_LEN,
>> + &sfc->dma_buffer, GFP_KERNEL);
>> + if (!sfc->buffer)
>> + return -ENOMEM;
>> +
>> + mutex_init(&sfc->lock);
>> +
>> + ret = clk_prepare_enable(sfc->hclk);
>> + if (ret) {
>> + dev_err(&pdev->dev, "Failed to enable hclk\n");
>> + goto err_hclk;
>> + }
>> +
>> + ret = clk_prepare_enable(sfc->clk);
>> + if (ret) {
>> + dev_err(&pdev->dev, "Failed to enable clk\n");
>> + goto err_clk;
>> + }
>> +
>> + sfc->use_dma = !of_property_read_bool(sfc->dev->of_node,
>> + "rockchip,sfc-no-DMA");
>> +
>> + sfc->negative_edge = of_device_is_compatible(sfc->dev->of_node,
>> + "rockchip,rk1108-sfc");
>> + /* Find the irq */
>> + ret = platform_get_irq(pdev, 0);
>> + if (ret < 0) {
>> + dev_err(dev, "Failed to get the irq\n");
>> + goto err_irq;
>> + }
>> +
>> + ret = devm_request_irq(dev, ret, rockchip_sfc_irq_handler,
>> + 0, pdev->name, sfc);
>> + if (ret) {
>> + dev_err(dev, "Failed to request irq\n");
>> + goto err_irq;
>> + }
>> +
>> + sfc->num_chip = 0;
>> + ret = rockchip_sfc_init(sfc);
>> + if (ret)
>> + goto err_irq;
>> +
>> + pm_runtime_get_noresume(&pdev->dev);
>> + pm_runtime_set_active(&pdev->dev);
>> + pm_runtime_enable(&pdev->dev);
>> + pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
>> + pm_runtime_use_autosuspend(&pdev->dev);
>> +
>> + ret = rockchip_sfc_register_all(sfc);
>> + if (ret)
>> + goto err_register;
>> +
>> + clk_disable_unprepare(sfc->clk);
>> + pm_runtime_put_autosuspend(&pdev->dev);
>> + return 0;
>> +
>> +err_register:
>> + pm_runtime_disable(&pdev->dev);
>> + pm_runtime_set_suspended(&pdev->dev);
>> + pm_runtime_put_noidle(&pdev->dev);
>> +err_irq:
>> + clk_disable_unprepare(sfc->clk);
>> +err_clk:
>> + clk_disable_unprepare(sfc->hclk);
>> +err_hclk:
>> + mutex_destroy(&sfc->lock);
>> + return ret;
>> +}
>> +
>> +static int rockchip_sfc_remove(struct platform_device *pdev)
>> +{
>> + struct rockchip_sfc *sfc = platform_get_drvdata(pdev);
>> +
>> + pm_runtime_get_sync(&pdev->dev);
>> + pm_runtime_disable(&pdev->dev);
>> + pm_runtime_put_noidle(&pdev->dev);
>> +
>> + rockchip_sfc_unregister_all(sfc);
>> + mutex_destroy(&sfc->lock);
>> + clk_disable_unprepare(sfc->clk);
>> + clk_disable_unprepare(sfc->hclk);
>> + return 0;
>> +}
>> +
>> +#ifdef CONFIG_PM
>> +int rockchip_sfc_runtime_suspend(struct device *dev)
>> +{
>> + struct rockchip_sfc *sfc = dev_get_drvdata(dev);
>> +
>> + clk_disable_unprepare(sfc->hclk);
>> + return 0;
>> +}
>> +
>> +int rockchip_sfc_runtime_resume(struct device *dev)
>> +{
>> + struct rockchip_sfc *sfc = dev_get_drvdata(dev);
>> +
>> + clk_prepare_enable(sfc->hclk);
>> + return rockchip_sfc_reset(sfc);
>> +}
>> +#endif /* CONFIG_PM */
>> +
>> +static const struct of_device_id rockchip_sfc_dt_ids[] = {
>> + { .compatible = "rockchip,sfc"},
>> + { /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, rockchip_sfc_dt_ids);
>> +
>> +static const struct dev_pm_ops rockchip_sfc_dev_pm_ops = {
>> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
>> + pm_runtime_force_resume)
>> + SET_RUNTIME_PM_OPS(rockchip_sfc_runtime_suspend,
>> + rockchip_sfc_runtime_resume, NULL)
>> +};
>> +
>> +static struct platform_driver rockchip_sfc_driver = {
>> + .driver = {
>> + .name = "rockchip-sfc",
>> + .of_match_table = rockchip_sfc_dt_ids,
>> + .pm = &rockchip_sfc_dev_pm_ops,
>> + },
>> + .probe = rockchip_sfc_probe,
>> + .remove = rockchip_sfc_remove,
>> +};
>> +module_platform_driver(rockchip_sfc_driver);
>> +
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_DESCRIPTION("Rockchip Serial Flash Controller Driver");
>> +MODULE_AUTHOR("Shawn Lin <shawn.lin-TNX95d0MmH7DzftRWevZcw@public.gmane.org>");
>>
>
>
>
>
--
Best Regards
Shawn Lin
--
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] Add Nexus 6P(msm8994) SDHCI support
From: Jeremy McNicoll @ 2017-01-17 1:33 UTC (permalink / raw)
To: Bastian.=?iso-8859-1?B?S/ZjaGVyIDxnaXRAa2Noci5kZT4=?=
Cc: linux-arm-msm, linux-soc, devicetree, linux-mmc, jeremymc,
robh+dt, andy.gross, david.brown
In-Reply-To: <20161228162134.13687-1-git@kchr.de>
On Wed, Dec 28, 2016 at 05:21:34PM +0100, Bastian Köcher wrote:
> Signed-off-by: Bastian Köcher <git@kchr.de>
> ---
>
Sorry for the delay, my vactions this year ended up being a
little longer than expected given the chaos in Fort Lauderdale
airport.
See comments / suggestions below.
> Patch for enabling Nexus 6P(msm8994) SDHCI support.
>
> The patch is based on the work of Jeremy McNicoll for
> the Nexus 5x:
> https://www.spinics.net/lists/linux-arm-msm/msg24827.html
>
> .../arm64/boot/dts/qcom/msm8994-angler-rev-101.dts | 262 +++++++++++++++++++++
> arch/arm64/boot/dts/qcom/msm8994-pins.dtsi | 82 +++++++
> arch/arm64/boot/dts/qcom/msm8994.dtsi | 154 ++++++++++--
> 3 files changed, 483 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
> index dfa08f513dc4..d0bf9072b614 100644
> --- a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
> +++ b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
> @@ -38,3 +38,265 @@
> };
> };
> };
> +
> +&smd_rpm {
This node seems to be identical to what I have, so it makes
more sense for us to share this type of thing.
Can you take a look at the V2 I just sent and CC'd you on.
By removing smd_rpm and including
arch/arm64/boot/dts/qcom/msm8994-smd-rpm.dtsi
you get all my fixes for FREE!
> + rpm {
> + rpm_requests {
> + pm8994-regulators {
> +
> + vdd_l1-supply = <&pm8994_s1>;
> + vdd_l2_26_28-supply = <&pm8994_s3>;
> + vdd_l3_11-supply = <&pm8994_s3>;
> + vdd_l4_27_31-supply = <&pm8994_s3>;
> + vdd_l5_7-supply = <&pm8994_s3>;
> + vdd_l6_12_32-supply = <&pm8994_s5>;
> + vdd_l8_16_30-supply = <&vreg_vph_pwr>;
> + vdd_l9_10_18_22-supply = <&vreg_vph_pwr>;
> + vdd_l13_19_23_24-supply = <&vreg_vph_pwr>;
> + vdd_l14_15-supply = <&pm8994_s5>;
> + vdd_l17_29-supply = <&vreg_vph_pwr>;
> + vdd_l20_21-supply = <&vreg_vph_pwr>;
> + vdd_l25-supply = <&pm8994_s5>;
> + /*vin_lvs1_2 = <&pm8994_s4>; */
> +
> + s1 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <800000>;
> + };
> +
> + s2 {
> + };
> +
> + s3 {
> + regulator-min-microvolt = <1300000>;
> + regulator-max-microvolt = <1300000>;
> + };
> +
> + s4 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-allow-set-load;
> + regulator-system-load = <325000>;
> + };
> +
> + s5 {
> + regulator-min-microvolt = <2150000>;
> + regulator-max-microvolt = <2150000>;
> + };
> +
> + s7 {
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + };
> +
> + l1 {
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + };
> +
> + l2 {
> + regulator-min-microvolt = <1250000>;
> + regulator-max-microvolt = <1250000>;
> + };
> +
> + l3 {
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + };
> +
> + l4 {
> + regulator-min-microvolt = <1225000>;
> + regulator-max-microvolt = <1225000>;
> + };
> +
> + l5 {
> + };
> +
> + l6 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + l7 {
> + };
> +
> + l8 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + l9 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + l10 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + qcom,init-voltage = <1800000>;
> + };
> +
> + l11 {
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + qcom,init-voltage = <1200000>;
> + };
> +
> + l12 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + qcom,init-voltage = <1800000>;
> + proxy-supply = <&pm8994_l12>;
> + qcom,proxy-consumer-enable;
> + qcom,proxy-consumer-current = <10000>;
> + status = "okay";
> + };
> +
> + l13 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <2950000>;
> + qcom,init-voltage = <2950000>;
> + status = "okay";
> + };
> +
> + l14 {
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + qcom,init-voltage = <1200000>;
> + proxy-supply = <&pm8994_l14>;
> + qcom,proxy-consumer-enable;
> + qcom,proxy-consumer-current = <10000>;
> + status = "okay";
> + };
> +
> + l15 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + qcom,init-voltage = <1800000>;
> + status = "okay";
> + };
> +
> + l16 {
> + regulator-min-microvolt = <2700000>;
> + regulator-max-microvolt = <2700000>;
> + qcom,init-voltage = <2700000>;
> + status = "okay";
> + };
> +
> + l17 {
> + regulator-min-microvolt = <2700000>;
> + regulator-max-microvolt = <2700000>;
> + qcom,init-voltage = <2700000>;
> + status = "okay";
> + };
> +
> + l18 {
> + regulator-min-microvolt = <3000000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-always-on;
> + qcom,init-voltage = <3000000>;
> + qcom,init-ldo-mode = <1>;
> + };
> +
> + l19 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + qcom,init-voltage = <1800000>;
> + status = "okay";
> + };
> +
> + l20 {
> + regulator-min-microvolt = <2950000>;
> + regulator-max-microvolt = <2950000>;
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-allow-set-load;
> + regulator-system-load = <570000>;
> + };
> +
> + l21 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-always-on;
> + qcom,init-voltage = <1800000>;
> + };
> +
> + l22 {
> + regulator-min-microvolt = <3100000>;
> + regulator-max-microvolt = <3100000>;
> + qcom,init-voltage = <3100000>;
> + };
> +
> + l23 {
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + qcom,init-voltage = <2800000>;
> + };
> +
> + l24 {
> + regulator-min-microvolt = <3075000>;
> + regulator-max-microvolt = <3150000>;
> + qcom,init-voltage = <3075000>;
> + };
> +
> + l25 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + qcom,init-voltage = <1800000>;
> + };
> +
> + l26 {
> + /* TODO: value from downstream
> + regulator-min-microvolt = <987500>;
> + fails to apply */
> + };
> +
> + l27 {
> + regulator-min-microvolt = <1050000>;
> + regulator-max-microvolt = <1050000>;
> + qcom,init-voltage = <1050000>;
> + };
> +
> + l28 {
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + qcom,init-voltage = <1000000>;
> + proxy-supply = <&pm8994_l28>;
> + qcom,proxy-consumer-enable;
> + qcom,proxy-consumer-current = <10000>;
> + };
> +
> + l29 {
> + /* TODO: Unsupported voltage range..
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + qcom,init-voltage = <2800000>;
> + */
> + };
> +
> + l30 {
> + /* TODO: get this verified
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + qcom,init-voltage = <1800000>;
> + */
> + };
> +
> + l31 {
> + regulator-min-microvolt = <1262500>;
> + regulator-max-microvolt = <1262500>;
> + qcom,init-voltage = <1262500>;
> + };
> +
> + l32 {
> + /* TODO: get this verified
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + qcom,init-voltage = <1800000>;
> + */
> + };
> +
> + };
> + };
> + };
> +};
> diff --git a/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi
> index 0e4eea0df25d..66c46b8f9e83 100644
> --- a/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi
> @@ -35,4 +35,86 @@
> bias-pull-down;
> };
> };
> +
> + /* 0-3 for sdc1 4-6 for sdc2 */
> + /* Order of pins */
> + /* SDC1: CLK -> 0, CMD -> 1, DATA -> 2, RCLK -> 3 */
> + /* SDC2: CLK -> 4, CMD -> 5, DATA -> 6 */
> + pmx_sdc1_clk {
Change all your node names,
anything before the '{'
to make sure it doesn't have '_' underscores.
> + sdc1_clk_on: clk_on {
change this to
sdc1_clk_on: clk-on {
label: node-name {
> + pinmux {
> + pins = "sdc1_clk";
> + };
> + pinconf {
> + pins = "sdc1_clk";
> + bias-disable = <0>; /* No pull */
> + drive-strength = <16>; /* 16mA */
> + };
> + };
> + sdc1_clk_off: clk_off {
> + pinmux {
> + pins = "sdc1_clk";
> + };
> + pinconf {
> + pins = "sdc1_clk";
> + bias-disable = <0>; /* No pull */
> + drive-strength = <2>; /* 2mA */
> + };
> + };
> + };
> +
> + pmx_sdc1_cmd {
> + sdc1_cmd_on: cmd_on {
> + pinmux {
> + pins = "sdc1_cmd";
> + };
> + pinconf {
> + pins = "sdc1_cmd";
> + bias-pull-up;
> + drive-strength = <8>;
> + };
> + };
> + sdc1_cmd_off: cmd_off {
> + pinmux {
> + pins = "sdc1_cmd";
> + };
> + pinconf {
> + pins = "sdc1_cmd";
> + bias-pull-up = <0x3>; /* same as 3.10 ?? */
> + drive-strength = <2>; /* 2mA */
> + };
> + };
> + };
> +
> + pmx_sdc1_data {
> + sdc1_data_on: data_on {
> + pinmux {
> + pins = "sdc1_data";
> + };
> + pinconf {
> + pins = "sdc1_data";
> + bias-pull-up;
> + drive-strength = <8>; /* 8mA */
> + };
> + };
> + sdc1_data_off: data_off {
> + pinmux {
> + pins = "sdc1_data";
> + };
> + pinconf {
> + pins = "sdc1_data";
> + bias-pull-up;
> + drive-strength = <2>;
> + };
> + };
> + };
> +
> + pmx_sdc1_rclk {
> + sdc1_rclk_on: rclk_on {
> + bias-pull-down; /* pull down */
> + };
> + sdc1_rclk_off: rclk_off {
> + bias-pull-down; /* pull down */
> + };
> + };
> };
> diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
> index f33c41d01c86..703888d608c6 100644
> --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
> @@ -73,6 +73,11 @@
> <0xf9002000 0x1000>;
> };
>
> + apcs: syscon@f900d000 {
> + compatible = "syscon";
> + reg = <0xf900d000 0x2000>;
> + };
> +
> timer@f9020000 {
> #address-cells = <1>;
> #size-cells = <1>;
> @@ -156,11 +161,6 @@
> <&clock_gcc GCC_BLSP1_AHB_CLK>;
> };
>
> - tcsr_mutex_regs: syscon@fd484000 {
> - compatible = "syscon";
> - reg = <0xfd484000 0x2000>;
> - };
> -
> clock_gcc: clock-controller@fc400000 {
> compatible = "qcom,gcc-msm8994";
> #clock-cells = <1>;
> @@ -168,6 +168,75 @@
> #power-domain-cells = <1>;
> reg = <0xfc400000 0x2000>;
> };
> +
> + sdhci1: mmc@f9824900 {
> + compatible = "qcom,sdhci-msm-v4";
> + reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
> + reg-names = "hc_mem", "core_mem";
> +
> + interrupts = <GIC_SPI 123 IRQ_TYPE_NONE>,
> + <GIC_SPI 138 IRQ_TYPE_NONE>;
> + interrupt-names = "hc_irq", "pwr_irq";
> +
> + clocks = <&clock_gcc GCC_SDCC1_APPS_CLK>,
> + <&clock_gcc GCC_SDCC1_AHB_CLK>;
> + clock-names = "core", "iface";
> +
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on
> + &sdc1_rclk_on>;
> + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off
> + &sdc1_rclk_off>;
> +
> + vdd-supply = <&pm8994_l20>;
> + qcom,vdd-voltage-level = <2950000 2950000>;
> + qcom,vdd-current-level = <200 570000>;
> +
> + vdd-io-supply = <&pm8994_s4>;
> + qcom,vdd-io-voltage-level = <1800000 1800000>;
> + qcom,vdd-io-current-level = <200 325000>;
> +
> + regulator-always-on;
> + bus-width = <8>;
> + mmc-hs400-1_8v;
> + status = "okay";
> + };
> +
> + vreg_vph_pwr: vreg-vph-pwr {
> + compatible = "regulator-fixed";
> + status = "okay";
> + regulator-name = "vph-pwr";
> +
> + regulator-min-microvolt = <3600000>;
> + regulator-max-microvolt = <3600000>;
> +
> + regulator-always-on;
> + };
> +
> + rpm_msg_ram: memory@fc428000 {
> + compatible = "qcom,rpm-msg-ram";
> + reg = <0xfc428000 0x4000>;
> + };
> +
> + sfpb_mutex_regs: syscon@fd484000 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "syscon";
> + reg = <0xfd484000 0x400>;
> + };
> +
> + sfpb_mutex: hwmutex {
> + compatible = "qcom,sfpb-mutex";
> + syscon = <&sfpb_mutex_regs 0x0 0x100>;
> + #hwlock-cells = <1>;
> + };
> +
> + smem {
> + compatible = "qcom,smem";
> + memory-region = <&smem_region>;
> + qcom,rpm-msg-ram = <&rpm_msg_ram>;
> + hwlocks = <&sfpb_mutex 3>;
> + };
> };
>
> memory {
> @@ -193,22 +262,77 @@
> #size-cells = <2>;
> ranges;
>
> - smem_mem: smem_region@6a00000 {
> + smem_region: smem@6a00000 {
good.
> reg = <0x0 0x6a00000 0x0 0x200000>;
> no-map;
> };
> };
>
> - tcsr_mutex: hwlock {
> - compatible = "qcom,tcsr-mutex";
> - syscon = <&tcsr_mutex_regs 0 0x80>;
> - #hwlock-cells = <1>;
> - };
> + smd_rpm: smd {
> + compatible = "qcom,smd";
> +
> + rpm {
> + interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
> + qcom,ipc = <&apcs 8 0>;
> + qcom,smd-edge = <15>;
> + qcom,local-pid = <0>;
> + qcom,remote-pid = <6>;
> +
> + rpm_requests {
s/rpm_requests {/rpm-requests {/
Node names cannot have an underscore.
-jeremy
> + compatible = "qcom,rpm-msm8994";
> + qcom,smd-channels = "rpm_requests";
> +
> + rpmcc: qcom,rpmcc {
> + /* TODO: update when rpmcc-msm8994 support added */
> + compatible = "qcom,rpmcc-msm8916",
> + "qcom,rpmcc";
> + #clock-cells = <1>;
> + };
>
> - qcom,smem@6a00000 {
> - compatible = "qcom,smem";
> - memory-region = <&smem_mem>;
> - hwlocks = <&tcsr_mutex 3>;
> + smd_rpm_regulators: pm8994-regulators {
> + compatible = "qcom,rpm-pm8994-regulators";
> +
> + pm8994_s1: s1 {};
> + pm8994_s2: s2 {};
> + pm8994_s3: s3 {};
> + pm8994_s4: s4 {};
> + pm8994_s5: s5 {};
> + pm8994_s6: s6 {};
> + pm8994_s7: s7 {};
> +
> + pm8994_l1: l1 {};
> + pm8994_l2: l2 {};
> + pm8994_l3: l3 {};
> + pm8994_l4: l4 {};
> + pm8994_l6: l6 {};
> + pm8994_l8: l8 {};
> + pm8994_l9: l9 {};
> + pm8994_l10: l10 {};
> + pm8994_l11: l11 {};
> + pm8994_l12: l12 {};
> + pm8994_l13: l13 {};
> + pm8994_l14: l14 {};
> + pm8994_l15: l15 {};
> + pm8994_l16: l16 {};
> + pm8994_l17: l17 {};
> + pm8994_l18: l18 {};
> + pm8994_l19: l19 {};
> + pm8994_l20: l20 {};
> + pm8994_l21: l21 {};
> + pm8994_l22: l22 {};
> + pm8994_l23: l23 {};
> + pm8994_l24: l24 {};
> + pm8994_l25: l25 {};
> + pm8994_l26: l26 {};
> + pm8994_l27: l27 {};
> + pm8994_l28: l28 {};
> + pm8994_l29: l29 {};
> + pm8994_l30: l30 {};
> + pm8994_l31: l31 {};
> + pm8994_l32: l32 {};
> + };
> + };
> + };
> };
> };
>
> --
> 2.11.0
>
^ permalink raw reply
* Re: [PATCH v4 2/2] mtd: spi-nor: add rockchip serial flash controller driver
From: Shawn Lin @ 2017-01-17 1:34 UTC (permalink / raw)
To: Cyrille Pitchen, Cyrille Pitchen
Cc: devicetree, Heiko Stuebner, Marek Vasut, shawn.lin,
linux-rockchip, Rob Herring, linux-mtd, Brian Norris,
David Woodhouse
In-Reply-To: <c4a50d88-4a31-ec67-c180-808bfc81f254@atmel.com>
Hi Cyrille,
On 2017/1/16 22:03, Cyrille Pitchen wrote:
> Le 16/01/2017 à 12:10, Cyrille Pitchen a écrit :
>> Hi Shawn,
>>
>> Le 15/12/2016 à 10:27, Shawn Lin a écrit :
>>> Add rockchip serial flash controller driver
>>>
>>> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
>>>
>>> ---
>>>
>>> Changes in v4:
>>> - simplify the code of get_if_type
>>> - use dma_dir to simplify the code
>>> - simplify the rockchip_sfc_do_rd_wr
>>> - some minor improvements
>>> - add reset controller when doing resume
>>>
>>> Changes in v3:
>>> - use io{read32,write32}_rep to simplify the corner cases
>>> - remove more unnecessary bit definitions
>>> - some minor comment fixes and improvement
>>> - fix wrong unregister function
>>> - unify more code
>>> - use nor to avoid constantly replicating the whole
>>> sfc->flash[sfc->num_chip].nor
>>> - add email for MODULE_AUTHOR
>>> - remove #if 1 --- #endif
>>> - extract DMA code to imporve the code structure
>>> - reset all when failing to do dma
>>> - pass sfc to get_if_type
>>> - rename sfc-no-dma to sfc-no-DMA
>>>
>>> Changes in v2:
>>> - fix typos
>>> - add some comment for buffer and others operations
>>> - rename SFC_MAX_CHIP_NUM to MAX_CHIPSELECT_NUM
>>> - use u8 for cs
>>> - return -EINVAL for default case of get_if_type
>>> - use readl_poll_*() to check timeout cases
>>> - simplify and clarify some condition checks
>>> - rework the bitshifts to simplify the code
>>> - define SFC_CMD_DUMMY(x)
>>> - fix ummap for dma read path and finish all the
>>> cache maintenance.
>>> - rename to rockchip_sfc_chip_priv and embed struct spi_nor
>>> in it.
>>> - add MODULE_AUTHOR
>>> - add runtime PM and general PM support.
>>> - Thanks for Marek's comments. Link:
>>> http://lists.infradead.org/pipermail/linux-mtd/2016-November/070321.html
>>>
>>> MAINTAINERS | 8 +
>>> drivers/mtd/spi-nor/Kconfig | 7 +
>>> drivers/mtd/spi-nor/Makefile | 1 +
>>> drivers/mtd/spi-nor/rockchip-sfc.c | 872 +++++++++++++++++++++++++++++++++++++
>>> 4 files changed, 888 insertions(+)
>>> create mode 100644 drivers/mtd/spi-nor/rockchip-sfc.c
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 1cd38a7..eb7e06d 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -10266,6 +10266,14 @@ L: linux-serial@vger.kernel.org
>>> S: Odd Fixes
>>> F: drivers/tty/serial/rp2.*
>>>
>>> +ROCKCHIP SERIAL FLASH CONTROLLER DRIVER
>>> +M: Shawn Lin <shawn.lin@rock-chips.com>
>>> +L: linux-mtd@lists.infradead.org
>>> +L: linux-rockchip@lists.infradead.org
>>> +S: Maintained
>>> +F: Documentation/devicetree/bindings/mtd/rockchip-sfc.txt
>>> +F: drivers/mtd/spi-nor/rockchip-sfc.c
>>> +
>>> ROSE NETWORK LAYER
>>> M: Ralf Baechle <ralf@linux-mips.org>
>>> L: linux-hams@vger.kernel.org
>>> diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
>>> index 4a682ee..bf783a8 100644
>>> --- a/drivers/mtd/spi-nor/Kconfig
>>> +++ b/drivers/mtd/spi-nor/Kconfig
>>> @@ -76,4 +76,11 @@ config SPI_NXP_SPIFI
>>> Flash. Enable this option if you have a device with a SPIFI
>>> controller and want to access the Flash as a mtd device.
>>>
>>> +config SPI_ROCKCHIP_SFC
>>> + tristate "Rockchip Serial Flash Controller(SFC)"
>>> + depends on ARCH_ROCKCHIP || COMPILE_TEST
>>> + depends on HAS_IOMEM && HAS_DMA
>>> + help
>>> + This enables support for rockchip serial flash controller.
>>> +
>>> endif # MTD_SPI_NOR
>>> diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
>>> index 121695e..364d4c6 100644
>>> --- a/drivers/mtd/spi-nor/Makefile
>>> +++ b/drivers/mtd/spi-nor/Makefile
>>> @@ -5,3 +5,4 @@ obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o
>>> obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o
>>> obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o
>>> obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o
>>> +obj-$(CONFIG_SPI_ROCKCHIP_SFC) += rockchip-sfc.o
>>> diff --git a/drivers/mtd/spi-nor/rockchip-sfc.c b/drivers/mtd/spi-nor/rockchip-sfc.c
>>> new file mode 100644
>>> index 0000000..102c08f
>>> --- /dev/null
>>> +++ b/drivers/mtd/spi-nor/rockchip-sfc.c
>>> @@ -0,0 +1,872 @@
>>> +/*
>>> + * Rockchip Serial Flash Controller Driver
>>> + *
>>> + * Copyright (c) 2016, Rockchip Inc.
>>> + * Author: Shawn Lin <shawn.lin@rock-chips.com>
>>> + *
>>> + * 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.
>>> + *
>>> + * 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/bitops.h>
>>> +#include <linux/clk.h>
>>> +#include <linux/completion.h>
>>> +#include <linux/dma-mapping.h>
>>> +#include <linux/iopoll.h>
>>> +#include <linux/module.h>
>>> +#include <linux/mtd/mtd.h>
>>> +#include <linux/mtd/spi-nor.h>
>>> +#include <linux/of.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/pm_runtime.h>
>>> +#include <linux/slab.h>
>>> +
>>> +/* System control */
>>> +#define SFC_CTRL 0x0
>>> +#define SFC_CTRL_COMMON_BITS_1 0x0
>>> +#define SFC_CTRL_COMMON_BITS_2 0x1
>>> +#define SFC_CTRL_COMMON_BITS_4 0x2
>>> +#define SFC_CTRL_DATA_BITS_SHIFT 12
>>> +#define SFC_CTRL_ADDR_BITS_SHIFT 10
>>> +#define SFC_CTRL_CMD_BITS_SHIFT 8
>>> +#define SFC_CTRL_PHASE_SEL_NEGETIVE BIT(1)
>>> +
>>> +/* Interrupt mask */
>>> +#define SFC_IMR 0x4
>>> +#define SFC_IMR_RX_FULL BIT(0)
>>> +#define SFC_IMR_RX_UFLOW BIT(1)
>>> +#define SFC_IMR_TX_OFLOW BIT(2)
>>> +#define SFC_IMR_TX_EMPTY BIT(3)
>>> +#define SFC_IMR_TRAN_FINISH BIT(4)
>>> +#define SFC_IMR_BUS_ERR BIT(5)
>>> +#define SFC_IMR_NSPI_ERR BIT(6)
>>> +#define SFC_IMR_DMA BIT(7)
>>> +/* Interrupt clear */
>>> +#define SFC_ICLR 0x8
>>> +#define SFC_ICLR_RX_FULL BIT(0)
>>> +#define SFC_ICLR_RX_UFLOW BIT(1)
>>> +#define SFC_ICLR_TX_OFLOW BIT(2)
>>> +#define SFC_ICLR_TX_EMPTY BIT(3)
>>> +#define SFC_ICLR_TRAN_FINISH BIT(4)
>>> +#define SFC_ICLR_BUS_ERR BIT(5)
>>> +#define SFC_ICLR_NSPI_ERR BIT(6)
>>> +#define SFC_ICLR_DMA BIT(7)
>>> +/* FIFO threshold level */
>>> +#define SFC_FTLR 0xc
>>> +#define SFC_FTLR_TX_SHIFT 0
>>> +#define SFC_FTLR_TX_MASK 0x1f
>>> +#define SFC_FTLR_RX_SHIFT 8
>>> +#define SFC_FTLR_RX_MASK 0x1f
>>> +/* Reset FSM and FIFO */
>>> +#define SFC_RCVR 0x10
>>> +#define SFC_RCVR_RESET BIT(0)
>>> +/* Enhanced mode */
>>> +#define SFC_AX 0x14
>>> +/* Address Bit number */
>>> +#define SFC_ABIT 0x18
>>> +/* Interrupt status */
>>> +#define SFC_ISR 0x1c
>>> +#define SFC_ISR_RX_FULL_SHIFT BIT(0)
>>> +#define SFC_ISR_RX_UFLOW_SHIFT BIT(1)
>>> +#define SFC_ISR_TX_OFLOW_SHIFT BIT(2)
>>> +#define SFC_ISR_TX_EMPTY_SHIFT BIT(3)
>>> +#define SFC_ISR_TX_FINISH_SHIFT BIT(4)
>>> +#define SFC_ISR_BUS_ERR_SHIFT BIT(5)
>>> +#define SFC_ISR_NSPI_ERR_SHIFT BIT(6)
>>> +#define SFC_ISR_DMA_SHIFT BIT(7)
>>> +/* FIFO status */
>>> +#define SFC_FSR 0x20
>>> +#define SFC_FSR_TX_IS_FULL BIT(0)
>>> +#define SFC_FSR_TX_IS_EMPTY BIT(1)
>>> +#define SFC_FSR_RX_IS_EMPTY BIT(2)
>>> +#define SFC_FSR_RX_IS_FULL BIT(3)
>>> +/* FSM status */
>>> +#define SFC_SR 0x24
>>> +#define SFC_SR_IS_IDLE 0x0
>>> +#define SFC_SR_IS_BUSY 0x1
>>> +/* Raw interrupt status */
>>> +#define SFC_RISR 0x28
>>> +#define SFC_RISR_RX_FULL BIT(0)
>>> +#define SFC_RISR_RX_UNDERFLOW BIT(1)
>>> +#define SFC_RISR_TX_OVERFLOW BIT(2)
>>> +#define SFC_RISR_TX_EMPTY BIT(3)
>>> +#define SFC_RISR_TRAN_FINISH BIT(4)
>>> +#define SFC_RISR_BUS_ERR BIT(5)
>>> +#define SFC_RISR_NSPI_ERR BIT(6)
>>> +#define SFC_RISR_DMA BIT(7)
>>> +/* Master trigger */
>>> +#define SFC_DMA_TRIGGER 0x80
>>> +/* Src or Dst addr for master */
>>> +#define SFC_DMA_ADDR 0x84
>>> +/* Command */
>>> +#define SFC_CMD 0x100
>>> +#define SFC_CMD_IDX_SHIFT 0
>>> +#define SFC_CMD_DUMMY_SHIFT 8
>>> +#define SFC_CMD_DIR_RD 0
>>> +#define SFC_CMD_DIR_WR 1
>>> +#define SFC_CMD_DIR_SHIFT 12
>>> +#define SFC_CMD_ADDR_ZERO (0x0 << 14)
>>> +#define SFC_CMD_ADDR_24BITS (0x1 << 14)
>>> +#define SFC_CMD_ADDR_32BITS (0x2 << 14)
>>> +#define SFC_CMD_ADDR_FRS (0x3 << 14)
>>> +#define SFC_CMD_TRAN_BYTES_SHIFT 16
>>> +#define SFC_CMD_CS_SHIFT 30
>>> +/* Address */
>>> +#define SFC_ADDR 0x104
>>> +/* Data */
>>> +#define SFC_DATA 0x108
>>> +
>>> +#define SFC_MAX_CHIPSELECT_NUM 4
>>> +#define SFC_DMA_MAX_LEN 0x4000
>>> +#define SFC_CMD_DUMMY(x) \
>>> + ((x) << SFC_CMD_DUMMY_SHIFT)
>>> +
>>> +enum rockchip_sfc_iftype {
>>> + IF_TYPE_STD,
>>> + IF_TYPE_DUAL,
>>> + IF_TYPE_QUAD,
>>> +};
>>> +
>>> +struct rockchip_sfc;
>>> +struct rockchip_sfc_chip_priv {
>>> + u8 cs;
>>> + u32 clk_rate;
>>> + struct spi_nor nor;
>>> + struct rockchip_sfc *sfc;
>>> +};
>>> +
>>> +struct rockchip_sfc {
>>> + struct device *dev;
>>> + struct mutex lock;
>>> + void __iomem *regbase;
>>> + struct clk *hclk;
>>> + struct clk *clk;
>>> + /* virtual mapped addr for dma_buffer */
>>> + void *buffer;
>>> + dma_addr_t dma_buffer;
>>> + struct completion cp;
>>> + struct rockchip_sfc_chip_priv flash[SFC_MAX_CHIPSELECT_NUM];
>>> + u32 num_chip;
>>> + bool use_dma;
>>> + /* use negative edge of hclk to latch data */
>>> + bool negative_edge;
>>> +};
>>> +
>>> +static int get_if_type(struct rockchip_sfc *sfc, enum read_mode flash_read)
>>> +{
>>> + if (flash_read == SPI_NOR_DUAL)
>>> + return IF_TYPE_DUAL;
>>> + else if (flash_read == SPI_NOR_QUAD)
>>> + return IF_TYPE_QUAD;
>>> + else if (flash_read == SPI_NOR_NORMAL ||
>>> + flash_read == SPI_NOR_FAST)
>>> + return IF_TYPE_STD;
>>> +
>>> + dev_err(sfc->dev, "unsupported SPI read mode\n");
>>> + return -EINVAL;
>>> +}
>>> +
>>> +static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
>>> +{
>>> + int err;
>>> + u32 status;
>>> +
>>> + writel_relaxed(SFC_RCVR_RESET, sfc->regbase + SFC_RCVR);
>>> +
>>> + err = readl_poll_timeout(sfc->regbase + SFC_RCVR, status,
>>> + !(status & SFC_RCVR_RESET), 20,
>>> + jiffies_to_usecs(HZ));
>>> + if (err)
>>> + dev_err(sfc->dev, "SFC reset never finished\n");
>>> +
>>> + /* Still need to clear the masked interrupt from RISR */
>>> + writel_relaxed(SFC_ICLR_RX_FULL | SFC_ICLR_RX_UFLOW |
>>> + SFC_ICLR_TX_OFLOW | SFC_ICLR_TX_EMPTY |
>>> + SFC_ICLR_TRAN_FINISH | SFC_ICLR_BUS_ERR |
>>> + SFC_ICLR_NSPI_ERR | SFC_ICLR_DMA,
>>> + sfc->regbase + SFC_ICLR);
>>> + return err;
>>> +}
>>> +
>>> +static int rockchip_sfc_init(struct rockchip_sfc *sfc)
>>> +{
>>> + int err;
>>> +
>>> + err = rockchip_sfc_reset(sfc);
>>> + if (err)
>>> + return err;
>>> +
>>> + /* Mask all eight interrupts */
>>> + writel_relaxed(0xff, sfc->regbase + SFC_IMR);
>>> +
>>> + /*
>>> + * Phase configure for sfc to latch data by using
>>> + * ahb clock, and this configuration should be Soc
>>> + * specific.
>>> + */
>>> + if (sfc->negative_edge)
>>> + writel_relaxed(SFC_CTRL_PHASE_SEL_NEGETIVE,
>>> + sfc->regbase + SFC_CTRL);
>>> + else
>>> + writel_relaxed(0, sfc->regbase + SFC_CTRL);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int rockchip_sfc_prep(struct spi_nor *nor, enum spi_nor_ops ops)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> + int ret;
>>> +
>>> + mutex_lock(&sfc->lock);
>>> + pm_runtime_get_sync(sfc->dev);
>>> +
>>> + ret = clk_set_rate(sfc->clk, priv->clk_rate);
>>> + if (ret)
>>> + goto out;
>>> +
>>> + ret = clk_prepare_enable(sfc->clk);
>>> + if (ret)
>>> + goto out;
>>> +
>>> + return 0;
>>> +
>>> +out:
>>> + mutex_unlock(&sfc->lock);
>>> + return ret;
>>> +}
>>> +
>>> +static void rockchip_sfc_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> +
>>> + clk_disable_unprepare(sfc->clk);
>>> + mutex_unlock(&sfc->lock);
>>> + pm_runtime_mark_last_busy(sfc->dev);
>>> + pm_runtime_put_autosuspend(sfc->dev);
>>> +}
>>> +
>>> +static int rockchip_sfc_wait_op_finish(struct rockchip_sfc *sfc)
>>> +{
>>> + int err;
>>> + u32 status;
>>> +
>>> + /*
>>> + * Note: tx and rx share the same fifo, so the rx's water level
>>> + * is the same as rx's, which means this function could be reused
>>> + * for checking the read operations as well.
>>> + */
>>> + err = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
>>> + status & SFC_FSR_TX_IS_EMPTY,
>>> + 20, jiffies_to_usecs(2 * HZ));
>>> + if (err)
>>> + dev_err(sfc->dev, "SFC fifo never empty\n");
>>> +
>>> + return err;
>>> +}
>>> +
>>> +static int rockchip_sfc_op_reg(struct spi_nor *nor,
>>> + u8 opcode, int len, u8 optype)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> + u32 reg;
>>> + bool tx_no_empty, rx_no_empty, is_busy;
>>> + int err;
>>> +
>>> + reg = readl_relaxed(sfc->regbase + SFC_FSR);
>>> + tx_no_empty = !(reg & SFC_FSR_TX_IS_EMPTY);
>>> + rx_no_empty = !(reg & SFC_FSR_RX_IS_EMPTY);
>>> +
>>> + is_busy = readl_relaxed(sfc->regbase + SFC_SR);
>>> +
>>> + if (tx_no_empty || rx_no_empty || is_busy) {
>>> + err = rockchip_sfc_reset(sfc);
>>> + if (err)
>>> + return err;
>>> + }
>>> +
>>> + reg = opcode << SFC_CMD_IDX_SHIFT;
>>> + reg |= len << SFC_CMD_TRAN_BYTES_SHIFT;
>>> + reg |= priv->cs << SFC_CMD_CS_SHIFT;
>>> + reg |= optype << SFC_CMD_DIR_SHIFT;
>>> +
>>> + writel_relaxed(reg, sfc->regbase + SFC_CMD);
>>> +
>>> + return rockchip_sfc_wait_op_finish(sfc);
>>> +}
>>> +
>>> +static void rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
>>> +{
>>> + u32 tmp, i;
>>> + int total_len = len;
>>> +
>>> + /* 32-bit access only */
>>> + if (len >= 4 && !((u32)buf & 0x03)) {
>
> if (len >= sizeof(u32) && IS_ALIGNED(buf, sizeof(u32))) {
>>> + ioread32_rep(sfc->regbase + SFC_DATA, buf, len >> 2);
>>> + len %= 4;
>>> + buf += total_len - len;
>>> + }
>>> +
>>> + /* read the rest bytes */
>>> + for (i = 0; i < len; i++) {
>>> + if (!(i & 0x03))
>>> + tmp = readl_relaxed(sfc->regbase + SFC_DATA);
>>> + buf[i] = (tmp >> ((i & 0x03) * 8)) & 0xff;
>>> + }
>>> +}
>>> +
>>> +static int rockchip_sfc_read_reg(struct spi_nor *nor, u8 opcode,
>>> + u8 *buf, int len)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> + int ret;
>>> +
>>> + ret = rockchip_sfc_op_reg(nor, opcode, len, SFC_CMD_DIR_RD);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + rockchip_sfc_read_fifo(sfc, buf, len);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int rockchip_sfc_write_reg(struct spi_nor *nor, u8 opcode,
>>> + u8 *buf, int len)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> + u32 dwords;
>>> +
>>> + /* Align bytes to dwords */
>>> + dwords = DIV_ROUND_UP(len, sizeof(u32));
>>> + iowrite32_rep(sfc->regbase + SFC_DATA, buf, dwords);
>
> iowrite32_rep() is likely to be implemented with writesl() and writesl()
> casts its "const void *buffer" argument into a "const u32 *buf" local
> variable. Then this buf variable is used with __raw_writel(*buf++).
>
> Hence if the u8 *buf argument of rockchip_sfc_write_reg() is not aligned to
> 32 bits, this function performs unaligned accesses to the memory pointed by
> buf.
>
Good catch, will fix it.
>>> +
>>> + return rockchip_sfc_op_reg(nor, opcode, len, SFC_CMD_DIR_WR);
>>> +}
>>> +
>>> +static inline void rockchip_sfc_setup_transfer(struct spi_nor *nor,
>>> + loff_t from_to,
>>> + size_t len, u8 op_type)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> + u32 reg;
>>> + u8 if_type = 0;
>>> +
>>> + if_type = get_if_type(sfc, nor->flash_read);
>>> + writel_relaxed((if_type << SFC_CTRL_DATA_BITS_SHIFT) |
>>> + (if_type << SFC_CTRL_ADDR_BITS_SHIFT) |
>>> + (if_type << SFC_CTRL_CMD_BITS_SHIFT) |
>>> + (sfc->negative_edge ? SFC_CTRL_PHASE_SEL_NEGETIVE : 0),
>>> + sfc->regbase + SFC_CTRL);
>>
>> Marek rose an issue when commenting v3:
>>
>> Looking at that code it seems that even if the hardware can support SPI
>> 1-1-n protocols, this driver actually allows SPI n-n-n protocols.
>>
>> However with the current spi-nor framework, the values of the enum
>> read_mode must be understood this way:
>> SPI_NOR_FAST or SPI_NOR_NORMAL: SPI 1-1-1 protocol
>> SPI_NOR_DUAL: SPI 1-1-2 protocol
>> SPI_NOR_QUAD: SPI 1-1-4 protocol
>>
>> Support to other SPI protocols such as SPI 1-4-4 or SPI 4-4-4 as not been
>> accepted in mainline yet.
>>
>> Below in this driver, spi_nor_scan() is called with the value SPI_NOR_QUAD
>> hence it asks the spi-nor framework for using the SPI 1-1-4 (and not SPI
>> 4-4-4) *when supported by the QSPI memory*.
>>
>> Also since the driver was tested with a Winbond w25q256 memory, let me warn
>> you that currently the SPI_NOR_QUAD_READ flag is *NOT* set in the "w25q256"
>> entry of the spi_nor_ids[] array. So this claims this memory is not capable
>> of using the SPI 1-1-4 protocol even if the Winbond memory actually
>> supports this protocol. Then the spi-nor framework selects the SPI 1-1-1
>> protocol as a fallback.
>> That's why you have succeeded in using your driver but it would have failed
>> with another QSPI memory with its SPI_NOR_QUAD_READ flag due to a protocol
>> mismatch.
>>
>> So with the current spi-nor framework you must set
>> SFC_CTRL_{DATA|ADDR}_BITS_SHIFT to IF_TYPE_STD.
>>
>> Later, once the patch adding support to other SPI protocols would have been
>> accepted in mainline, you could update your driver to tell the spi-nor
>> framework that the rockchip controller also supports SPI 1-2-2 and SPI
>> 1-4-4 protocols.
>>
>>
>>> +
>>> + if (op_type == SFC_CMD_DIR_WR)
>>> + reg = nor->program_opcode << SFC_CMD_IDX_SHIFT;
>>> + else
>>> + reg = nor->read_opcode << SFC_CMD_IDX_SHIFT;
>>> +
>>> + reg |= op_type << SFC_CMD_DIR_SHIFT;
>>> + reg |= (nor->addr_width == 4) ?
>>> + SFC_CMD_ADDR_32BITS : SFC_CMD_ADDR_24BITS;
>>> +
>>> + reg |= priv->cs << SFC_CMD_CS_SHIFT;
>>> + reg |= len << SFC_CMD_TRAN_BYTES_SHIFT;
>>
>> Looking at the definitions of SFC_CMD_TRAN_BYTES_SHIFT (16) and
>> SFC_CMD_CS_SHIFT (30), I understand that the bitfield for the transfer
>> length lays between bits 16 and 30 hence a 14 bit value at most.
>> So what if len is greater than 16384? It overflows in the cs bitfield?
>>
>> You should apply masks to avoid such overflows and also test the len value
>> then report the actual number of transferred bytes.
>>
>>> +
>>> + if (op_type == SFC_CMD_DIR_RD)
>>> + reg |= SFC_CMD_DUMMY(nor->read_dummy);
>>> +
>>> + /* Should minus one as 0x0 means 1 bit flash address */
>>> + writel_relaxed(nor->addr_width * 8 - 1, sfc->regbase + SFC_ABIT);
>>> + writel_relaxed(reg, sfc->regbase + SFC_CMD);
>>> + writel_relaxed(from_to, sfc->regbase + SFC_ADDR);
>>> +}
>>> +
>>> +static int rockchip_sfc_do_dma_transfer(struct spi_nor *nor, loff_t from_to,
>>> + dma_addr_t dma_buf, size_t len,
>>> + u8 op_type)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> + u32 reg;
>>> + int err = 0;
>>> +
>>> + init_completion(&sfc->cp);
>>> +
>>> + writel_relaxed(SFC_ICLR_RX_FULL | SFC_ICLR_RX_UFLOW |
>>> + SFC_ICLR_TX_OFLOW | SFC_ICLR_TX_EMPTY |
>>> + SFC_ICLR_TRAN_FINISH | SFC_ICLR_BUS_ERR |
>>> + SFC_ICLR_NSPI_ERR | SFC_ICLR_DMA,
>>> + sfc->regbase + SFC_ICLR);
>>> +
>>> + /* Enable transfer complete interrupt */
>>> + reg = readl_relaxed(sfc->regbase + SFC_IMR);
>>> + reg &= ~SFC_IMR_TRAN_FINISH;
>>> + writel_relaxed(reg, sfc->regbase + SFC_IMR);
>>> +
>>> + rockchip_sfc_setup_transfer(nor, from_to, len, op_type);
>>> + writel_relaxed(dma_buf, sfc->regbase + SFC_DMA_ADDR);
>>> +
>>> + /*
>>> + * Start dma but note that the sfc->dma_buffer is derived from
>>> + * dmam_alloc_coherent so we don't actually need any sync operations
>>> + * for coherent dma memory.
>>> + */
>>> + writel_relaxed(0x1, sfc->regbase + SFC_DMA_TRIGGER);
>>> +
>>> + /* Wait for the interrupt. */
>>> + if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) {
>>> + dev_err(sfc->dev, "DMA wait for transfer finish timeout\n");
>>> + err = -ETIMEDOUT;
>>> + }
>>> +
>>> + /* Disable transfer finish interrupt */
>>> + reg = readl_relaxed(sfc->regbase + SFC_IMR);
>>> + reg |= SFC_IMR_TRAN_FINISH;
>>> + writel_relaxed(reg, sfc->regbase + SFC_IMR);
>>> +
>>> + if (err) {
>>> + rockchip_sfc_reset(sfc);
>>> + return err;
>>> + }
>>> +
>>> + return rockchip_sfc_wait_op_finish(sfc);
>>> +}
>>> +
>>> +static inline int rockchip_sfc_pio_write(struct rockchip_sfc *sfc, u_char *buf,
>>> + size_t len)
>>> +{
>>> + u32 dwords;
>>> +
>>> + /*
>>> + * Align bytes to dwords, although we will write some extra
>>> + * bytes to fifo but the transfer bytes number in SFC_CMD
>>> + * register will make sure we just send out the expected
>>> + * byte numbers and the extra bytes will be clean before
>>> + * setting up the next transfer. We should always round up
>>> + * to align to DWORD as the ahb for Rockchip Socs won't
>>> + * support non-aligned-to-DWORD transfer.
>>> + */
>>> + dwords = DIV_ROUND_UP(len, sizeof(u32));
>>> + iowrite32_rep(sfc->regbase + SFC_DATA, buf, dwords);
>>> +
>
> Here again the buf pointer might not be aligned to 4 bytes.
>
>>> + return rockchip_sfc_wait_op_finish(sfc);
>>> +}
>>> +
>>> +static inline int rockchip_sfc_pio_read(struct rockchip_sfc *sfc, u_char *buf,
>>> + size_t len)
>>> +{
>>> + rockchip_sfc_read_fifo(sfc, buf, len);
>>> +
>>> + return rockchip_sfc_wait_op_finish(sfc);
>>> +}
>>> +
>>> +static int rockchip_sfc_pio_transfer(struct spi_nor *nor, loff_t from_to,
>>> + size_t len, u_char *buf, u8 op_type)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> +
>>> + rockchip_sfc_setup_transfer(nor, from_to, len, op_type);
>>> +
>>> + if (op_type == SFC_CMD_DIR_WR)
>>> + return rockchip_sfc_pio_write(sfc, buf, len);
>>> + else
>>> + return rockchip_sfc_pio_read(sfc, buf, len);
>>> +}
>>> +
>>> +static int rockchip_sfc_dma_transfer(struct spi_nor *nor, loff_t from_to,
>>> + size_t len, u_char *buf, u8 op_type)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> + size_t offset;
>>> + int ret;
>>> + dma_addr_t dma_addr = 0;
>>> + int dma_dir;
>>> +
>>> + dma_dir = (op_type == SFC_CMD_DIR_RD) ?
>>> + DMA_FROM_DEVICE : DMA_TO_DEVICE;
>>> +
>>> + for (offset = 0; offset < len; offset += SFC_DMA_MAX_LEN) {
>>> + size_t trans = min_t(size_t, SFC_DMA_MAX_LEN, len - offset);
>>> +
>>> + dma_addr = dma_map_single(NULL, (void *)buf, trans, dma_dir);
>> not good: buf may have been allocated with vmalloc() hence the pages of buf
>> are not garanteed to be contiguous in physical memory.
>>
>> Just write a ubifs image into your QSPI memory and try to mount it. You are
>> very likely to notice some issues/crashes.
>>
>>
>
> This code can only work when:
> - len <= SFC_DMA_MAX_LEN and (buf + len) points inside the very same page
> as buf.
> or
> - dma_map_single() always fails so the driver always copy from/to buf data
> to/from sfc->buffer and transfers from/to sfc->buffer_dma.
>
> Otherwise the driver always tries to dma map from buf but buf is never
> incremented by offset after a transfer. Hence the driver transfers the
> right data during the first loop but starting from the 2nd loop it
> transfers the very same data again and again till offset >= len.
>
> I think you have forgotten a "+ offset" in the dma_map_single() call:
>
> dma_map_single(NULL, (void *)buf + offset, trans, dma_dir);
>
> ^^ should be better to provide some dev, e.g. nor->dev
>
> Anyway, like I've explained in my previous mail dma_map_single() is not
> suited to buffers allocated by vmalloc().
>
Got it, thanks.
>
>>> +
>>> + if (dma_mapping_error(sfc->dev, dma_addr)) {
>>> + /*
>>> + * If we use pre-allocated dma_buffer, we need to
>>> + * do a copy here.
>>> + */
>>> + if (op_type == SFC_CMD_DIR_WR)
>>> + memcpy(sfc->buffer, buf + offset, trans);
>>> +
>>> + dma_addr = 0;
>>> + }
>>> +
>>> + if (op_type == SFC_CMD_DIR_WR)
>>> + /*
>>> + * Flush the write data from write_buf to dma_addr
>>> + * if using dynamic allocated dma buffer before dma
>>> + * moves data from dma_addr to fifo.
>>> + */
>>> + dma_sync_single_for_device(sfc->dev, dma_addr,
>>> + trans, DMA_TO_DEVICE);
>>> +
>>> +
>>> + /* If failing to map dma, use pre-allocated area instead */
>>> + ret = rockchip_sfc_do_dma_transfer(nor, from_to + offset,
>>> + dma_addr ? dma_addr :
>>> + sfc->dma_buffer,
>>> + trans, op_type);
>>> +
>>> + if (dma_addr) {
>>> + /*
>>> + * Invalidate the read data from dma_addr if using
>>> + * dynamic allocated dma buffer after dma moves data
>>> + * from fifo to dma_addr.
>>> + */
>>> + if (op_type == SFC_CMD_DIR_RD)
>>> + dma_sync_single_for_cpu(sfc->dev, dma_addr,
>>> + trans, DMA_FROM_DEVICE);
>>> +
>>> + dma_unmap_single(NULL, dma_addr,
>>> + trans, dma_dir);
>>> + }
>>> +
>>> + if (ret) {
>>> + dev_warn(nor->dev, "DMA read timeout\n");
>>> + return ret;
>>> + }
>>> + /*
>>> + * If we use pre-allocated dma_buffer for read, we need to
>>> + * do a copy here.
>>> + */
>>> + if (!dma_addr && (op_type == SFC_CMD_DIR_RD))
>>> + memcpy(buf + offset, sfc->buffer, trans);
>>> + }
>>> +
>>> + return len;
>>> +}
>>> +
>>> +static ssize_t rockchip_sfc_do_rd_wr(struct spi_nor *nor, loff_t from_to,
>>> + size_t len, u_char *buf, u32 op_type)
>>> +{
>>> + struct rockchip_sfc_chip_priv *priv = nor->priv;
>>> + struct rockchip_sfc *sfc = priv->sfc;
>>> + int ret;
>>> +
>>> + if (likely(sfc->use_dma))
>>> + return rockchip_sfc_dma_transfer(nor, from_to, len,
>>> + buf, op_type);
>>> +
>>> + /* Fall back to PIO mode if DMA isn't present */
>>> + ret = rockchip_sfc_pio_transfer(nor, from_to, len,
>>> + (u_char *)buf, op_type);
>>> + if (ret) {
>>> + if (op_type == SFC_CMD_DIR_RD)
>>> + dev_warn(nor->dev, "PIO read timeout\n");
>>> + else
>>> + dev_warn(nor->dev, "PIO write timeout\n");
>>> + return ret;
>>> + }
>>> +
>>> + return len;
>>> +}
>>> +
>>> +static ssize_t rockchip_sfc_read(struct spi_nor *nor, loff_t from,
>>> + size_t len, u_char *read_buf)
>>> +{
>>> + return rockchip_sfc_do_rd_wr(nor, from, len,
>>> + read_buf, SFC_CMD_DIR_RD);
>>> +}
>>> +
>>> +static ssize_t rockchip_sfc_write(struct spi_nor *nor, loff_t to,
>>> + size_t len, const u_char *write_buf)
>>> +{
>>> + return rockchip_sfc_do_rd_wr(nor, to, len,
>>> + (u_char *)write_buf,
>>> + SFC_CMD_DIR_WR);
>>> +}
>>> +
>>> +static int rockchip_sfc_register(struct device_node *np,
>>> + struct rockchip_sfc *sfc)
>>> +{
>>> + struct device *dev = sfc->dev;
>>> + struct mtd_info *mtd;
>>> + struct spi_nor *nor;
>>> + int ret;
>>> +
>>> + nor = &sfc->flash[sfc->num_chip].nor;
>>> + nor->dev = dev;
>>> + spi_nor_set_flash_node(nor, np);
>>> +
>>> + ret = of_property_read_u8(np, "reg", &sfc->flash[sfc->num_chip].cs);
>>> + if (ret) {
>>> + dev_err(dev, "No reg property for %s\n",
>>> + np->full_name);
>>> + return ret;
>>> + }
>>> +
>>> + ret = of_property_read_u32(np, "spi-max-frequency",
>>> + &sfc->flash[sfc->num_chip].clk_rate);
>>> + if (ret) {
>>> + dev_err(dev, "No spi-max-frequency property for %s\n",
>>> + np->full_name);
>>> + return ret;
>>> + }
>>> +
>>> + sfc->flash[sfc->num_chip].sfc = sfc;
>>> + nor->priv = &(sfc->flash[sfc->num_chip]);
>>> +
>>> + nor->prepare = rockchip_sfc_prep;
>>> + nor->unprepare = rockchip_sfc_unprep;
>>> + nor->read_reg = rockchip_sfc_read_reg;
>>> + nor->write_reg = rockchip_sfc_write_reg;
>>> + nor->read = rockchip_sfc_read;
>>> + nor->write = rockchip_sfc_write;
>>> + nor->erase = NULL;
>>> + ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + mtd = &(nor->mtd);
>>> + mtd->name = np->name;
>>> + ret = mtd_device_register(mtd, NULL, 0);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + sfc->num_chip++;
>>> + return 0;
>>> +}
>>> +
>>> +static void rockchip_sfc_unregister_all(struct rockchip_sfc *sfc)
>>> +{
>>> + int i;
>>> +
>>> + for (i = 0; i < sfc->num_chip; i++)
>>> + mtd_device_unregister(&sfc->flash[i].nor.mtd);
>>> +}
>>> +
>>> +static int rockchip_sfc_register_all(struct rockchip_sfc *sfc)
>>> +{
>>> + struct device *dev = sfc->dev;
>>> + struct device_node *np;
>>> + int ret;
>>> +
>>> + for_each_available_child_of_node(dev->of_node, np) {
>>> + ret = rockchip_sfc_register(np, sfc);
>>> + if (ret)
>>> + goto fail;
>>> +
>>> + if (sfc->num_chip == SFC_MAX_CHIPSELECT_NUM) {
>>> + dev_warn(dev, "Exceeds the max cs limitation\n");
>>> + break;
>>> + }
>>> + }
>>> +
>>> + return 0;
>>> +
>>> +fail:
>>> + dev_err(dev, "Failed to register all chips\n");
>>> + /* Unregister all the _registered_ nor flash */
>>> + rockchip_sfc_unregister_all(sfc);
>>> + return ret;
>>> +}
>>> +
>>> +static irqreturn_t rockchip_sfc_irq_handler(int irq, void *dev_id)
>>> +{
>>> + struct rockchip_sfc *sfc = dev_id;
>>> + u32 reg;
>>> +
>>> + reg = readl_relaxed(sfc->regbase + SFC_RISR);
>>> + dev_dbg(sfc->dev, "Get irq: 0x%x\n", reg);
>>> +
>>> + /* Clear interrupt */
>>> + writel_relaxed(reg, sfc->regbase + SFC_ICLR);
>>> +
>>> + if (reg & SFC_RISR_TRAN_FINISH)
>>> + complete(&sfc->cp);
>>> +
>>> + return IRQ_HANDLED;
>>> +}
>>> +
>>> +static int rockchip_sfc_probe(struct platform_device *pdev)
>>> +{
>>> + struct device *dev = &pdev->dev;
>>> + struct resource *res;
>>> + struct rockchip_sfc *sfc;
>>> + int ret;
>>> +
>>> + sfc = devm_kzalloc(dev, sizeof(*sfc), GFP_KERNEL);
>>> + if (!sfc)
>>> + return -ENOMEM;
>>> +
>>> + platform_set_drvdata(pdev, sfc);
>>> + sfc->dev = dev;
>>> +
>>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> + sfc->regbase = devm_ioremap_resource(dev, res);
>>> + if (IS_ERR(sfc->regbase))
>>> + return PTR_ERR(sfc->regbase);
>>> +
>>> + sfc->clk = devm_clk_get(&pdev->dev, "sfc");
>>> + if (IS_ERR(sfc->clk)) {
>>> + dev_err(&pdev->dev, "Failed to get sfc interface clk\n");
>>> + return PTR_ERR(sfc->clk);
>>> + }
>>> +
>>> + sfc->hclk = devm_clk_get(&pdev->dev, "hsfc");
>>> + if (IS_ERR(sfc->hclk)) {
>>> + dev_err(&pdev->dev, "Failed to get sfc ahp clk\n");
>>> + return PTR_ERR(sfc->hclk);
>>> + }
>>> +
>>> + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
>>> + if (ret) {
>>> + dev_warn(dev, "Unable to set dma mask\n");
>>> + return ret;
>>> + }
>>> +
>>> + sfc->buffer = dmam_alloc_coherent(dev, SFC_DMA_MAX_LEN,
>>> + &sfc->dma_buffer, GFP_KERNEL);
>>> + if (!sfc->buffer)
>>> + return -ENOMEM;
>>> +
>>> + mutex_init(&sfc->lock);
>>> +
>>> + ret = clk_prepare_enable(sfc->hclk);
>>> + if (ret) {
>>> + dev_err(&pdev->dev, "Failed to enable hclk\n");
>>> + goto err_hclk;
>>> + }
>>> +
>>> + ret = clk_prepare_enable(sfc->clk);
>>> + if (ret) {
>>> + dev_err(&pdev->dev, "Failed to enable clk\n");
>>> + goto err_clk;
>>> + }
>>> +
>>> + sfc->use_dma = !of_property_read_bool(sfc->dev->of_node,
>>> + "rockchip,sfc-no-DMA");
>>> +
>>> + sfc->negative_edge = of_device_is_compatible(sfc->dev->of_node,
>>> + "rockchip,rk1108-sfc");
>>> + /* Find the irq */
>>> + ret = platform_get_irq(pdev, 0);
>>> + if (ret < 0) {
>>> + dev_err(dev, "Failed to get the irq\n");
>>> + goto err_irq;
>>> + }
>>> +
>>> + ret = devm_request_irq(dev, ret, rockchip_sfc_irq_handler,
>>> + 0, pdev->name, sfc);
>>> + if (ret) {
>>> + dev_err(dev, "Failed to request irq\n");
>>> + goto err_irq;
>>> + }
>>> +
>>> + sfc->num_chip = 0;
>>> + ret = rockchip_sfc_init(sfc);
>>> + if (ret)
>>> + goto err_irq;
>>> +
>>> + pm_runtime_get_noresume(&pdev->dev);
>>> + pm_runtime_set_active(&pdev->dev);
>>> + pm_runtime_enable(&pdev->dev);
>>> + pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
>>> + pm_runtime_use_autosuspend(&pdev->dev);
>>> +
>>> + ret = rockchip_sfc_register_all(sfc);
>>> + if (ret)
>>> + goto err_register;
>>> +
>>> + clk_disable_unprepare(sfc->clk);
>>> + pm_runtime_put_autosuspend(&pdev->dev);
>>> + return 0;
>>> +
>>> +err_register:
>>> + pm_runtime_disable(&pdev->dev);
>>> + pm_runtime_set_suspended(&pdev->dev);
>>> + pm_runtime_put_noidle(&pdev->dev);
>>> +err_irq:
>>> + clk_disable_unprepare(sfc->clk);
>>> +err_clk:
>>> + clk_disable_unprepare(sfc->hclk);
>>> +err_hclk:
>>> + mutex_destroy(&sfc->lock);
>>> + return ret;
>>> +}
>>> +
>>> +static int rockchip_sfc_remove(struct platform_device *pdev)
>>> +{
>>> + struct rockchip_sfc *sfc = platform_get_drvdata(pdev);
>>> +
>>> + pm_runtime_get_sync(&pdev->dev);
>>> + pm_runtime_disable(&pdev->dev);
>>> + pm_runtime_put_noidle(&pdev->dev);
>>> +
>>> + rockchip_sfc_unregister_all(sfc);
>>> + mutex_destroy(&sfc->lock);
>>> + clk_disable_unprepare(sfc->clk);
>>> + clk_disable_unprepare(sfc->hclk);
>>> + return 0;
>>> +}
>>> +
>>> +#ifdef CONFIG_PM
>>> +int rockchip_sfc_runtime_suspend(struct device *dev)
>>> +{
>>> + struct rockchip_sfc *sfc = dev_get_drvdata(dev);
>>> +
>>> + clk_disable_unprepare(sfc->hclk);
>>> + return 0;
>>> +}
>>> +
>>> +int rockchip_sfc_runtime_resume(struct device *dev)
>>> +{
>>> + struct rockchip_sfc *sfc = dev_get_drvdata(dev);
>>> +
>>> + clk_prepare_enable(sfc->hclk);
>>> + return rockchip_sfc_reset(sfc);
>>> +}
>>> +#endif /* CONFIG_PM */
>>> +
>>> +static const struct of_device_id rockchip_sfc_dt_ids[] = {
>>> + { .compatible = "rockchip,sfc"},
>>> + { /* sentinel */ }
>>> +};
>>> +MODULE_DEVICE_TABLE(of, rockchip_sfc_dt_ids);
>>> +
>>> +static const struct dev_pm_ops rockchip_sfc_dev_pm_ops = {
>>> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
>>> + pm_runtime_force_resume)
>>> + SET_RUNTIME_PM_OPS(rockchip_sfc_runtime_suspend,
>>> + rockchip_sfc_runtime_resume, NULL)
>>> +};
>>> +
>>> +static struct platform_driver rockchip_sfc_driver = {
>>> + .driver = {
>>> + .name = "rockchip-sfc",
>>> + .of_match_table = rockchip_sfc_dt_ids,
>>> + .pm = &rockchip_sfc_dev_pm_ops,
>>> + },
>>> + .probe = rockchip_sfc_probe,
>>> + .remove = rockchip_sfc_remove,
>>> +};
>>> +module_platform_driver(rockchip_sfc_driver);
>>> +
>>> +MODULE_LICENSE("GPL v2");
>>> +MODULE_DESCRIPTION("Rockchip Serial Flash Controller Driver");
>>> +MODULE_AUTHOR("Shawn Lin <shawn.lin@rock-chips.com>");
>>>
>>
>>
>> ______________________________________________________
>> Linux MTD discussion mailing list
>> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>>
>
>
>
>
--
Best Regards
Shawn Lin
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
* Re: [PATCH v2 1/2] devicetree: add Garmin vendor prefix
From: Matt Ranostay @ 2017-01-17 1:50 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Jonathan Cameron, Rob Herring
In-Reply-To: <06f2cde2-ac7e-d0e5-5e35-a4946d0398f8-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Mon, Jan 16, 2017 at 5:07 PM, Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On 12/29/2016 06:13 AM, Matt Ranostay wrote:
>
> Some commit message / description of the company would be useful.
>
>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>> ---
>> Changes from v1:
>> * switch to stock ticker for Garmin Limited
>>
>> Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
>> index 16d3b5e7f5d1..5749bfc5fc5b 100644
>> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
>> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
>> @@ -107,6 +107,7 @@ firefly Firefly
>> focaltech FocalTech Systems Co.,Ltd
>> friendlyarm Guangzhou FriendlyARM Computer Tech Co., Ltd
>> fsl Freescale Semiconductor
>> +grmn Garmin Limited
>
> Why grmn ? Why not 'garmin' ? Also, the rest uses Ltd. , so make it
> consistent ?
>
As already stated GRMN is the US stock ticker... and is the "correct way" :)
>> ge General Electric Company
>> geekbuying GeekBuying
>> gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
>>
>
>
> --
> Best regards,
> Marek Vasut
^ permalink raw reply
* Re: [PATCH v2 1/2] devicetree: add Garmin vendor prefix
From: Marek Vasut @ 2017-01-17 1:52 UTC (permalink / raw)
To: Matt Ranostay
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Jonathan Cameron, Rob Herring
In-Reply-To: <CAJ_EiSQ+kfNnoDsed67v_1CLui7Fp2qMsx67bYMvQ0Y98jO+Aw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 01/17/2017 02:50 AM, Matt Ranostay wrote:
> On Mon, Jan 16, 2017 at 5:07 PM, Marek Vasut <marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> On 12/29/2016 06:13 AM, Matt Ranostay wrote:
>>
>> Some commit message / description of the company would be useful.
>>
>>> Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>>> ---
>>> Changes from v1:
>>> * switch to stock ticker for Garmin Limited
>>>
>>> Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
>>> 1 file changed, 1 insertion(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
>>> index 16d3b5e7f5d1..5749bfc5fc5b 100644
>>> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
>>> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
>>> @@ -107,6 +107,7 @@ firefly Firefly
>>> focaltech FocalTech Systems Co.,Ltd
>>> friendlyarm Guangzhou FriendlyARM Computer Tech Co., Ltd
>>> fsl Freescale Semiconductor
>>> +grmn Garmin Limited
>>
>> Why grmn ? Why not 'garmin' ? Also, the rest uses Ltd. , so make it
>> consistent ?
>>
>
> As already stated GRMN is the US stock ticker... and is the "correct way" :)
So we should use the US stock tickers for DT vendor prefixes now ?
>>> ge General Electric Company
>>> geekbuying GeekBuying
>>> gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
>>>
>>
>>
>> --
>> Best regards,
>> Marek Vasut
--
Best regards,
Marek Vasut
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox