* [RFC] Documentation: devicetree: bindings: drm: Xylon binding
From: Davor Joja @ 2014-02-05 15:36 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA; +Cc: Davor Joja
In-Reply-To: <1391614588-2831-1-git-send-email-davorjoja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
Xylon binding of DRM driver and logiCVC IP core.
Signed-off-by: Davor Joja <davorjoja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
---
.../devicetree/bindings/drm/xylon/logicvc.txt | 79 ++++++++++++++++++++
.../devicetree/bindings/drm/xylon/xylon_drm.txt | 24 ++++++
2 files changed, 103 insertions(+)
create mode 100644 Documentation/devicetree/bindings/drm/xylon/logicvc.txt
create mode 100644 Documentation/devicetree/bindings/drm/xylon/xylon_drm.txt
diff --git a/Documentation/devicetree/bindings/drm/xylon/logicvc.txt b/Documentation/devicetree/bindings/drm/xylon/logicvc.txt
new file mode 100644
index 0000000..505e655
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/xylon/logicvc.txt
@@ -0,0 +1,79 @@
+Binding for Xylon configurable video controller logiCVC IP core
+
+Required properties:
+ - compatible: value must be "xylon,logicvc-4.00.a"
+ - reg: MMIO base address and size of the logiCVC IP core address space
+ - interrupts-parent: the phandle for interrupt controller
+ - interrupts: the interrupt number
+ - background-layer-bits-per-pixel: background layer bits per pixel (16, 32)
+ if omitted, last available layer is logiCVC standard layer, which has its
+ own video memory of specific size, color format and specified
+ bits per pixel
+ if 16 or 32, last available layer is logiCVC background layer,
+ with only specified bits per pixel value
+ - interface: logiCVC to display physical interface
+ (0=Parallel, 1=ITU656)
+ - color-space: logiCVC to display physical color space
+ (0=RGB, 1=YCbCr 4:2:2, 2=YCbCr 4:4:4)
+ - is-readable-regs: all logiCVC registers are available for reading
+ if omitted, only Interrupt Status, Power Control and IP Version registers
+ are available for reading
+ - is-size-position: logiCVC functionality for controlling on screen layer size
+ and position is available
+ if omitted, functionality is not available
+ - pixel-stride: layer video memory width in pixels
+ common for all available logiCVC standard layers
+ - layer_0: layer has its own configuration described with below properties
+ - bits-per-pixel: layer bits per pixel configuration (16, 32)
+ layer is configured to be used with specific pixel width in bits
+ pixels written to layer video memory must match in size to configured
+ bits per pixel value
+ - format: layer format (0=RGB, 1=YCbCr)
+ layer is configured to be used with specific color format
+ pixels written to layer video memory must match specified color format
+ - transparency: layer transparency (0=Layer, 1=Pixel)
+ logiCVC layer can be configured to have transparency control on
+ layer or pixel level
+ "Layer" mode enables controlling of layer transparency by changing
+ alpha value in single logiCVC register
+ "Pixel" mode enables controlling of pixel transparency by changing
+ dedicated alpha bits of specific pixel in video memory
+
+Example:
+
+ logicvc_0: logicvc@40000000 {
+ compatible = "xylon,logicvc-4.00.a";
+ reg = <0x40000000 0x6000>;
+ interrupt-parent = <&gic_0>;
+ interrupts = <0 59 4>;
+ background-layer-bits-per-pixel = <32>;
+ interface = <0>;
+ color-space = <1>;
+ is-readable-regs;
+ is-size-position;
+ pixel-stride = <2048>;
+ layer_0 {
+ address = <0x30000000>;
+ bits-per-pixel = <16>;
+ format = <0>;
+ transparency = <0>;
+ };
+ layer_1 {
+ address = <0x30500000>;
+ bits-per-pixel = <32>;
+ format = <0>;
+ transparency = <0>;
+ };
+ layer_2 {
+ address = <0x30E00000>;
+ bits-per-pixel = <32>;
+ format = <0>;
+ transparency = <1>;
+ };
+ layer_3 {
+ address = <0x31700000>;
+ bits-per-pixel = <16>;
+ format = <1>;
+ transparency = <0>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/drm/xylon/xylon_drm.txt b/Documentation/devicetree/bindings/drm/xylon/xylon_drm.txt
new file mode 100644
index 0000000..da4940e
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/xylon/xylon_drm.txt
@@ -0,0 +1,24 @@
+Binding for Xylon DRM driver
+
+Xylon DRM driver supports the Xylon configurable video controller
+logiCVC FPGA IP core device.
+
+On ZC702, ZC706, ZED boards, logiCVC uses SI570 CCF driver for pixel clock
+generation, and ADV7511 DRM encoder driver to set video encoding configuration.
+
+Required properties:
+ - compatible: value should be "xylon,drm-1.00.a".
+ - clocks: the phandle for the pixel clock generator
+ - device: the phandle for logiCVC video controller device
+ - encoder: the phandle for the video encoder
+ - private-plane: logiCVC layer id used for DRM driver private plane
+
+Example:
+
+ xylon_drm {
+ compatible = "xylon,drm-1.00.a";
+ clocks = <&si570>;
+ device = <&logicvc_0>;
+ encoder = <&adv7511>;
+ private-plane = <0>;
+ };
--
1.7.9.5
--
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
* [RFC] Xylon video controller binding
From: Davor Joja @ 2014-02-05 15:36 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA
Hi,
I would like to get some comments on logiCVC video controller binding from
patch.
Thank you,
Davor
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] DT: net: document Ethernet bindings in one place
From: Sergei Shtylyov @ 2014-02-05 15:36 UTC (permalink / raw)
To: Grant Likely, Florian Fainelli, Rob Herring
Cc: netdev, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, devicetree@vger.kernel.org, Rob Landley,
linux-doc@vger.kernel.org
In-Reply-To: <20140205120843.9ED08C40A89@trevor.secretlab.ca>
Hello.
On 02/05/2014 03:08 PM, Grant Likely wrote:
>>>>>>>>> I'm afraid that's too late, it has spread very far, so that
>>>>>>>>> of_get_phy_mode() handles that property, not "phy-connection-type".
>>>>>>>> Uggg, I guess this is a case of a defacto standard then if the kernel
>>>>>>>> doesn't even support it.
>>>>>>> Maybe I forgot to CC you on patch sent to Grant only, I sent a patch a
>>>>>>> while ago for of_get_phy_mode() to look for both "phy-mode" and
>>>>>>> "phy-connection-type" since the former has been a Linux invention, but
>>>>>>> the latter is ePAPR specified.
>>>>>> Here is a link to the actual patch in question, not sure which tree
>>>>>> Grant applied it to though:
>>>>>> http://lkml.indiana.edu/hypermail/linux/kernel/1311.2/00048.html
>>>>> It's not the patch mail, it's Grant's "applied" reply, patch is mangled in
>>>>> this reply, and I couldn't follow the thread. Here's the actual patch mail:
>>>>> http://marc.info/?l=devicetree&m=138449662807254
>>>> Florian, I didn't find this patch in Grant's official tree, so maybe you
>>>> should ask him where is the patch already?
>>> Sorry, I accidentally dropped it. It will be in the next merge window.
>> Already saw it, thanks. Would that it was in 3.14 instead of course, so
>> that I could use "phy-connection-type" in my binding...
> Is 3.14 broken because of missing the patch? If so I'll get it merged as
> a bug fix.
No, it's not. I could have used "phy-connection-type" in my binding
destined for 3.15 and document it as a preferred property as well.
> g.
WBR, Sergei
^ permalink raw reply
* Re: [PATCH 1/6] i2c: bcm-kona: register with subsys_initcall
From: Alan Stern @ 2014-02-05 15:30 UTC (permalink / raw)
To: Matt Porter
Cc: Wolfram Sang, Tim Kryger, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Samuel Ortiz, Lee Jones, Liam Girdwood,
Mark Brown, Christian Daudt, Devicetree List, Linux I2C List,
Linux ARM Kernel List, Linux Kernel Mailing List, Felipe Balbi,
linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20140205151826.GC22153@beef>
On Wed, 5 Feb 2014, Matt Porter wrote:
> On Wed, Feb 05, 2014 at 10:08:18AM +0100, Wolfram Sang wrote:
> > On Tue, Feb 04, 2014 at 07:19:07AM -0500, Matt Porter wrote:
> >
> > > Voltage regulators are needed very early due to deferred probe
> > > being incompatible with built-in USB gadget drivers.
> >
> > What does it need to fix those instead?
>
> [added Alan/Felipe for more insight]
>
> Discussion on that topic came about from this submission:
> http://www.spinics.net/lists/linux-usb/msg94217.html
>
> End of it is:
> http://www.spinics.net/lists/linux-usb/msg94731.html
>
> We can either add to the many drivers that already do subsys_initcall()
> for similar reasons...or I can drop this from the series and add gadget
> probe ordering to my TODO list.
>
> In short, it can't be a late_initcall() hack like the original post and
> really could be solved by converting to a real bus (and letting
> deferred probe do its job)..but Alan voiced concerns about that.
Don't worry too much about what I said. If adding a "gadget" bus will
solve the problem in an appropriate way, and if nobody else objects
(particularly Felipe, who is on vacation now), then go for it.
Alan Stern
--
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 RESEND] ARM: dts: add BeagleBone Audio Cape (Rev A) dtsi
From: Matt Porter @ 2014-02-05 15:29 UTC (permalink / raw)
To: Nishanth Menon
Cc: Jack Mitchell, bcousson, tony, robh+dt, pawel.moll, mark.rutland,
ijc+devicetree, galak, linux, linux-omap, devicetree,
linux-arm-kernel, linux-kernel, Jack Mitchell
In-Reply-To: <52F25122.50400@ti.com>
On Wed, Feb 05, 2014 at 08:56:34AM -0600, Nishanth Menon wrote:
> On 02/05/2014 08:38 AM, Matt Porter wrote:
> > On Wed, Feb 05, 2014 at 08:09:16AM -0600, Nishanth Menon wrote:
> >> On 02/05/2014 07:48 AM, Jack Mitchell wrote:
> [...]
> >>> + * --- a/arch/arm/boot/dts/am335x-boneblack.dts
> >>> + * +++ b/arch/arm/boot/dts/am335x-boneblack.dts
> >>> + * @@ -73,6 +74,6 @@
> >>> + * pinctrl-names = "default", "off";
> >>> + * pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
> >>> + * pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
> >>> + * - status = "okay";
> >>> + * + status = "disabled";
> >>> + * };
> >>> + * };
> >>> + */
> >>> +
> >> how about making the audio-cape-reva.dts which includes and overrides
> >> parameters of boneblack.dts?
> >
> > Yeah, that might be a little cleaner. Black makes things unfortunately
> > messy for these capes that were really intended for BBW :(
>
> yes indeed - we might have to live with more dts in such a case.
> >
> >> Further, I see a bunch of capes in
> >> http://elinux.org/Beagleboard:BeagleBone_Capes
> >>
> >> Assuming that we dont want to discuss capebus all over again, is this
> >> the approach we'd like to consider in the interim?
> >
> > I think that's a fair assumption...I'll note that there is work slowly
> > in progress on a very minimal implementation DT overlays upstream. But
> > that doesn't exist. We are simply interested in a sane way to use the
> > hardware we own in mainline and this approach makes it possible to build
> > a kernel+dtb from mainline that works for this configuration. If
> > there's a better way to support this hardware *today* let's discuss it.
> > One of the big benefits to having this upstream is that it's no longer
> > out of sight out of mind. It should be managed alongside all the other
> > am335x dts data.
> >
> > Incidentally, I'm hoping to contribute a similar patch for the DVI cape
> > I have here.
>
> If I am not mistaken, the capes are stackable (within reason), and are
> not exactly hotpluggable.. question pops up as to how do we handle
> multiple cape descriptions on the same board without having the user
> to create custom dts which includes each relevant cape dts he has on
> his/her bone? I wonder(without proper research, just thinking aloud)
> if u-boot can do some sort of merge of dtbs - assuming ofcourse eeprom
> data is used to detect the capes plugged on board?
Well covered in the original discussion. gcl summarizes options in
https://lkml.org/lkml/2012/11/5/615
Since then, the basic overlay support for the kernel is pretty much a
done deal. It has a wide variety of users (FPGA folks) beyond this board
specific case. The problem you describe about resource management and
conflicts would probably need to be built on top of that. Pantelis
had a PoC implementation with capebus/not-a-capebus but that's not part
of what is being upstreamed. I'm not sure if there's anybody with enough
time out of the Beagleboard community to upstream a resource manager on
top of the basic overlay support that's in progress. However, it might
make a nice GSoC2014 project. :)
-Matt
^ permalink raw reply
* [PATCH v2 RESEND] pwm: Add CLPS711X PWM support
From: Alexander Shiyan @ 2014-02-05 15:22 UTC (permalink / raw)
To: linux-pwm
Cc: Thierry Reding, devicetree, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Grant Likely, Alexander Shiyan
Add a new driver for the ARM CLPS711X Pulse Width Modulator (PWM) interface.
This CPU contain two 4-bit PWM outputs with constant period, based on CPU
PLL frequency. PWM polarity is determined by hardware by power on reset.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
.../bindings/pwm/cirrus-clps711x-pwm.txt | 15 ++
drivers/pwm/Kconfig | 9 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-clps711x.c | 176 +++++++++++++++++++++
4 files changed, 201 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pwm/cirrus-clps711x-pwm.txt
create mode 100644 drivers/pwm/pwm-clps711x.c
diff --git a/Documentation/devicetree/bindings/pwm/cirrus-clps711x-pwm.txt b/Documentation/devicetree/bindings/pwm/cirrus-clps711x-pwm.txt
new file mode 100644
index 0000000..e252f6d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/cirrus-clps711x-pwm.txt
@@ -0,0 +1,15 @@
+* Cirris Logic CLPS711X PWM controller
+
+Required properties:
+- compatible: Should be "cirrus,clps711x-pwm".
+- reg: Physical base address and length of the controller's registers.
+- clocks: phandle to the PWM reference clock.
+- #pwm-cells: Should be 1. The cell specifies the index of the channel.
+
+Example:
+ pwm: pwm@80000400 {
+ compatible = "cirrus,clps711x-pwm";
+ reg = <0x80000400 0x4>;
+ clocks = <&clks 8>;
+ #pwm-cells = <1>;
+ };
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 22f2f28..d3a2c26 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -71,6 +71,15 @@ config PWM_BFIN
To compile this driver as a module, choose M here: the module
will be called pwm-bfin.
+config PWM_CLPS711X
+ tristate "CLPS711X PWM support"
+ depends on ARCH_CLPS711X || COMPILE_TEST
+ help
+ Generic PWM framework driver for Cirrus Logic CLPS711X.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-clps711x.
+
config PWM_EP93XX
tristate "Cirrus Logic EP93xx PWM support"
depends on ARCH_EP93XX
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index d8906ec..d676681 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o
obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o
obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
+obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o
obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
obj-$(CONFIG_PWM_IMX) += pwm-imx.o
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c
new file mode 100644
index 0000000..fafb6a0
--- /dev/null
+++ b/drivers/pwm/pwm-clps711x.c
@@ -0,0 +1,176 @@
+/*
+ * Cirrus Logic CLPS711X PWM driver
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+
+struct clps711x_chip {
+ struct pwm_chip chip;
+ void __iomem *pmpcon;
+ struct clk *clk;
+ spinlock_t lock;
+};
+
+static inline struct clps711x_chip *to_clps711x_chip(struct pwm_chip *chip)
+{
+ return container_of(chip, struct clps711x_chip, chip);
+}
+
+static void clps711x_pwm_update_val(struct clps711x_chip *priv, u32 n, u32 v)
+{
+ /* PWM0 - bits 4..7, PWM1 - bits 8..11 */
+ u32 shift = (n + 1) * 4;
+ unsigned long flags;
+ u32 tmp;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ tmp = readl(priv->pmpcon);
+ tmp &= ~(0xf << shift);
+ tmp |= v << shift;
+ writel(tmp, priv->pmpcon);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static unsigned int clps711x_get_duty(struct pwm_device *pwm, unsigned int v)
+{
+ /* Duty cycle 0..15 max */
+ return DIV_ROUND_CLOSEST(v * 0xf, pwm_get_period(pwm));
+}
+
+static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct clps711x_chip *priv = to_clps711x_chip(chip);
+ unsigned int freq = clk_get_rate(priv->clk);
+
+ if (!freq)
+ return -EINVAL;
+
+ /* Store constant period value */
+ pwm_set_period(pwm, DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq));
+
+ return 0;
+}
+
+static int clps711x_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ struct clps711x_chip *priv = to_clps711x_chip(chip);
+ unsigned int duty;
+
+ if (period_ns != pwm_get_period(pwm))
+ return -EINVAL;
+
+ duty = clps711x_get_duty(pwm, duty_ns);
+ clps711x_pwm_update_val(priv, pwm->hwpwm, duty);
+
+ return 0;
+}
+
+static int clps711x_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct clps711x_chip *priv = to_clps711x_chip(chip);
+ unsigned int duty;
+
+ duty = clps711x_get_duty(pwm, pwm_get_duty_cycle(pwm));
+ clps711x_pwm_update_val(priv, pwm->hwpwm, duty);
+
+ return 0;
+}
+
+static void clps711x_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct clps711x_chip *priv = to_clps711x_chip(chip);
+
+ clps711x_pwm_update_val(priv, pwm->hwpwm, 0);
+}
+
+static const struct pwm_ops clps711x_pwm_ops = {
+ .request = clps711x_pwm_request,
+ .config = clps711x_pwm_config,
+ .enable = clps711x_pwm_enable,
+ .disable = clps711x_pwm_disable,
+ .owner = THIS_MODULE,
+};
+
+static struct pwm_device *clps711x_pwm_xlate(struct pwm_chip *chip,
+ const struct of_phandle_args *args)
+{
+ if (args->args[0] >= chip->npwm)
+ return ERR_PTR(-EINVAL);
+
+ return pwm_request_from_chip(chip, args->args[0], NULL);
+}
+
+static int clps711x_pwm_probe(struct platform_device *pdev)
+{
+ struct clps711x_chip *priv;
+ struct resource *res;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->pmpcon = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->pmpcon))
+ return PTR_ERR(priv->pmpcon);
+
+ priv->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+ priv->chip.ops = &clps711x_pwm_ops;
+ priv->chip.dev = &pdev->dev;
+ priv->chip.base = -1;
+ priv->chip.npwm = 2;
+ priv->chip.of_xlate = clps711x_pwm_xlate;
+ priv->chip.of_pwm_n_cells = 1;
+
+ spin_lock_init(&priv->lock);
+
+ platform_set_drvdata(pdev, priv);
+
+ return pwmchip_add(&priv->chip);
+}
+
+static int clps711x_pwm_remove(struct platform_device *pdev)
+{
+ struct clps711x_chip *priv = platform_get_drvdata(pdev);
+
+ return pwmchip_remove(&priv->chip);
+}
+
+static const struct of_device_id __maybe_unused clps711x_pwm_dt_ids[] = {
+ { .compatible = "cirrus,clps711x-pwm", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, clps711x_pwm_dt_ids);
+
+static struct platform_driver clps711x_pwm_driver = {
+ .driver = {
+ .name = "clps711x-pwm",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(clps711x_pwm_dt_ids),
+ },
+ .probe = clps711x_pwm_probe,
+ .remove = clps711x_pwm_remove,
+};
+module_platform_driver(clps711x_pwm_driver);
+
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Cirrus Logic CLPS711X PWM driver");
+MODULE_LICENSE("GPL");
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH 1/6] i2c: bcm-kona: register with subsys_initcall
From: Matt Porter @ 2014-02-05 15:18 UTC (permalink / raw)
To: Wolfram Sang
Cc: Tim Kryger, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Samuel Ortiz, Lee Jones, Liam Girdwood, Mark Brown,
Christian Daudt, Devicetree List, Linux I2C List,
Linux ARM Kernel List, Linux Kernel Mailing List, Alan Stern,
Felipe Balbi, linux-usb
In-Reply-To: <20140205090818.GA2614@katana>
On Wed, Feb 05, 2014 at 10:08:18AM +0100, Wolfram Sang wrote:
> On Tue, Feb 04, 2014 at 07:19:07AM -0500, Matt Porter wrote:
>
> > Voltage regulators are needed very early due to deferred probe
> > being incompatible with built-in USB gadget drivers.
>
> What does it need to fix those instead?
[added Alan/Felipe for more insight]
Discussion on that topic came about from this submission:
http://www.spinics.net/lists/linux-usb/msg94217.html
End of it is:
http://www.spinics.net/lists/linux-usb/msg94731.html
We can either add to the many drivers that already do subsys_initcall()
for similar reasons...or I can drop this from the series and add gadget
probe ordering to my TODO list.
In short, it can't be a late_initcall() hack like the original post and
really could be solved by converting to a real bus (and letting
deferred probe do its job)..but Alan voiced concerns about that.
-Matt
^ permalink raw reply
* Re: [PATCH v4 3/5] spi: sunxi: Add Allwinner A31 SPI controller driver
From: Mark Brown @ 2014-02-05 14:59 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mike Turquette, Emilio Lopez, linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
kevin.z.m.zh-Re5JQEeQqe8AvxtiuMwx3w,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
zhuzhenhua-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf
In-Reply-To: <1391605507-30981-4-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 182 bytes --]
On Wed, Feb 05, 2014 at 02:05:05PM +0100, Maxime Ripard wrote:
> The Allwinner A31 has a new SPI controller IP compared to the older Allwinner
> SoCs.
Looks good - applied, thanks!
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH RESEND] ARM: dts: add BeagleBone Audio Cape (Rev A) dtsi
From: Nishanth Menon @ 2014-02-05 14:56 UTC (permalink / raw)
To: Matt Porter
Cc: Jack Mitchell, bcousson, tony, robh+dt, pawel.moll, mark.rutland,
ijc+devicetree, galak, linux, linux-omap, devicetree,
linux-arm-kernel, linux-kernel, Jack Mitchell
In-Reply-To: <20140205143800.GB22153@beef>
On 02/05/2014 08:38 AM, Matt Porter wrote:
> On Wed, Feb 05, 2014 at 08:09:16AM -0600, Nishanth Menon wrote:
>> On 02/05/2014 07:48 AM, Jack Mitchell wrote:
[...]
>>> + * --- a/arch/arm/boot/dts/am335x-boneblack.dts
>>> + * +++ b/arch/arm/boot/dts/am335x-boneblack.dts
>>> + * @@ -73,6 +74,6 @@
>>> + * pinctrl-names = "default", "off";
>>> + * pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
>>> + * pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
>>> + * - status = "okay";
>>> + * + status = "disabled";
>>> + * };
>>> + * };
>>> + */
>>> +
>> how about making the audio-cape-reva.dts which includes and overrides
>> parameters of boneblack.dts?
>
> Yeah, that might be a little cleaner. Black makes things unfortunately
> messy for these capes that were really intended for BBW :(
yes indeed - we might have to live with more dts in such a case.
>
>> Further, I see a bunch of capes in
>> http://elinux.org/Beagleboard:BeagleBone_Capes
>>
>> Assuming that we dont want to discuss capebus all over again, is this
>> the approach we'd like to consider in the interim?
>
> I think that's a fair assumption...I'll note that there is work slowly
> in progress on a very minimal implementation DT overlays upstream. But
> that doesn't exist. We are simply interested in a sane way to use the
> hardware we own in mainline and this approach makes it possible to build
> a kernel+dtb from mainline that works for this configuration. If
> there's a better way to support this hardware *today* let's discuss it.
> One of the big benefits to having this upstream is that it's no longer
> out of sight out of mind. It should be managed alongside all the other
> am335x dts data.
>
> Incidentally, I'm hoping to contribute a similar patch for the DVI cape
> I have here.
If I am not mistaken, the capes are stackable (within reason), and are
not exactly hotpluggable.. question pops up as to how do we handle
multiple cape descriptions on the same board without having the user
to create custom dts which includes each relevant cape dts he has on
his/her bone? I wonder(without proper research, just thinking aloud)
if u-boot can do some sort of merge of dtbs - assuming ofcourse eeprom
data is used to detect the capes plugged on board?
--
Regards,
Nishanth Menon
^ permalink raw reply
* Re: [PATCH v4 1/5] clk: sunxi: Add support for PLL6 on the A31
From: Mike Turquette @ 2014-02-05 14:51 UTC (permalink / raw)
To: Mark Brown, Emilio Lopez
Cc: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
kevin.z.m.zh-Re5JQEeQqe8AvxtiuMwx3w,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
zhuzhenhua-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf, Maxime Ripard
In-Reply-To: <1391605507-30981-2-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Quoting Maxime Ripard (2014-02-05 05:05:03)
> The A31 has a slightly different PLL6 clock. Add support for this new clock in
> our driver.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Looks good to me.
Regards,
Mike
> ---
> Documentation/devicetree/bindings/clock/sunxi.txt | 1 +
> drivers/clk/sunxi/clk-sunxi.c | 45 +++++++++++++++++++++++
> 2 files changed, 46 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index c2cb762..954845c 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -11,6 +11,7 @@ Required properties:
> "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
> "allwinner,sun4i-pll5-clk" - for the PLL5 clock
> "allwinner,sun4i-pll6-clk" - for the PLL6 clock
> + "allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31
> "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
> "allwinner,sun4i-axi-clk" - for the AXI clock
> "allwinner,sun4i-axi-gates-clk" - for the AXI gates
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index abb6c5a..0c05c2d 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -249,7 +249,38 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
> *n = DIV_ROUND_UP(div, (*k+1));
> }
>
> +/**
> + * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6
> + * PLL6 rate is calculated as follows
> + * rate = parent_rate * n * (k + 1) / 2
> + * parent_rate is always 24Mhz
> + */
> +
> +static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
> + u8 *n, u8 *k, u8 *m, u8 *p)
> +{
> + u8 div;
> +
> + /*
> + * We always have 24MHz / 2, so we can just say that our
> + * parent clock is 12MHz.
> + */
> + parent_rate = parent_rate / 2;
> +
> + /* Normalize value to a parent_rate multiple (24M / 2) */
> + div = *freq / parent_rate;
> + *freq = parent_rate * div;
> +
> + /* we were called to round the frequency, we can now return */
> + if (n == NULL)
> + return;
> +
> + *k = div / 32;
> + if (*k > 3)
> + *k = 3;
>
> + *n = DIV_ROUND_UP(div, (*k+1));
> +}
>
> /**
> * sun4i_get_apb1_factors() - calculates m, p factors for APB1
> @@ -416,6 +447,13 @@ static struct clk_factors_config sun4i_pll5_config = {
> .kwidth = 2,
> };
>
> +static struct clk_factors_config sun6i_a31_pll6_config = {
> + .nshift = 8,
> + .nwidth = 5,
> + .kshift = 4,
> + .kwidth = 2,
> +};
> +
> static struct clk_factors_config sun4i_apb1_config = {
> .mshift = 0,
> .mwidth = 5,
> @@ -457,6 +495,12 @@ static const struct factors_data sun4i_pll5_data __initconst = {
> .getter = sun4i_get_pll5_factors,
> };
>
> +static const struct factors_data sun6i_a31_pll6_data __initconst = {
> + .enable = 31,
> + .table = &sun6i_a31_pll6_config,
> + .getter = sun6i_a31_get_pll6_factors,
> +};
> +
> static const struct factors_data sun4i_apb1_data __initconst = {
> .table = &sun4i_apb1_config,
> .getter = sun4i_get_apb1_factors,
> @@ -972,6 +1016,7 @@ free_clkdata:
> static const struct of_device_id clk_factors_match[] __initconst = {
> {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
> {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
> + {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
> {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
> {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
> {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,},
> --
> 1.8.4.2
>
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v5 2/3] clocksource: keystone: add bindings for keystone timer
From: Rob Herring @ 2014-02-05 14:39 UTC (permalink / raw)
To: Ivan Khoronzhuk
Cc: Santosh Shilimkar, Rob Landley, Russell King - ARM Linux,
Kumar Gala, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
Daniel Lezcano, Thomas Gleixner, devicetree@vger.kernel.org,
linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Grygorii Strashko
In-Reply-To: <1391608060-10760-3-git-send-email-ivan.khoronzhuk@ti.com>
On Wed, Feb 5, 2014 at 7:47 AM, Ivan Khoronzhuk <ivan.khoronzhuk@ti.com> wrote:
> This patch provides bindings for the 64-bit timer in the KeyStone
> architecture devices. The timer can be configured as a general-purpose 64-bit
> timer, dual general-purpose 32-bit timers. When configured as dual 32-bit
> timers, each half can operate in conjunction (chain mode) or independently
> (unchained mode) of each other.
This is software configurable or h/w design time configurations?
Rob
>
> It is global timer is a free running up-counter and can generate interrupt
> when the counter reaches preset counter values.
>
> Documentation:
> http://www.ti.com/lit/ug/sprugv5a/sprugv5a.pdf
>
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
> ---
> .../bindings/timer/ti,keystone-timer.txt | 29 ++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/timer/ti,keystone-timer.txt
>
> diff --git a/Documentation/devicetree/bindings/timer/ti,keystone-timer.txt b/Documentation/devicetree/bindings/timer/ti,keystone-timer.txt
> new file mode 100644
> index 0000000..5fbe361
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/ti,keystone-timer.txt
> @@ -0,0 +1,29 @@
> +* Device tree bindings for Texas instruments Keystone timer
> +
> +This document provides bindings for the 64-bit timer in the KeyStone
> +architecture devices. The timer can be configured as a general-purpose 64-bit
> +timer, dual general-purpose 32-bit timers. When configured as dual 32-bit
> +timers, each half can operate in conjunction (chain mode) or independently
> +(unchained mode) of each other.
> +
> +It is global timer is a free running up-counter and can generate interrupt
> +when the counter reaches preset counter values.
> +
> +Documentation:
> +http://www.ti.com/lit/ug/sprugv5a/sprugv5a.pdf
> +
> +Required properties:
> +
> +- compatible : should be "ti,keystone-timer".
> +- reg : specifies base physical address and count of the registers.
> +- interrupts : interrupt generated by the timer.
> +- clocks : the clock feeding the timer clock.
> +
> +Example:
> +
> +timer@22f0000 {
> + compatible = "ti,keystone-timer";
> + reg = <0x022f0000 0x80>;
> + interrupts = <GIC_SPI 110 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&clktimer15>;
> +};
> --
> 1.8.3.2
>
^ permalink raw reply
* Re: [PATCH RESEND] ARM: dts: add BeagleBone Audio Cape (Rev A) dtsi
From: Matt Porter @ 2014-02-05 14:38 UTC (permalink / raw)
To: Nishanth Menon
Cc: Jack Mitchell, bcousson-rdvid1DuHRBWk0Htik3J/w,
tony-4v6yS6AI5VpBDgjK7y7TUQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, linux-lFZ/pmaqli7XmaaqVzeoHQ,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jack Mitchell
In-Reply-To: <52F2460C.3080908-l0cyMroinI0@public.gmane.org>
On Wed, Feb 05, 2014 at 08:09:16AM -0600, Nishanth Menon wrote:
> On 02/05/2014 07:48 AM, Jack Mitchell wrote:
> > From: Jack Mitchell <jack-psbXN780rFT10XsdtD+oqA@public.gmane.org>
> >
> > Devicetree include file for setting up the am335x mcasp bus, i2c-2
> > bus, and audio codec required for a functioning BeagleBone Audio Cape.
> >
> > Signed-off-by: Jack Mitchell <jack-psbXN780rFT10XsdtD+oqA@public.gmane.org>
> > Signed-off-by: Matt Porter <mporter-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > ---
> > arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi | 124 +++++++++++++++++++++
> > arch/arm/boot/dts/am335x-bone-common.dtsi | 14 +++
> > 2 files changed, 138 insertions(+)
> > create mode 100644 arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi
> >
> > diff --git a/arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi b/arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi
> > new file mode 100644
> > index 0000000..b8ec3dc
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi
> > @@ -0,0 +1,124 @@
> > +/*
> > + * Copyright (C) 2014 Jack Mitchell <jack-psbXN780rFT10XsdtD+oqA@public.gmane.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * In order to enable the BeagleBone Audio Cape this dtsi must be
> > + * incuded in the top level dts. On BeagleBone Black hardware the
> > + * status of the HDMI dts node must also be set to "disabled".
> > + *
> > + * --- a/arch/arm/boot/dts/am335x-bone.dts
> > + * +++ b/arch/arm/boot/dts/am335x-bone.dts
> > + * @@ -9,6 +9,7 @@
> > + *
> > + * #include "am33xx.dtsi"
> > + * #include "am335x-bone-common.dtsi"
> > + * +#include "am335x-bone-audio-cape-reva.dtsi"
> > + *
> > + * &ldo3_reg {
> > + * regulator-min-microvolt = <1800000>;
> > + *
> > + * On BeagleBone Black hardware the status of the HDMI dts node must
> > + * also be set to "disabled"
> > + *
> > + * --- a/arch/arm/boot/dts/am335x-boneblack.dts
> > + * +++ b/arch/arm/boot/dts/am335x-boneblack.dts
> > + * @@ -73,6 +74,6 @@
> > + * pinctrl-names = "default", "off";
> > + * pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
> > + * pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
> > + * - status = "okay";
> > + * + status = "disabled";
> > + * };
> > + * };
> > + */
> > +
> how about making the audio-cape-reva.dts which includes and overrides
> parameters of boneblack.dts?
Yeah, that might be a little cleaner. Black makes things unfortunately
messy for these capes that were really intended for BBW :(
> Further, I see a bunch of capes in
> http://elinux.org/Beagleboard:BeagleBone_Capes
>
> Assuming that we dont want to discuss capebus all over again, is this
> the approach we'd like to consider in the interim?
I think that's a fair assumption...I'll note that there is work slowly
in progress on a very minimal implementation DT overlays upstream. But
that doesn't exist. We are simply interested in a sane way to use the
hardware we own in mainline and this approach makes it possible to build
a kernel+dtb from mainline that works for this configuration. If
there's a better way to support this hardware *today* let's discuss it.
One of the big benefits to having this upstream is that it's no longer
out of sight out of mind. It should be managed alongside all the other
am335x dts data.
Incidentally, I'm hoping to contribute a similar patch for the DVI cape
I have here.
-Matt
--
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] mmc: omap_hsmmc: Add support for Erratum 2.1.1.128 in device tree boot
From: Nishanth Menon @ 2014-02-05 14:12 UTC (permalink / raw)
To: Balaji T K
Cc: devicetree, Tony Lindgren, linux-mmc, Chris Ball, linux-omap,
linux-arm-kernel
In-Reply-To: <52F2465A.6060804@ti.com>
On Wed 05 Feb 2014 08:10:34 AM CST, Balaji T K wrote:
> On Tuesday 04 February 2014 08:48 PM, Nishanth Menon wrote:
>> On 02/04/2014 06:44 AM, Balaji T K wrote:
>>> On Tuesday 21 January 2014 04:59 AM, Nishanth Menon wrote:
>>>> When device is booted using devicetree, platforms impacted by
>>>> Erratum 2.1.1.128 is not detected easily in the mmc driver. This erratum
>>>> indicates that the module cannot do multi-block transfers.
>>>>
>>>> Handle this by providing a boolean flag to indicate to driver that it is
>>>> working on a hardware with mentioned limitation.
>>>>
>>>> Signed-off-by: Nishanth Menon <nm@ti.com>
>>>> ---
>>>>
>>>> This explains the logs I see:
>>>> OMAP3430 LDP (ES2.2):
>>>> uImage only boot: http://slexy.org/raw/s2YrbMAi7c
>>>> uImage+dtb concatenated boot: http://slexy.org/raw/s20qVg17T0
>>>>
>>>> With the following flag set, device is now able to consistently boot with
>>>> device tree supported uImage+dtb concat boot.
>>>>
>>>> .../devicetree/bindings/mmc/ti-omap-hsmmc.txt | 2 ++
>>>> drivers/mmc/host/omap_hsmmc.c | 3 +++
>>>> 2 files changed, 5 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
>>>> index 8c8908a..ab36f8b 100644
>>>> --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
>>>> +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
>>>> @@ -26,6 +26,8 @@ specifier is required.
>>>> dma-names: List of DMA request names. These strings correspond
>>>> 1:1 with the DMA specifiers listed in dmas. The string naming is
>>>> to be "rx" and "tx" for RX and TX DMA requests, respectively.
>>>> +ti,erratum-2.1.1.128: boolean, for OMAP3430/OMAP35xx platforms with broken
>>>> +multiblock reads
>>>
>>> Rather than ti,errata.. specific property, something like
>>> caps no/disable multiblock read is more readable in my opinion, Otherwise
>>
>> Is'nt the better definition to state i have quirk X and allow the
>> driver to do the necessary thing/things needed to handle quirk X? in
>> this case, there is just one thing to do: broken multi_block_read, in
>> the case of other quirks, there might be more than 1 thing to do.. let
>> driver figure that out, dts just states the h/w capabilty or in this
>> case, the quirk capability.
>>
>
> But in this case there is only one. disable multi block read is more readable
> than the errata reference, No strong feelings though.
Considering this might set an precedence for other quirk description,
I'd like to leave it as it stands.
--
Regards,
Nishanth Menon
^ permalink raw reply
* Re: [PATCH V5 2/4] DRIVERS: IRQCHIP: CROSSBAR: Add support for Crossbar IP
From: Sricharan R @ 2014-02-05 14:11 UTC (permalink / raw)
To: Thomas Gleixner
Cc: linux-kernel, devicetree, linux-doc, linux-arm-kernel, linux-omap,
linus.walleij, linux, tony, rnayak, marc.zyngier, grant.likely,
mark.rutland, robherring2, galak, rob.herring, santosh.shilimkar,
nm, bcousson, Kevin Hilman
In-Reply-To: <52F23887.9060209@ti.com>
Tony,
On Wednesday 05 February 2014 06:41 PM, Sricharan R wrote:
> On Tuesday 04 February 2014 09:44 PM, Thomas Gleixner wrote:
>> On Mon, 3 Feb 2014, Sricharan R wrote:
>>>> I already have your reviewed-by tag for the first patch in this series.
>>>>
>>>> Kevin was pointing out that irqchip maintainer tag is needed for this patch as well
>>>> to be merged. We are planning to take this series through arm-soc tree.
>>>>
>>>> Can i please have your tag for this patch as well ?
>>
>> Acked-by-me
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> Thanks Thomas.
>
> Kevin,
> I will re-send a branch based on rc1 for this.
>
I have pushed a branch based on mainline,
git://github.com/Sricharanti/sricharan.git
branch: crossbar_3.14_rc1
Regards,
Sricharan
^ permalink raw reply
* Re: [PATCH] mmc: omap_hsmmc: Add support for Erratum 2.1.1.128 in device tree boot
From: Balaji T K @ 2014-02-05 14:10 UTC (permalink / raw)
To: Nishanth Menon
Cc: Chris Ball, Tony Lindgren, devicetree, linux-mmc, linux-omap,
linux-arm-kernel
In-Reply-To: <52F104B7.6040606@ti.com>
On Tuesday 04 February 2014 08:48 PM, Nishanth Menon wrote:
> On 02/04/2014 06:44 AM, Balaji T K wrote:
>> On Tuesday 21 January 2014 04:59 AM, Nishanth Menon wrote:
>>> When device is booted using devicetree, platforms impacted by
>>> Erratum 2.1.1.128 is not detected easily in the mmc driver. This erratum
>>> indicates that the module cannot do multi-block transfers.
>>>
>>> Handle this by providing a boolean flag to indicate to driver that it is
>>> working on a hardware with mentioned limitation.
>>>
>>> Signed-off-by: Nishanth Menon <nm@ti.com>
>>> ---
>>>
>>> This explains the logs I see:
>>> OMAP3430 LDP (ES2.2):
>>> uImage only boot: http://slexy.org/raw/s2YrbMAi7c
>>> uImage+dtb concatenated boot: http://slexy.org/raw/s20qVg17T0
>>>
>>> With the following flag set, device is now able to consistently boot with
>>> device tree supported uImage+dtb concat boot.
>>>
>>> .../devicetree/bindings/mmc/ti-omap-hsmmc.txt | 2 ++
>>> drivers/mmc/host/omap_hsmmc.c | 3 +++
>>> 2 files changed, 5 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
>>> index 8c8908a..ab36f8b 100644
>>> --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
>>> +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
>>> @@ -26,6 +26,8 @@ specifier is required.
>>> dma-names: List of DMA request names. These strings correspond
>>> 1:1 with the DMA specifiers listed in dmas. The string naming is
>>> to be "rx" and "tx" for RX and TX DMA requests, respectively.
>>> +ti,erratum-2.1.1.128: boolean, for OMAP3430/OMAP35xx platforms with broken
>>> +multiblock reads
>>
>> Rather than ti,errata.. specific property, something like
>> caps no/disable multiblock read is more readable in my opinion, Otherwise
>
> Is'nt the better definition to state i have quirk X and allow the
> driver to do the necessary thing/things needed to handle quirk X? in
> this case, there is just one thing to do: broken multi_block_read, in
> the case of other quirks, there might be more than 1 thing to do.. let
> driver figure that out, dts just states the h/w capabilty or in this
> case, the quirk capability.
>
But in this case there is only one. disable multi block read is more readable
than the errata reference, No strong feelings though.
>>
>> Acked-by: Balaji T K <balajitk@ti.com>
>>
>>>
>>> Examples:
>>>
>>> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
>>> index 014bfe5..f2d5940 100644
>>> --- a/drivers/mmc/host/omap_hsmmc.c
>>> +++ b/drivers/mmc/host/omap_hsmmc.c
>>> @@ -1730,6 +1730,9 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
>>> if (of_find_property(np, "ti,dual-volt", NULL))
>>> pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT;
>>>
>>> + if (of_find_property(np, "ti,erratum-2.1.1.128", NULL))
>>> + pdata->controller_flags |= OMAP_HSMMC_BROKEN_MULTIBLOCK_READ;
>>> +
>>> /* This driver only supports 1 slot */
>>> pdata->nr_slots = 1;
>>> pdata->slots[0].switch_pin = cd_gpio;
>>>
>>
>
>
^ permalink raw reply
* Re: [PATCH RESEND] ARM: dts: add BeagleBone Audio Cape (Rev A) dtsi
From: Nishanth Menon @ 2014-02-05 14:09 UTC (permalink / raw)
To: Jack Mitchell, bcousson, tony, robh+dt, pawel.moll, mark.rutland,
ijc+devicetree, galak, linux
Cc: linux-omap, devicetree, linux-arm-kernel, linux-kernel,
Jack Mitchell, Matt Porter
In-Reply-To: <1391608084-12665-1-git-send-email-ml@embed.me.uk>
On 02/05/2014 07:48 AM, Jack Mitchell wrote:
> From: Jack Mitchell <jack@embed.me.uk>
>
> Devicetree include file for setting up the am335x mcasp bus, i2c-2
> bus, and audio codec required for a functioning BeagleBone Audio Cape.
>
> Signed-off-by: Jack Mitchell <jack@embed.me.uk>
> Signed-off-by: Matt Porter <mporter@linaro.org>
> ---
> arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi | 124 +++++++++++++++++++++
> arch/arm/boot/dts/am335x-bone-common.dtsi | 14 +++
> 2 files changed, 138 insertions(+)
> create mode 100644 arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi
>
> diff --git a/arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi b/arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi
> new file mode 100644
> index 0000000..b8ec3dc
> --- /dev/null
> +++ b/arch/arm/boot/dts/am335x-bone-audio-cape-reva.dtsi
> @@ -0,0 +1,124 @@
> +/*
> + * Copyright (C) 2014 Jack Mitchell <jack@embed.me.uk>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * In order to enable the BeagleBone Audio Cape this dtsi must be
> + * incuded in the top level dts. On BeagleBone Black hardware the
> + * status of the HDMI dts node must also be set to "disabled".
> + *
> + * --- a/arch/arm/boot/dts/am335x-bone.dts
> + * +++ b/arch/arm/boot/dts/am335x-bone.dts
> + * @@ -9,6 +9,7 @@
> + *
> + * #include "am33xx.dtsi"
> + * #include "am335x-bone-common.dtsi"
> + * +#include "am335x-bone-audio-cape-reva.dtsi"
> + *
> + * &ldo3_reg {
> + * regulator-min-microvolt = <1800000>;
> + *
> + * On BeagleBone Black hardware the status of the HDMI dts node must
> + * also be set to "disabled"
> + *
> + * --- a/arch/arm/boot/dts/am335x-boneblack.dts
> + * +++ b/arch/arm/boot/dts/am335x-boneblack.dts
> + * @@ -73,6 +74,6 @@
> + * pinctrl-names = "default", "off";
> + * pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
> + * pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
> + * - status = "okay";
> + * + status = "disabled";
> + * };
> + * };
> + */
> +
how about making the audio-cape-reva.dts which includes and overrides
parameters of boneblack.dts?
Further, I see a bunch of capes in
http://elinux.org/Beagleboard:BeagleBone_Capes
Assuming that we dont want to discuss capebus all over again, is this
the approach we'd like to consider in the interim?
> +/ {
> + sound {
> + compatible = "ti,da830-evm-audio";
> + ti,model = "AM335x BeagleBone Audio Cape Rev. A";
> + ti,audio-codec = <&tlv320aic3106>;
> + ti,mcasp-controller = <&mcasp0>;
> + ti,codec-clock-rate = <12000000>;
> + ti,audio-routing =
> + "Headphone Jack", "HPLOUT",
> + "Headphone Jack", "HPROUT",
> + "LINE1L", "Line In",
> + "LINE1R", "Line In";
> + };
> +
> + audio-cape-gpio-leds {
> + compatible = "gpio-leds";
> + pinctrl-names = "default";
> + pinctrl-0 = <&bone_audio_cape_led_pins>;
> +
> + audio-led0 {
> + label = "audio:green:usr0";
> + gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
> + linux,default-trigger = "heartbeat";
> + default-state = "off";
> + };
> +
> + audio-led1 {
> + label = "audio:green:usr1";
> + gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
> + linux,default-trigger = "mmc0";
> + default-state = "off";
> + };
> + };
> +};
> +
> +&am33xx_pinmux {
> + bone_audio_cape_led_pins: pinmux_bone_audio_cape_led_pins {
> + pinctrl-single,pins = <
> + 0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a2.gpio1_18 */
> + 0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a3.gpio1_19 */
> + >;
> + };
> +
> + bone_audio_cape_pins: bone_audio_cape_pins {
> + pinctrl-single,pins = <
> + 0x190 (PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */
> + 0x194 (PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */
> + 0x19c (PIN_INPUT_PULLUP | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2 */
> + 0x1ac (PIN_INPUT_PULLUP | MUX_MODE2) /* mcasp0_ahclkx.mcasp0_axr3 */
> + >;
> + };
> +};
> +
> +&i2c2 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c2_pins>;
> +
> + status = "okay";
> + clock-frequency = <100000>;
> +
> + tlv320aic3106: tlv320aic3106@1b {
> + compatible = "ti,tlv320aic3106";
> + reg = <0x1b>;
> + status = "okay";
> +
> + /* Regulators */
> + AVDD-supply = <&vmmcsd_fixed>;
> + IOVDD-supply = <&vmmcsd_fixed>;
> + DRVDD-supply = <&vmmcsd_fixed>;
> + DVDD-supply = <&vdd1v8_fixed>;
> + };
> +};
> +
> +&mcasp0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&bone_audio_cape_pins>;
> +
> + status = "okay";
> +
> + op-mode = <0>; /* MCASP_IIS_MODE */
> + tdm-slots = <2>;
> + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
> + 0 0 2 1
> + >;
> + tx-num-evt = <1>;
> + rx-num-evt = <1>;
> +};
> diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
> index e3f27ec..c1c0f74 100644
> --- a/arch/arm/boot/dts/am335x-bone-common.dtsi
> +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
> @@ -62,12 +62,26 @@
> regulator-min-microvolt = <3300000>;
> regulator-max-microvolt = <3300000>;
> };
> +
> + vdd1v8_fixed: fixedregulator@1 {
> + compatible = "regulator-fixed";
> + regulator-name = "vdd1v8_fixed";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> };
>
> &am33xx_pinmux {
> pinctrl-names = "default";
> pinctrl-0 = <&clkout2_pin>;
>
> + i2c2_pins: pinmux_i2c2_pins {
> + pinctrl-single,pins = <
> + 0x178 (PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_ctsn.i2c2_sda */
> + 0x17c (PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_rtsn.i2c2_scl */
> + >;
> + };
> +
> user_leds_s0: user_leds_s0 {
> pinctrl-single,pins = <
> 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
>
--
Regards,
Nishanth Menon
^ permalink raw reply
* Re: [PATCH 09/10] watchdog: xilinx: Add missing binding
From: Arnd Bergmann @ 2014-02-05 14:00 UTC (permalink / raw)
To: monstr
Cc: Mark Rutland, devicetree, Pawel Moll, linux-doc, Ian Campbell,
Michal Simek, linux-kernel, Rob Herring, Rob Landley, Kumar Gala,
linux-arm-kernel
In-Reply-To: <52F20732.6070209@monstr.eu>
On Wednesday 05 February 2014, Michal Simek wrote:
> On 02/05/2014 10:36 AM, Arnd Bergmann wrote:
> > On Wednesday 05 February 2014, Michal Simek wrote:
> > Still, the choice of putting the timeout into DT in terms of
> > cycles rather than miliseconds wasn't ideal from an interface
> > perspective and we should change that if/when we do a generic
> > binding. I can definitely see where it's coming from for your
> > case, as the cycle count totally makes sense from an FPGA
> > tool perspective...
>
> Thanks. I take this like ACK for this current binding description.
>
Yes, please add my 'Acked-by'.
Arnd
^ permalink raw reply
* [PATCH v3 7/7] ARM: dts: sun5i: Add support for mmc
From: David Lanzendörfer @ 2014-02-05 13:55 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Simon Baatz, Hans de Goede, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo, Maxime Ripard,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20140205134741.3027.50207.stgit-GPtPHOohwllnsqa/0SyWJQ@public.gmane.org>
Signed-off-by: David Lanzendörfer <david.lanzendoerfer-Z7Kmv9EsliU@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 30 +++++++++++++++
arch/arm/boot/dts/sun5i-a10s.dtsi | 44 ++++++++++++++++++++++
arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts | 15 ++++++++
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 15 ++++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 37 +++++++++++++++++++
5 files changed, 141 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index 3c9f8b3..7189adf55 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -34,7 +34,37 @@
};
};
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_olinuxino_micro>;
+ cd-gpios = <&pio 6 1 0>; /* PG1 */
+ status = "okay";
+ };
+
+ mmc1: mmc@01c10000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc1_pins_a>;
+ pinctrl-1 = <&mmc1_cd_pin_olinuxino_micro>;
+ cd-gpios = <&pio 6 13 0>; /* PG13 */
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxino_micro: mmc0_cd_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ mmc1_cd_pin_olinuxino_micro: mmc1_cd_pin@0 {
+ allwinner,pins = "PG13";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PE3";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index ea16054..abff7f8 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -293,6 +293,36 @@
#size-cells = <0>;
};
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>, <&mmc0_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <32>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb_gates 9>, <&mmc1_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <33>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb_gates 10>, <&mmc2_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <34>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-ic";
reg = <0x01c20400 0x400>;
@@ -363,6 +393,20 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <3>;
+ allwinner,pull = <0>;
+ };
+
+ mmc1_pins_a: mmc1@0 {
+ allwinner,pins = "PG3","PG4","PG5","PG6","PG7","PG8";
+ allwinner,function = "mmc1";
+ allwinner,drive = <3>;
+ allwinner,pull = <0>;
+ };
};
timer@01c20c00 {
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
index fe2ce0a..6ae5867 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
@@ -20,7 +20,22 @@
compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_olinuxinom>;
+ cd-gpios = <&pio 6 0 0>; /* PG0 */
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_olinuxinom: led_pins@0 {
allwinner,pins = "PG9";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index a4ba5ff..b23237b 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -19,7 +19,22 @@
compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13";
soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_olinuxino>;
+ cd-gpios = <&pio 6 0 0>; /* PG0 */
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxino: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PG9";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 320335a..5d71c82 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -274,6 +274,36 @@
#size-cells = <1>;
ranges;
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>, <&mmc0_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <32>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb_gates 9>, <&mmc1_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <33>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb_gates 10>, <&mmc2_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <34>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-ic";
reg = <0x01c20400 0x400>;
@@ -326,6 +356,13 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <3>;
+ allwinner,pull = <0>;
+ };
};
timer@01c20c00 {
--
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/groups/opt_out.
^ permalink raw reply related
* [PATCH v3 6/7] ARM: dts: sun4i: Add support for mmc
From: David Lanzendörfer @ 2014-02-05 13:54 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Simon Baatz, Hans de Goede, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo, Maxime Ripard,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20140205134741.3027.50207.stgit-GPtPHOohwllnsqa/0SyWJQ@public.gmane.org>
Signed-off-by: David Lanzendörfer <david.lanzendoerfer-Z7Kmv9EsliU@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun4i-a10-a1000.dts | 8 ++++
arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 8 ++++
arch/arm/boot/dts/sun4i-a10.dtsi | 54 ++++++++++++++++++++++++++++
3 files changed, 70 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
index d4b081d..a879ef3 100644
--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -35,6 +35,14 @@
};
};
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_reference_design>;
+ cd-gpios = <&pio 7 1 0>; /* PH1 */
+ status = "okay";
+ };
+
pinctrl@01c20800 {
emac_power_pin_a1000: emac_power_pin@0 {
allwinner,pins = "PH15";
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index b139ee6..20b976a 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -33,6 +33,14 @@
};
};
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_reference_design>;
+ cd-gpios = <&pio 7 1 0>; /* PH1 */
+ status = "okay";
+ };
+
pinctrl@01c20800 {
led_pins_cubieboard: led_pins@0 {
allwinner,pins = "PH20", "PH21";
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 040bb0e..c941ca3 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -330,6 +330,46 @@
#size-cells = <0>;
};
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>, <&mmc0_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <32>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb_gates 9>, <&mmc1_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <33>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb_gates 10>, <&mmc2_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <34>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@01c12000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c12000 0x1000>;
+ clocks = <&ahb_gates 11>, <&mmc3_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <35>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-ic";
reg = <0x01c20400 0x400>;
@@ -400,6 +440,20 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <3>;
+ allwinner,pull = <0>;
+ };
+
+ mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
};
timer@01c20c00 {
--
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/groups/opt_out.
^ permalink raw reply related
* [PATCH v3 5/7] ARM: dts: sun7i: Add support for mmc
From: David Lanzendörfer @ 2014-02-05 13:54 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Simon Baatz, Hans de Goede, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo, Maxime Ripard,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20140205134741.3027.50207.stgit-GPtPHOohwllnsqa/0SyWJQ@public.gmane.org>
Signed-off-by: David Lanzendörfer <david.lanzendoerfer-Z7Kmv9EsliU@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 8 +++
arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 8 +++
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 23 +++++++++
arch/arm/boot/dts/sun7i-a20.dtsi | 61 +++++++++++++++++++++++
4 files changed, 100 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 5c51cb8..ae800b6 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -34,6 +34,14 @@
};
};
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_reference_design>;
+ cd-gpios = <&pio 7 1 0>; /* PH1 */
+ status = "okay";
+ };
+
pinctrl@01c20800 {
led_pins_cubieboard2: led_pins@0 {
allwinner,pins = "PH20", "PH21";
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index f9dcb61..370cef84 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -19,6 +19,14 @@
compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
soc@01c00000 {
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_reference_design>;
+ cd-gpios = <&pio 7 1 0>; /* PH1 */
+ status = "okay";
+ };
+
pinctrl@01c20800 {
led_pins_cubietruck: led_pins@0 {
allwinner,pins = "PH7", "PH11", "PH20", "PH21";
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index ead3013..46dbe5b 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -34,7 +34,30 @@
};
};
+ mmc0: mmc@01c0f000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_reference_design>;
+ cd-gpios = <&pio 7 1 0>; /* PH1 */
+ status = "okay";
+ };
+
+ mmc3: mmc@01c12000 {
+ pinctrl-names = "default", "default";
+ pinctrl-0 = <&mmc3_pins_a>;
+ pinctrl-1 = <&mmc3_cd_pin_olinuxinom>;
+ cd-gpios = <&pio 7 11 0>; /* PH11 */
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc3_cd_pin_olinuxinom: mmc3_cd_pin@0 {
+ allwinner,pins = "PH11";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 119f066..4cd6210 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -355,6 +355,46 @@
#size-cells = <0>;
};
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>, <&mmc0_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <0 32 4>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb_gates 9>, <&mmc1_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <0 33 4>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&ahb_gates 10>, <&mmc2_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <0 34 4>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@01c12000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c12000 0x1000>;
+ clocks = <&ahb_gates 11>, <&mmc3_clk>;
+ clock-names = "ahb", "mod";
+ interrupts = <0 35 4>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
pio: pinctrl@01c20800 {
compatible = "allwinner,sun7i-a20-pinctrl";
reg = <0x01c20800 0x400>;
@@ -432,6 +472,27 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ mmc0_pins_a: mmc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <3>;
+ allwinner,pull = <0>;
+ };
+
+ mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ mmc3_pins_a: mmc3@0 {
+ allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9";
+ allwinner,function = "mmc3";
+ allwinner,drive = <3>;
+ allwinner,pull = <0>;
+ };
};
timer@01c20c00 {
--
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/groups/opt_out.
^ permalink raw reply related
* [PATCH v3 4/7] ARM: sunxi: Add driver for SD/MMC hosts found on Allwinner sunxi SoCs
From: David Lanzendörfer @ 2014-02-05 13:54 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Simon Baatz, Hans de Goede, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo, Maxime Ripard,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20140205134741.3027.50207.stgit-GPtPHOohwllnsqa/0SyWJQ@public.gmane.org>
This is based on the driver Allwinner ships in their Android kernel sources.
Initial porting to upstream kernels done by David Lanzendörfer, additional
fixes and cleanups by Hans de Goede.
It uses dma in bus-master mode using a built-in designware idmac controller,
which is identical to the one found in the mmc-dw hosts.
The rest of the host is not identical to mmc-dw.
Signed-off-by: David Lanzendörfer <david.lanzendoerfer-Z7Kmv9EsliU@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/mmc/host/Kconfig | 7
drivers/mmc/host/Makefile | 2
drivers/mmc/host/sunxi-mci.c | 859 ++++++++++++++++++++++++++++++++++++++++++
drivers/mmc/host/sunxi-mci.h | 239 ++++++++++++
4 files changed, 1107 insertions(+)
create mode 100644 drivers/mmc/host/sunxi-mci.c
create mode 100644 drivers/mmc/host/sunxi-mci.h
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 1384f67..7caf266 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -689,3 +689,10 @@ config MMC_REALTEK_PCI
help
Say Y here to include driver code to support SD/MMC card interface
of Realtek PCI-E card reader
+
+config MMC_SUNXI
+ tristate "Allwinner sunxi SD/MMC Host Controller support"
+ depends on ARCH_SUNXI
+ help
+ This selects support for the SD/MMC Host Controller on
+ Allwinner sunxi SoCs.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 3483b6b..6c9cbd3 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -54,6 +54,8 @@ obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o
obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o
+obj-$(CONFIG_MMC_SUNXI) += sunxi-mci.o
+
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
diff --git a/drivers/mmc/host/sunxi-mci.c b/drivers/mmc/host/sunxi-mci.c
new file mode 100644
index 0000000..627d0ee
--- /dev/null
+++ b/drivers/mmc/host/sunxi-mci.c
@@ -0,0 +1,859 @@
+/*
+ * Driver for sunxi SD/MMC host controllers
+ * (C) Copyright 2014-2015 Reuuimlla Technology Co., Ltd.
+ * (C) Copyright 2014-2015 Aaron Maoye <leafy.myeh-jFKXxz0WcGyYHARAtoI1EgC/G2K4zDHf@public.gmane.org>
+ * (C) Copyright 2014-2015 O2S GmbH <www.o2s.ch>
+ * (C) Copyright 2014-2015 David Lanzendörfer <david.lanzendoerfer@o2s.ch>
+ * (C) Copyright 2014-2015 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#include <linux/clk.h>
+#include <linux/clk-private.h>
+#include <linux/clk/sunxi.h>
+
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/slot-gpio.h>
+
+#include "sunxi-mci.h"
+
+static void sunxi_mmc_init_host(struct mmc_host *mmc)
+{
+ u32 rval;
+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc);
+
+ /* reset controller */
+ rval = mci_readl(smc_host, REG_GCTRL) | SDXC_HWReset;
+ mci_writel(smc_host, REG_GCTRL, rval);
+
+ mci_writel(smc_host, REG_FTRGL, 0x20070008);
+ mci_writel(smc_host, REG_TMOUT, 0xffffffff);
+ mci_writel(smc_host, REG_IMASK, smc_host->sdio_imask);
+ mci_writel(smc_host, REG_RINTR, 0xffffffff);
+ mci_writel(smc_host, REG_DBGC, 0xdeb);
+ mci_writel(smc_host, REG_FUNS, 0xceaa0000);
+ mci_writel(smc_host, REG_DLBA, smc_host->sg_dma);
+ rval = mci_readl(smc_host, REG_GCTRL)|SDXC_INTEnb;
+ rval &= ~SDXC_AccessDoneDirect;
+ mci_writel(smc_host, REG_GCTRL, rval);
+}
+
+static void sunxi_mmc_exit_host(struct sunxi_mmc_host *smc_host)
+{
+ mci_writel(smc_host, REG_GCTRL, SDXC_HWReset);
+}
+
+/* /\* UHS-I Operation Modes */
+/* * DS 25MHz 12.5MB/s 3.3V */
+/* * HS 50MHz 25MB/s 3.3V */
+/* * SDR12 25MHz 12.5MB/s 1.8V */
+/* * SDR25 50MHz 25MB/s 1.8V */
+/* * SDR50 100MHz 50MB/s 1.8V */
+/* * SDR104 208MHz 104MB/s 1.8V */
+/* * DDR50 50MHz 50MB/s 1.8V */
+/* * MMC Operation Modes */
+/* * DS 26MHz 26MB/s 3/1.8/1.2V */
+/* * HS 52MHz 52MB/s 3/1.8/1.2V */
+/* * HSDDR 52MHz 104MB/s 3/1.8/1.2V */
+/* * HS200 200MHz 200MB/s 1.8/1.2V */
+/* * */
+/* * Spec. Timing */
+/* * SD3.0 */
+/* * Fcclk Tcclk Fsclk Tsclk Tis Tih odly RTis RTih */
+/* * 400K 2.5us 24M 41ns 5ns 5ns 1 2209ns 41ns */
+/* * 25M 40ns 600M 1.67ns 5ns 5ns 3 14.99ns 5.01ns */
+/* * 50M 20ns 600M 1.67ns 6ns 2ns 3 14.99ns 5.01ns */
+/* * 50MDDR 20ns 600M 1.67ns 6ns 0.8ns 2 6.67ns 3.33ns */
+/* * 104M 9.6ns 600M 1.67ns 3ns 0.8ns 1 7.93ns 1.67ns */
+/* * 208M 4.8ns 600M 1.67ns 1.4ns 0.8ns 1 3.33ns 1.67ns */
+
+/* * 25M 40ns 300M 3.33ns 5ns 5ns 2 13.34ns 6.66ns */
+/* * 50M 20ns 300M 3.33ns 6ns 2ns 2 13.34ns 6.66ns */
+/* * 50MDDR 20ns 300M 3.33ns 6ns 0.8ns 1 6.67ns 3.33ns */
+/* * 104M 9.6ns 300M 3.33ns 3ns 0.8ns 0 7.93ns 1.67ns */
+/* * 208M 4.8ns 300M 3.33ns 1.4ns 0.8ns 0 3.13ns 1.67ns */
+
+/* * eMMC4.5 */
+/* * 400K 2.5us 24M 41ns 3ns 3ns 1 2209ns 41ns */
+/* * 25M 40ns 600M 1.67ns 3ns 3ns 3 14.99ns 5.01ns */
+/* * 50M 20ns 600M 1.67ns 3ns 3ns 3 14.99ns 5.01ns */
+/* * 50MDDR 20ns 600M 1.67ns 2.5ns 2.5ns 2 6.67ns 3.33ns */
+/* * 200M 5ns 600M 1.67ns 1.4ns 0.8ns 1 3.33ns 1.67ns */
+/* *\/ */
+
+static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host,
+ struct mmc_data *data)
+{
+ struct sunxi_idma_des *pdes = (struct sunxi_idma_des *)host->sg_cpu;
+ struct sunxi_idma_des *pdes_pa = (struct sunxi_idma_des *)host->sg_dma;
+ int i, max_len = (1 << host->idma_des_size_bits);
+
+ for (i = 0; i < data->sg_len; i++) {
+ pdes[i].config = SDXC_IDMAC_DES0_CH | SDXC_IDMAC_DES0_OWN |
+ SDXC_IDMAC_DES0_DIC;
+
+ if (data->sg[i].length == max_len)
+ pdes[i].buf_size = 0; /* 0 == max_len */
+ else
+ pdes[i].buf_size = data->sg[i].length;
+
+ pdes[i].buf_addr_ptr1 = sg_dma_address(&data->sg[i]);
+ pdes[i].buf_addr_ptr2 = (u32)&pdes_pa[i + 1];
+ }
+
+ pdes[0].config |= SDXC_IDMAC_DES0_FD;
+ pdes[i - 1].config = SDXC_IDMAC_DES0_OWN | SDXC_IDMAC_DES0_LD;
+
+ wmb(); /* Ensure idma_des hit main mem before we start the idmac */
+}
+
+static enum dma_data_direction sunxi_mmc_get_dma_dir(struct mmc_data *data)
+{
+ if (data->flags & MMC_DATA_WRITE)
+ return DMA_TO_DEVICE;
+ else
+ return DMA_FROM_DEVICE;
+}
+
+static int sunxi_mmc_prepare_dma(struct sunxi_mmc_host *smc_host,
+ struct mmc_data *data)
+{
+ u32 dma_len;
+ u32 i;
+ u32 temp;
+ struct scatterlist *sg;
+
+ dma_len = dma_map_sg(mmc_dev(smc_host->mmc), data->sg, data->sg_len,
+ sunxi_mmc_get_dma_dir(data));
+ if (dma_len == 0) {
+ dev_err(mmc_dev(smc_host->mmc), "dma_map_sg failed\n");
+ return -ENOMEM;
+ }
+
+ for_each_sg(data->sg, sg, data->sg_len, i) {
+ if (sg->offset & 3 || sg->length & 3) {
+ dev_err(mmc_dev(smc_host->mmc),
+ "unaligned scatterlist: os %x length %d\n",
+ sg->offset, sg->length);
+ return -EINVAL;
+ }
+ }
+
+ sunxi_mmc_init_idma_des(smc_host, data);
+
+ temp = mci_readl(smc_host, REG_GCTRL);
+ temp |= SDXC_DMAEnb;
+ mci_writel(smc_host, REG_GCTRL, temp);
+ temp |= SDXC_DMAReset;
+ mci_writel(smc_host, REG_GCTRL, temp);
+ mci_writel(smc_host, REG_DMAC, SDXC_IDMACSoftRST);
+
+ if (!(data->flags & MMC_DATA_WRITE))
+ mci_writel(smc_host, REG_IDIE, SDXC_IDMACReceiveInt);
+
+ mci_writel(smc_host, REG_DMAC, SDXC_IDMACFixBurst | SDXC_IDMACIDMAOn);
+
+ return 0;
+}
+
+static void sunxi_mmc_send_manual_stop(struct sunxi_mmc_host *host,
+ struct mmc_request *req)
+{
+ u32 cmd_val = SDXC_Start | SDXC_RspExp | SDXC_StopAbortCMD
+ | SDXC_CheckRspCRC | MMC_STOP_TRANSMISSION;
+ u32 ri = 0;
+ unsigned long expire = jiffies + msecs_to_jiffies(1000);
+
+ mci_writel(host, REG_CARG, 0);
+ mci_writel(host, REG_CMDR, cmd_val);
+
+ do {
+ ri = mci_readl(host, REG_RINTR);
+ } while (!(ri & (SDXC_CmdDone | SDXC_IntErrBit)) &&
+ time_before(jiffies, expire));
+
+ if (ri & SDXC_IntErrBit) {
+ dev_err(mmc_dev(host->mmc), "send stop command failed\n");
+ if (req->stop)
+ req->stop->resp[0] = -ETIMEDOUT;
+ } else {
+ if (req->stop)
+ req->stop->resp[0] = mci_readl(host, REG_RESP0);
+ }
+
+ mci_writel(host, REG_RINTR, 0xffff);
+}
+
+static void sunxi_mmc_dump_errinfo(struct sunxi_mmc_host *smc_host)
+{
+ struct mmc_command *cmd = smc_host->mrq->cmd;
+ struct mmc_data *data = smc_host->mrq->data;
+
+ /* For some cmds timeout is normal with sd/mmc cards */
+ if ((smc_host->int_sum & SDXC_IntErrBit) == SDXC_RespTimeout &&
+ (cmd->opcode == 5 || cmd->opcode == 52))
+ return;
+
+ dev_err(mmc_dev(smc_host->mmc),
+ "smc %d err, cmd %d,%s%s%s%s%s%s%s%s%s%s !!\n",
+ smc_host->mmc->index, cmd->opcode,
+ data ? (data->flags & MMC_DATA_WRITE ? " WR" : " RD") : "",
+ smc_host->int_sum & SDXC_RespErr ? " RE" : "",
+ smc_host->int_sum & SDXC_RespCRCErr ? " RCE" : "",
+ smc_host->int_sum & SDXC_DataCRCErr ? " DCE" : "",
+ smc_host->int_sum & SDXC_RespTimeout ? " RTO" : "",
+ smc_host->int_sum & SDXC_DataTimeout ? " DTO" : "",
+ smc_host->int_sum & SDXC_FIFORunErr ? " FE" : "",
+ smc_host->int_sum & SDXC_HardWLocked ? " HL" : "",
+ smc_host->int_sum & SDXC_StartBitErr ? " SBE" : "",
+ smc_host->int_sum & SDXC_EndBitErr ? " EBE" : ""
+ );
+}
+
+static void sunxi_mmc_finalize_request(struct sunxi_mmc_host *host)
+{
+ struct mmc_request *mrq;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&host->lock, iflags);
+
+ mrq = host->mrq;
+ if (!mrq) {
+ spin_unlock_irqrestore(&host->lock, iflags);
+ dev_err(mmc_dev(host->mmc), "no request to finalize\n");
+ return;
+ }
+
+ if (host->int_sum & SDXC_IntErrBit) {
+ sunxi_mmc_dump_errinfo(host);
+ mrq->cmd->error = -ETIMEDOUT;
+ if (mrq->data)
+ mrq->data->error = -ETIMEDOUT;
+ if (mrq->stop)
+ mrq->stop->error = -ETIMEDOUT;
+ } else {
+ if (mrq->cmd->flags & MMC_RSP_136) {
+ mrq->cmd->resp[0] = mci_readl(host, REG_RESP3);
+ mrq->cmd->resp[1] = mci_readl(host, REG_RESP2);
+ mrq->cmd->resp[2] = mci_readl(host, REG_RESP1);
+ mrq->cmd->resp[3] = mci_readl(host, REG_RESP0);
+ } else {
+ mrq->cmd->resp[0] = mci_readl(host, REG_RESP0);
+ }
+ if (mrq->data)
+ mrq->data->bytes_xfered =
+ mrq->data->blocks * mrq->data->blksz;
+ }
+
+ if (mrq->data) {
+ struct mmc_data *data = mrq->data;
+ u32 temp;
+
+ mci_writel(host, REG_IDST, 0x337);
+ mci_writel(host, REG_DMAC, 0);
+ temp = mci_readl(host, REG_GCTRL);
+ mci_writel(host, REG_GCTRL, temp|SDXC_DMAReset);
+ temp &= ~SDXC_DMAEnb;
+ mci_writel(host, REG_GCTRL, temp);
+ temp |= SDXC_FIFOReset;
+ mci_writel(host, REG_GCTRL, temp);
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+ sunxi_mmc_get_dma_dir(data));
+ }
+
+ mci_writel(host, REG_RINTR, 0xffff);
+
+ dev_dbg(mmc_dev(host->mmc), "req done, resp %08x %08x %08x %08x\n",
+ mrq->cmd->resp[0], mrq->cmd->resp[1],
+ mrq->cmd->resp[2], mrq->cmd->resp[3]);
+
+ host->mrq = NULL;
+ host->int_sum = 0;
+ host->wait_dma = 0;
+
+ spin_unlock_irqrestore(&host->lock, iflags);
+
+ if (mrq->data && mrq->data->error) {
+ dev_err(mmc_dev(host->mmc),
+ "data error, sending stop command\n");
+ sunxi_mmc_send_manual_stop(host, mrq);
+ }
+
+ mmc_request_done(host->mmc, mrq);
+}
+
+static irqreturn_t sunxi_mmc_irq(int irq, void *dev_id)
+{
+ struct sunxi_mmc_host *host = dev_id;
+ u32 finalize = 0;
+ u32 sdio_int = 0;
+ u32 msk_int;
+ u32 idma_int;
+
+ spin_lock(&host->lock);
+
+ idma_int = mci_readl(host, REG_IDST);
+ msk_int = mci_readl(host, REG_MISTA);
+
+ dev_dbg(mmc_dev(host->mmc), "irq: rq %p mi %08x idi %08x\n",
+ host->mrq, msk_int, idma_int);
+
+ if (host->mrq) {
+ if (idma_int & SDXC_IDMACReceiveInt)
+ host->wait_dma = 0;
+
+ host->int_sum |= msk_int;
+
+ /* Wait for CmdDone on RespTimeout before finishing the req */
+ if ((host->int_sum & SDXC_RespTimeout) &&
+ !(host->int_sum & SDXC_CmdDone))
+ mci_writel(host, REG_IMASK,
+ host->sdio_imask | SDXC_CmdDone);
+ else if (host->int_sum & SDXC_IntErrBit)
+ finalize = 1; /* Don't wait for dma on error */
+ else if (host->int_sum & SDXC_IntDoneBit && !host->wait_dma)
+ finalize = 1; /* Done */
+
+ if (finalize) {
+ mci_writel(host, REG_IMASK, host->sdio_imask);
+ mci_writel(host, REG_IDIE, 0);
+ }
+ }
+
+ if (msk_int & SDXC_SDIOInt)
+ sdio_int = 1;
+
+ mci_writel(host, REG_RINTR, msk_int);
+ mci_writel(host, REG_IDST, idma_int);
+
+ spin_unlock(&host->lock);
+
+ if (finalize)
+ tasklet_schedule(&host->tasklet);
+
+ if (sdio_int)
+ mmc_signal_sdio_irq(host->mmc);
+
+ return IRQ_HANDLED;
+}
+
+static void sunxi_mmc_tasklet(unsigned long data)
+{
+ struct sunxi_mmc_host *smc_host = (struct sunxi_mmc_host *) data;
+ sunxi_mmc_finalize_request(smc_host);
+}
+
+static void sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
+{
+ unsigned long expire = jiffies + msecs_to_jiffies(2000);
+ u32 rval;
+
+ rval = mci_readl(host, REG_CLKCR);
+ rval &= ~(SDXC_CardClkOn | SDXC_LowPowerOn);
+
+ if (oclk_en)
+ rval |= SDXC_CardClkOn;
+
+ if (!host->io_flag)
+ rval |= SDXC_LowPowerOn;
+
+ mci_writel(host, REG_CLKCR, rval);
+
+ rval = SDXC_Start | SDXC_UPCLKOnly | SDXC_WaitPreOver;
+ if (host->voltage_switching)
+ rval |= SDXC_VolSwitch;
+ mci_writel(host, REG_CMDR, rval);
+
+ do {
+ rval = mci_readl(host, REG_CMDR);
+ } while (time_before(jiffies, expire) && (rval & SDXC_Start));
+
+ if (rval & SDXC_Start) {
+ dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n");
+ host->ferror = 1;
+ }
+}
+
+static void sunxi_mmc_set_clk_dly(struct sunxi_mmc_host *smc_host,
+ u32 oclk_dly, u32 sclk_dly)
+{
+ unsigned long iflags;
+ struct clk_hw *hw = __clk_get_hw(smc_host->clk_mod);
+
+ spin_lock_irqsave(&smc_host->lock, iflags);
+ clk_sunxi_mmc_phase_control(hw, sclk_dly, oclk_dly);
+ spin_unlock_irqrestore(&smc_host->lock, iflags);
+}
+
+struct sunxi_mmc_clk_dly mmc_clk_dly[MMC_CLK_MOD_NUM] = {
+ { MMC_CLK_400K, 0, 7 },
+ { MMC_CLK_25M, 0, 5 },
+ { MMC_CLK_50M, 3, 5 },
+ { MMC_CLK_50MDDR, 2, 4 },
+ { MMC_CLK_50MDDR_8BIT, 2, 4 },
+ { MMC_CLK_100M, 1, 4 },
+ { MMC_CLK_200M, 1, 4 },
+};
+
+static void sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *smc_host,
+ unsigned int rate)
+{
+ u32 newrate;
+ u32 src_clk;
+ u32 oclk_dly;
+ u32 sclk_dly;
+ u32 temp;
+ struct sunxi_mmc_clk_dly *dly = NULL;
+
+ newrate = clk_round_rate(smc_host->clk_mod, rate);
+ if (smc_host->clk_mod_rate == newrate) {
+ dev_dbg(mmc_dev(smc_host->mmc), "clk already %d, rounded %d\n",
+ rate, newrate);
+ return;
+ }
+
+ dev_dbg(mmc_dev(smc_host->mmc), "setting clk to %d, rounded %d\n",
+ rate, newrate);
+
+ /* setting clock rate */
+ clk_disable(smc_host->clk_mod);
+ clk_set_rate(smc_host->clk_mod, newrate);
+ clk_enable(smc_host->clk_mod);
+ smc_host->clk_mod_rate = newrate = clk_get_rate(smc_host->clk_mod);
+ dev_dbg(mmc_dev(smc_host->mmc), "clk is now %d\n", newrate);
+
+ sunxi_mmc_oclk_onoff(smc_host, 0);
+ /* clear internal divider */
+ temp = mci_readl(smc_host, REG_CLKCR);
+ temp &= ~0xff;
+ mci_writel(smc_host, REG_CLKCR, temp);
+
+ /* determine delays */
+ if (rate <= 400000) {
+ dly = &mmc_clk_dly[MMC_CLK_400K];
+ } else if (rate <= 25000000) {
+ dly = &mmc_clk_dly[MMC_CLK_25M];
+ } else if (rate <= 50000000) {
+ if (smc_host->ddr) {
+ if (smc_host->bus_width == 8)
+ dly = &mmc_clk_dly[MMC_CLK_50MDDR_8BIT];
+ else
+ dly = &mmc_clk_dly[MMC_CLK_50MDDR];
+ } else {
+ dly = &mmc_clk_dly[MMC_CLK_50M];
+ }
+ } else if (rate <= 104000000) {
+ dly = &mmc_clk_dly[MMC_CLK_100M];
+ } else if (rate <= 208000000) {
+ dly = &mmc_clk_dly[MMC_CLK_200M];
+ } else {
+ dly = &mmc_clk_dly[MMC_CLK_50M];
+ }
+
+ oclk_dly = dly->oclk_dly;
+ sclk_dly = dly->sclk_dly;
+
+ src_clk = clk_get_rate(clk_get_parent(smc_host->clk_mod));
+
+ if (src_clk >= 300000000 && src_clk <= 400000000) {
+ if (oclk_dly)
+ oclk_dly--;
+ if (sclk_dly)
+ sclk_dly--;
+ }
+
+ sunxi_mmc_set_clk_dly(smc_host, oclk_dly, sclk_dly);
+ sunxi_mmc_oclk_onoff(smc_host, 1);
+
+ /* oclk_onoff sets various irq status bits, clear these */
+ mci_writel(smc_host, REG_RINTR,
+ mci_readl(smc_host, REG_RINTR) & ~SDXC_SDIOInt);
+}
+
+static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct sunxi_mmc_host *host = mmc_priv(mmc);
+ u32 temp;
+ s32 err;
+
+ /* Set the power state */
+ switch (ios->power_mode) {
+ case MMC_POWER_ON:
+ break;
+
+ case MMC_POWER_UP:
+ if (!IS_ERR(host->vmmc)) {
+ mmc_regulator_set_ocr(host->mmc, host->vmmc, ios->vdd);
+ udelay(200);
+ }
+
+ err = clk_prepare_enable(host->clk_ahb);
+ if (err) {
+ dev_err(mmc_dev(host->mmc), "AHB clk err %d\n", err);
+ host->ferror = 1;
+ return;
+ }
+ err = clk_prepare_enable(host->clk_mod);
+ if (err) {
+ dev_err(mmc_dev(host->mmc), "MOD clk err %d\n", err);
+ clk_disable_unprepare(host->clk_ahb);
+ host->ferror = 1;
+ return;
+ }
+
+ sunxi_mmc_init_host(mmc);
+ enable_irq(host->irq);
+
+ dev_dbg(mmc_dev(host->mmc), "power on!\n");
+ host->ferror = 0;
+ break;
+
+ case MMC_POWER_OFF:
+ dev_dbg(mmc_dev(host->mmc), "power off!\n");
+ disable_irq(host->irq);
+ sunxi_mmc_exit_host(host);
+ clk_disable_unprepare(host->clk_ahb);
+ clk_disable_unprepare(host->clk_mod);
+ if (!IS_ERR(host->vmmc))
+ mmc_regulator_set_ocr(host->mmc, host->vmmc, 0);
+ host->ferror = 0;
+ break;
+ }
+
+ /* set bus width */
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_1:
+ mci_writel(host, REG_WIDTH, SDXC_WIDTH1);
+ host->bus_width = 1;
+ break;
+ case MMC_BUS_WIDTH_4:
+ mci_writel(host, REG_WIDTH, SDXC_WIDTH4);
+ host->bus_width = 4;
+ break;
+ case MMC_BUS_WIDTH_8:
+ mci_writel(host, REG_WIDTH, SDXC_WIDTH8);
+ host->bus_width = 8;
+ break;
+ }
+
+ /* set ddr mode */
+ temp = mci_readl(host, REG_GCTRL);
+ if (ios->timing == MMC_TIMING_UHS_DDR50) {
+ temp |= SDXC_DDR_MODE;
+ host->ddr = 1;
+ } else {
+ temp &= ~SDXC_DDR_MODE;
+ host->ddr = 0;
+ }
+ mci_writel(host, REG_GCTRL, temp);
+
+ /* set up clock */
+ if (ios->clock && ios->power_mode) {
+ dev_dbg(mmc_dev(host->mmc), "ios->clock: %d\n", ios->clock);
+ sunxi_mmc_clk_set_rate(host, ios->clock);
+ usleep_range(50000, 55000);
+ }
+}
+
+static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc);
+ unsigned long flags;
+ u32 imask;
+
+ spin_lock_irqsave(&smc_host->lock, flags);
+ imask = mci_readl(smc_host, REG_IMASK);
+ if (enable) {
+ smc_host->sdio_imask = SDXC_SDIOInt;
+ imask |= SDXC_SDIOInt;
+ } else {
+ smc_host->sdio_imask = 0;
+ imask &= ~SDXC_SDIOInt;
+ }
+ mci_writel(smc_host, REG_IMASK, imask);
+ spin_unlock_irqrestore(&smc_host->lock, flags);
+}
+
+static void sunxi_mmc_hw_reset(struct mmc_host *mmc)
+{
+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc);
+ mci_writel(smc_host, REG_HWRST, 0);
+ udelay(10);
+ mci_writel(smc_host, REG_HWRST, 1);
+ udelay(300);
+}
+
+static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct sunxi_mmc_host *host = mmc_priv(mmc);
+ struct mmc_command *cmd = mrq->cmd;
+ struct mmc_data *data = mrq->data;
+ unsigned long iflags;
+ u32 imask = SDXC_IntErrBit;
+ u32 cmd_val = SDXC_Start | (cmd->opcode & 0x3f);
+ u32 byte_cnt = 0;
+ int ret;
+
+ if (!mmc_gpio_get_cd(mmc) || host->ferror) {
+ dev_dbg(mmc_dev(host->mmc), "no medium present\n");
+ mrq->cmd->error = -ENOMEDIUM;
+ mmc_request_done(mmc, mrq);
+ return;
+ }
+
+ if (data) {
+ byte_cnt = data->blksz * data->blocks;
+ mci_writel(host, REG_BLKSZ, data->blksz);
+ mci_writel(host, REG_BCNTR, byte_cnt);
+ ret = sunxi_mmc_prepare_dma(host, data);
+ if (ret < 0) {
+ dev_err(mmc_dev(host->mmc), "prepare DMA failed\n");
+ cmd->error = ret;
+ cmd->data->error = ret;
+ mmc_request_done(host->mmc, mrq);
+ return;
+ }
+ }
+
+ if (cmd->opcode == MMC_GO_IDLE_STATE) {
+ cmd_val |= SDXC_SendInitSeq;
+ imask |= SDXC_CmdDone;
+ }
+
+ if (cmd->opcode == SD_SWITCH_VOLTAGE) {
+ cmd_val |= SDXC_VolSwitch;
+ imask |= SDXC_VolChgDone;
+ host->voltage_switching = 1;
+ sunxi_mmc_oclk_onoff(host, 1);
+ }
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ cmd_val |= SDXC_RspExp;
+ if (cmd->flags & MMC_RSP_136)
+ cmd_val |= SDXC_LongRsp;
+ if (cmd->flags & MMC_RSP_CRC)
+ cmd_val |= SDXC_CheckRspCRC;
+
+ if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) {
+ cmd_val |= SDXC_DataExp | SDXC_WaitPreOver;
+ if (cmd->data->flags & MMC_DATA_STREAM) {
+ imask |= SDXC_AutoCMDDone;
+ cmd_val |= SDXC_Seqmod | SDXC_SendAutoStop;
+ }
+ if (cmd->data->stop) {
+ imask |= SDXC_AutoCMDDone;
+ cmd_val |= SDXC_SendAutoStop;
+ } else
+ imask |= SDXC_DataOver;
+
+ if (cmd->data->flags & MMC_DATA_WRITE)
+ cmd_val |= SDXC_Write;
+ else
+ host->wait_dma = 1;
+ } else
+ imask |= SDXC_CmdDone;
+ } else
+ imask |= SDXC_CmdDone;
+
+ dev_dbg(mmc_dev(host->mmc), "cmd %d(%08x) arg %x ie 0x%08x len %d\n",
+ cmd_val & 0x3f, cmd_val, cmd->arg, imask,
+ mrq->data ? mrq->data->blksz * mrq->data->blocks : 0);
+
+ spin_lock_irqsave(&host->lock, iflags);
+ host->mrq = mrq;
+ mci_writel(host, REG_IMASK, host->sdio_imask | imask);
+ spin_unlock_irqrestore(&host->lock, iflags);
+
+ mci_writel(host, REG_CARG, cmd->arg);
+ mci_writel(host, REG_CMDR, cmd_val);
+}
+
+static const struct of_device_id sunxi_mmc_of_match[] = {
+ { .compatible = "allwinner,sun4i-a10-mmc", },
+ { .compatible = "allwinner,sun5i-a13-mmc", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
+
+static struct mmc_host_ops sunxi_mmc_ops = {
+ .request = sunxi_mmc_request,
+ .set_ios = sunxi_mmc_set_ios,
+ .get_ro = mmc_gpio_get_ro,
+ .get_cd = mmc_gpio_get_cd,
+ .enable_sdio_irq = sunxi_mmc_enable_sdio_irq,
+ .hw_reset = sunxi_mmc_hw_reset,
+};
+
+static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
+ struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int ret;
+
+ if (of_device_is_compatible(np, "allwinner,sun4i-a10-mmc"))
+ host->idma_des_size_bits = 13;
+ else
+ host->idma_des_size_bits = 16;
+
+ host->vmmc = devm_regulator_get_optional(&pdev->dev, "vmmc");
+ if (IS_ERR(host->vmmc) && PTR_ERR(host->vmmc) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ host->reg_base = devm_ioremap_resource(&pdev->dev,
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
+ if (IS_ERR(host->reg_base))
+ return PTR_ERR(host->reg_base);
+
+ host->irq = platform_get_irq(pdev, 0);
+ ret = devm_request_irq(&pdev->dev, host->irq, sunxi_mmc_irq, 0,
+ "sunxi-mci", host);
+ if (ret)
+ return ret;
+ disable_irq(host->irq);
+
+ host->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+ if (IS_ERR(host->clk_ahb)) {
+ dev_err(&pdev->dev, "Could not get ahb clock\n");
+ return PTR_ERR(host->clk_ahb);
+ }
+
+ host->clk_mod = devm_clk_get(&pdev->dev, "mod");
+ if (IS_ERR(host->clk_mod)) {
+ dev_err(&pdev->dev, "Could not get mod clock\n");
+ return PTR_ERR(host->clk_mod);
+ }
+
+ return 0;
+}
+
+static int sunxi_mmc_probe(struct platform_device *pdev)
+{
+ struct sunxi_mmc_host *host;
+ struct mmc_host *mmc;
+ int ret;
+
+ mmc = mmc_alloc_host(sizeof(struct sunxi_mmc_host), &pdev->dev);
+ if (!mmc) {
+ dev_err(&pdev->dev, "mmc alloc host failed\n");
+ return -ENOMEM;
+ }
+
+ ret = mmc_of_parse(mmc);
+ if (ret)
+ goto error_free_host;
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+ spin_lock_init(&host->lock);
+ tasklet_init(&host->tasklet, sunxi_mmc_tasklet, (unsigned long)host);
+
+ ret = sunxi_mmc_resource_request(host, pdev);
+ if (ret)
+ goto error_free_host;
+
+ host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
+ &host->sg_dma, GFP_KERNEL);
+ if (!host->sg_cpu) {
+ dev_err(&pdev->dev, "Failed to allocate DMA descriptor mem\n");
+ ret = -ENOMEM;
+ goto error_free_host;
+ }
+
+ mmc->ops = &sunxi_mmc_ops;
+ mmc->max_blk_count = 8192;
+ mmc->max_blk_size = 4096;
+ mmc->max_segs = PAGE_SIZE / sizeof(struct sunxi_idma_des);
+ mmc->max_seg_size = (1 << host->idma_des_size_bits);
+ mmc->max_req_size = mmc->max_seg_size * mmc->max_segs;
+ /* 400kHz ~ 50MHz */
+ mmc->f_min = 400000;
+ mmc->f_max = 50000000;
+ /* available voltages */
+ if (!IS_ERR(host->vmmc))
+ mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vmmc);
+ else
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ mmc->caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
+ MMC_CAP_UHS_DDR50 | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL |
+ MMC_CAP_DRIVER_TYPE_A;
+
+ if (host->bus_width == 4)
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
+
+ mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP;
+
+ ret = mmc_add_host(mmc);
+
+ if (ret)
+ goto error_free_dma;
+
+ dev_info(&pdev->dev, "base:0x%p irq:%u\n", host->reg_base, host->irq);
+ platform_set_drvdata(pdev, mmc);
+ return 0;
+
+error_free_dma:
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+error_free_host:
+ mmc_free_host(mmc);
+ return ret;
+}
+
+static int sunxi_mmc_remove(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+ struct sunxi_mmc_host *host = mmc_priv(mmc);
+
+ mmc_remove_host(mmc);
+ sunxi_mmc_exit_host(host);
+ tasklet_disable(&host->tasklet);
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+ mmc_free_host(mmc);
+
+ return 0;
+}
+
+static struct platform_driver sunxi_mmc_driver = {
+ .driver = {
+ .name = "sunxi-mci",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(sunxi_mmc_of_match),
+ },
+ .probe = sunxi_mmc_probe,
+ .remove = sunxi_mmc_remove,
+};
+module_platform_driver(sunxi_mmc_driver);
+
+MODULE_DESCRIPTION("Allwinner's SD/MMC Card Controller Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("David Lanzendörfer <david.lanzendoerfer-Z7Kmv9EsliU@public.gmane.org>");
+MODULE_ALIAS("platform:sunxi-mmc");
diff --git a/drivers/mmc/host/sunxi-mci.h b/drivers/mmc/host/sunxi-mci.h
new file mode 100644
index 0000000..4f3c2d9
--- /dev/null
+++ b/drivers/mmc/host/sunxi-mci.h
@@ -0,0 +1,239 @@
+/*
+ * Driver for sunxi SD/MMC host controllers
+ * (C) Copyright 2014-2015 Reuuimlla Technology Co., Ltd.
+ * (C) Copyright 2014-2015 Aaron Maoye <leafy.myeh-jFKXxz0WcGyYHARAtoI1EgC/G2K4zDHf@public.gmane.org>
+ * (C) Copyright 2014-2015 O2S GmbH <www.o2s.ch>
+ * (C) Copyright 2014-2015 David Lanzendörfer <david.lanzendoerfer@o2s.ch>
+ * (C) Copyright 2014-2015 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@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.
+ */
+
+#ifndef __SUNXI_MCI_H__
+#define __SUNXI_MCI_H__
+
+/* register offset define */
+#define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */
+#define SDXC_REG_CLKCR (0x04) /* SMC Clock Control Register */
+#define SDXC_REG_TMOUT (0x08) /* SMC Time Out Register */
+#define SDXC_REG_WIDTH (0x0C) /* SMC Bus Width Register */
+#define SDXC_REG_BLKSZ (0x10) /* SMC Block Size Register */
+#define SDXC_REG_BCNTR (0x14) /* SMC Byte Count Register */
+#define SDXC_REG_CMDR (0x18) /* SMC Command Register */
+#define SDXC_REG_CARG (0x1C) /* SMC Argument Register */
+#define SDXC_REG_RESP0 (0x20) /* SMC Response Register 0 */
+#define SDXC_REG_RESP1 (0x24) /* SMC Response Register 1 */
+#define SDXC_REG_RESP2 (0x28) /* SMC Response Register 2 */
+#define SDXC_REG_RESP3 (0x2C) /* SMC Response Register 3 */
+#define SDXC_REG_IMASK (0x30) /* SMC Interrupt Mask Register */
+#define SDXC_REG_MISTA (0x34) /* SMC Masked Interrupt Status Register */
+#define SDXC_REG_RINTR (0x38) /* SMC Raw Interrupt Status Register */
+#define SDXC_REG_STAS (0x3C) /* SMC Status Register */
+#define SDXC_REG_FTRGL (0x40) /* SMC FIFO Threshold Watermark Registe */
+#define SDXC_REG_FUNS (0x44) /* SMC Function Select Register */
+#define SDXC_REG_CBCR (0x48) /* SMC CIU Byte Count Register */
+#define SDXC_REG_BBCR (0x4C) /* SMC BIU Byte Count Register */
+#define SDXC_REG_DBGC (0x50) /* SMC Debug Enable Register */
+#define SDXC_REG_HWRST (0x78) /* SMC Card Hardware Reset for Register */
+#define SDXC_REG_DMAC (0x80) /* SMC IDMAC Control Register */
+#define SDXC_REG_DLBA (0x84) /* SMC IDMAC Descriptor List Base Addre */
+#define SDXC_REG_IDST (0x88) /* SMC IDMAC Status Register */
+#define SDXC_REG_IDIE (0x8C) /* SMC IDMAC Interrupt Enable Register */
+#define SDXC_REG_CHDA (0x90)
+#define SDXC_REG_CBDA (0x94)
+
+#define mci_readl(host, reg) \
+ readl((host)->reg_base + SDXC_##reg)
+#define mci_writel(host, reg, value) \
+ writel((value), (host)->reg_base + SDXC_##reg)
+
+/* global control register bits */
+#define SDXC_SoftReset BIT(0)
+#define SDXC_FIFOReset BIT(1)
+#define SDXC_DMAReset BIT(2)
+#define SDXC_HWReset (SDXC_SoftReset|SDXC_FIFOReset|SDXC_DMAReset)
+#define SDXC_INTEnb BIT(4)
+#define SDXC_DMAEnb BIT(5)
+#define SDXC_DebounceEnb BIT(8)
+#define SDXC_PosedgeLatchData BIT(9)
+#define SDXC_DDR_MODE BIT(10)
+#define SDXC_MemAccessDone BIT(29)
+#define SDXC_AccessDoneDirect BIT(30)
+#define SDXC_ACCESS_BY_AHB BIT(31)
+#define SDXC_ACCESS_BY_DMA (0U << 31)
+/* clock control bits */
+#define SDXC_CardClkOn BIT(16)
+#define SDXC_LowPowerOn BIT(17)
+/* bus width */
+#define SDXC_WIDTH1 (0)
+#define SDXC_WIDTH4 (1)
+#define SDXC_WIDTH8 (2)
+/* smc command bits */
+#define SDXC_RspExp BIT(6)
+#define SDXC_LongRsp BIT(7)
+#define SDXC_CheckRspCRC BIT(8)
+#define SDXC_DataExp BIT(9)
+#define SDXC_Write BIT(10)
+#define SDXC_Seqmod BIT(11)
+#define SDXC_SendAutoStop BIT(12)
+#define SDXC_WaitPreOver BIT(13)
+#define SDXC_StopAbortCMD BIT(14)
+#define SDXC_SendInitSeq BIT(15)
+#define SDXC_UPCLKOnly BIT(21)
+#define SDXC_RdCEATADev BIT(22)
+#define SDXC_CCSExp BIT(23)
+#define SDXC_EnbBoot BIT(24)
+#define SDXC_AltBootOpt BIT(25)
+#define SDXC_BootACKExp BIT(26)
+#define SDXC_BootAbort BIT(27)
+#define SDXC_VolSwitch BIT(28)
+#define SDXC_UseHoldReg BIT(29)
+#define SDXC_Start BIT(31)
+/* interrupt bits */
+#define SDXC_RespErr BIT(1)
+#define SDXC_CmdDone BIT(2)
+#define SDXC_DataOver BIT(3)
+#define SDXC_TxDataReq BIT(4)
+#define SDXC_RxDataReq BIT(5)
+#define SDXC_RespCRCErr BIT(6)
+#define SDXC_DataCRCErr BIT(7)
+#define SDXC_RespTimeout BIT(8)
+#define SDXC_DataTimeout BIT(9)
+#define SDXC_VolChgDone BIT(10)
+#define SDXC_FIFORunErr BIT(11)
+#define SDXC_HardWLocked BIT(12)
+#define SDXC_StartBitErr BIT(13)
+#define SDXC_AutoCMDDone BIT(14)
+#define SDXC_EndBitErr BIT(15)
+#define SDXC_SDIOInt BIT(16)
+#define SDXC_CardInsert BIT(30)
+#define SDXC_CardRemove BIT(31)
+#define SDXC_IntErrBit (SDXC_RespErr | SDXC_RespCRCErr | \
+ SDXC_DataCRCErr | SDXC_RespTimeout | \
+ SDXC_DataTimeout | SDXC_FIFORunErr | \
+ SDXC_HardWLocked | SDXC_StartBitErr | \
+ SDXC_EndBitErr) /* 0xbbc2 */
+#define SDXC_IntDoneBit (SDXC_AutoCMDDone | SDXC_DataOver | \
+ SDXC_CmdDone | SDXC_VolChgDone)
+/* status */
+#define SDXC_RXWLFlag BIT(0)
+#define SDXC_TXWLFlag BIT(1)
+#define SDXC_FIFOEmpty BIT(2)
+#define SDXC_FIFOFull BIT(3)
+#define SDXC_CardPresent BIT(8)
+#define SDXC_CardDataBusy BIT(9)
+#define SDXC_DataFSMBusy BIT(10)
+#define SDXC_DMAReq BIT(31)
+#define SDXC_FIFO_SIZE (16)
+/* Function select */
+#define SDXC_CEATAOn (0xceaaU << 16)
+#define SDXC_SendIrqRsp BIT(0)
+#define SDXC_SDIORdWait BIT(1)
+#define SDXC_AbtRdData BIT(2)
+#define SDXC_SendCCSD BIT(8)
+#define SDXC_SendAutoStopCCSD BIT(9)
+#define SDXC_CEATADevIntEnb BIT(10)
+/* IDMA controller bus mod bit field */
+#define SDXC_IDMACSoftRST BIT(0)
+#define SDXC_IDMACFixBurst BIT(1)
+#define SDXC_IDMACIDMAOn BIT(7)
+#define SDXC_IDMACRefetchDES BIT(31)
+/* IDMA status bit field */
+#define SDXC_IDMACTransmitInt BIT(0)
+#define SDXC_IDMACReceiveInt BIT(1)
+#define SDXC_IDMACFatalBusErr BIT(2)
+#define SDXC_IDMACDesInvalid BIT(4)
+#define SDXC_IDMACCardErrSum BIT(5)
+#define SDXC_IDMACNormalIntSum BIT(8)
+#define SDXC_IDMACAbnormalIntSum BIT(9)
+#define SDXC_IDMACHostAbtInTx BIT(10)
+#define SDXC_IDMACHostAbtInRx BIT(10)
+#define SDXC_IDMACIdle (0U << 13)
+#define SDXC_IDMACSuspend (1U << 13)
+#define SDXC_IDMACDESCRd (2U << 13)
+#define SDXC_IDMACDESCCheck (3U << 13)
+#define SDXC_IDMACRdReqWait (4U << 13)
+#define SDXC_IDMACWrReqWait (5U << 13)
+#define SDXC_IDMACRd (6U << 13)
+#define SDXC_IDMACWr (7U << 13)
+#define SDXC_IDMACDESCClose (8U << 13)
+
+struct sunxi_idma_des {
+ u32 config;
+#define SDXC_IDMAC_DES0_DIC BIT(1) /* disable interrupt on completion */
+#define SDXC_IDMAC_DES0_LD BIT(2) /* last descriptor */
+#define SDXC_IDMAC_DES0_FD BIT(3) /* first descriptor */
+#define SDXC_IDMAC_DES0_CH BIT(4) /* chain mode */
+#define SDXC_IDMAC_DES0_ER BIT(5) /* end of ring */
+#define SDXC_IDMAC_DES0_CES BIT(30) /* card error summary */
+#define SDXC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */
+
+ /*
+ * If the idma-des-size-bits of property is ie 13, bufsize bits are:
+ * Bits 0-12: buf1 size
+ * Bits 13-25: buf2 size
+ * Bits 26-31: not used
+ * Since we only ever set buf1 size, we can simply store it directly.
+ */
+ u32 buf_size;
+ u32 buf_addr_ptr1;
+ u32 buf_addr_ptr2;
+};
+
+struct sunxi_mmc_host {
+ struct mmc_host *mmc;
+ struct regulator *vmmc;
+
+ /* IO mapping base */
+ void __iomem *reg_base;
+
+ spinlock_t lock;
+ struct tasklet_struct tasklet;
+
+ /* clock management */
+ struct clk *clk_ahb;
+ struct clk *clk_mod;
+
+ /* ios information */
+ u32 clk_mod_rate;
+ u32 bus_width;
+ u32 idma_des_size_bits;
+ u32 ddr;
+ u32 voltage_switching;
+
+ /* irq */
+ int irq;
+ u32 int_sum;
+ u32 sdio_imask;
+
+ /* flags */
+ u32 power_on:1;
+ u32 io_flag:1;
+ u32 wait_dma:1;
+
+ dma_addr_t sg_dma;
+ void *sg_cpu;
+
+ struct mmc_request *mrq;
+ u32 ferror;
+};
+
+#define MMC_CLK_400K 0
+#define MMC_CLK_25M 1
+#define MMC_CLK_50M 2
+#define MMC_CLK_50MDDR 3
+#define MMC_CLK_50MDDR_8BIT 4
+#define MMC_CLK_100M 5
+#define MMC_CLK_200M 6
+#define MMC_CLK_MOD_NUM 7
+
+struct sunxi_mmc_clk_dly {
+ u32 mode;
+ u32 oclk_dly;
+ u32 sclk_dly;
+};
+
+#endif
--
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/groups/opt_out.
^ permalink raw reply related
* [PATCH v3 3/7] ARM: sunxi: clk: export clk_sunxi_mmc_phase_control
From: David Lanzendörfer @ 2014-02-05 13:54 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Simon Baatz, Hans de Goede, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo, Maxime Ripard,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20140205134741.3027.50207.stgit-GPtPHOohwllnsqa/0SyWJQ@public.gmane.org>
From: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
include/linux/clk/sunxi.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 include/linux/clk/sunxi.h
diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
new file mode 100644
index 0000000..1ef5c89
--- /dev/null
+++ b/include/linux/clk/sunxi.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 - Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@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.
+ */
+
+#ifndef __LINUX_CLK_SUNXI_H_
+#define __LINUX_CLK_SUNXI_H_
+
+#include <linux/clk.h>
+
+void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output);
+
+#endif
^ permalink raw reply related
* [PATCH v3 2/7] clk: sunxi: Implement MMC phase control
From: David Lanzendörfer @ 2014-02-05 13:53 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Simon Baatz, Hans de Goede, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo, Maxime Ripard,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20140205134741.3027.50207.stgit-GPtPHOohwllnsqa/0SyWJQ@public.gmane.org>
From: Emilio López <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
Signed-off-by: Emilio López <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
---
drivers/clk/sunxi/clk-sunxi.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index abb6c5a..33b9977 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -377,6 +377,41 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate,
/**
+ * clk_sunxi_mmc_phase_control() - configures MMC clock phase control
+ */
+
+void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output)
+{
+ #define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
+ #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+
+ struct clk_composite *composite = to_clk_composite(hw);
+ struct clk_hw *rate_hw = composite->rate_hw;
+ struct clk_factors *factors = to_clk_factors(rate_hw);
+ unsigned long flags = 0;
+ u32 reg;
+
+ if (factors->lock)
+ spin_lock_irqsave(factors->lock, flags);
+
+ reg = readl(factors->reg);
+
+ /* set sample clock phase control */
+ reg &= ~(0x7 << 20);
+ reg |= ((sample & 0x7) << 20);
+
+ /* set output clock phase control */
+ reg &= ~(0x7 << 8);
+ reg |= ((output & 0x7) << 8);
+
+ writel(reg, factors->reg);
+
+ if (factors->lock)
+ spin_unlock_irqrestore(factors->lock, flags);
+}
+
+
+/**
* sunxi_factors_clk_setup() - Setup function for factor clocks
*/
--
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/groups/opt_out.
^ permalink raw reply related
* [PATCH v3 1/7] clk: sunxi: factors: automatic reparenting support
From: David Lanzendörfer @ 2014-02-05 13:53 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Simon Baatz, Hans de Goede, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo, Maxime Ripard,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20140205134741.3027.50207.stgit-GPtPHOohwllnsqa/0SyWJQ@public.gmane.org>
From: Emilio López <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
This commit implements .determine_rate, so that our factor clocks can be
reparented when needed.
Signed-off-by: Emilio López <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
---
drivers/clk/sunxi/clk-factors.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 9e23264..3806d97 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -77,6 +77,41 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
return rate;
}
+static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *best_parent_rate,
+ struct clk **best_parent_p)
+{
+ struct clk *clk = hw->clk, *parent, *best_parent = NULL;
+ int i, num_parents;
+ unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
+
+ /* find the parent that can help provide the fastest rate <= rate */
+ num_parents = __clk_get_num_parents(clk);
+ for (i = 0; i < num_parents; i++) {
+ parent = clk_get_parent_by_index(clk, i);
+ if (!parent)
+ continue;
+ if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
+ parent_rate = __clk_round_rate(parent, rate);
+ else
+ parent_rate = __clk_get_rate(parent);
+
+ child_rate = clk_factors_round_rate(hw, rate, &parent_rate);
+
+ if (child_rate <= rate && child_rate > best_child_rate) {
+ best_parent = parent;
+ best = parent_rate;
+ best_child_rate = child_rate;
+ }
+ }
+
+ if (best_parent)
+ *best_parent_p = best_parent;
+ *best_parent_rate = best;
+
+ return best_child_rate;
+}
+
static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
@@ -113,6 +148,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
}
const struct clk_ops clk_factors_ops = {
+ .determine_rate = clk_factors_determine_rate,
.recalc_rate = clk_factors_recalc_rate,
.round_rate = clk_factors_round_rate,
.set_rate = clk_factors_set_rate,
--
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/groups/opt_out.
^ permalink raw reply related
* [PATCH v3 0/7] ARM: sunxi: Add driver for SD/MMC hosts found on allwinner sunxi SOCs
From: David Lanzendörfer @ 2014-02-05 13:53 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Simon Baatz, Hans de Goede, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo, Maxime Ripard,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Hello
The following patchset adds support for the SD/MMC host found in the Allwinner SoCs.
It contains all the necessary modifications for clock environment and also the device
tree script modification which add it to all the boards using it.
The clock environment function needed for phase offset configuration has
been proposed and implemented by Emilio.
A lot of work and cleanup has been done by Hans de Goede. Special thanks to him!
This patchset is the third attempt to send this driver upstream.
It addresses special remarks about coding style and API usage and incorporates proposed
corrections into the previous commits.
It also includes the patch of Emilios, I forgot to include last time.
best regards
David
---
David Lanzendörfer (4):
ARM: sunxi: Add driver for SD/MMC hosts found on Allwinner sunxi SoCs
ARM: dts: sun7i: Add support for mmc
ARM: dts: sun4i: Add support for mmc
ARM: dts: sun5i: Add support for mmc
Emilio López (2):
clk: sunxi: factors: automatic reparenting support
clk: sunxi: Implement MMC phase control
Hans de Goede (1):
ARM: sunxi: clk: export clk_sunxi_mmc_phase_control
arch/arm/boot/dts/sun4i-a10-a1000.dts | 8
arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 8
arch/arm/boot/dts/sun4i-a10.dtsi | 54 +
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 30 +
arch/arm/boot/dts/sun5i-a10s.dtsi | 44 +
arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts | 15
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 15
arch/arm/boot/dts/sun5i-a13.dtsi | 37 +
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 8
arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 8
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 23 +
arch/arm/boot/dts/sun7i-a20.dtsi | 61 ++
drivers/clk/sunxi/clk-factors.c | 36 +
drivers/clk/sunxi/clk-sunxi.c | 35 +
drivers/mmc/host/Kconfig | 7
drivers/mmc/host/Makefile | 2
drivers/mmc/host/sunxi-mci.c | 859 ++++++++++++++++++++++
drivers/mmc/host/sunxi-mci.h | 239 ++++++
include/linux/clk/sunxi.h | 22 +
19 files changed, 1511 insertions(+)
create mode 100644 drivers/mmc/host/sunxi-mci.c
create mode 100644 drivers/mmc/host/sunxi-mci.h
create mode 100644 include/linux/clk/sunxi.h
--
Signature
--
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/groups/opt_out.
^ 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