* [PATCH v2 1/2] serial: 8250: Add flag so drivers can avoid THRE probe
From: Joel Stanley @ 2017-04-05 4:03 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Mark Rutland, Rob Herring
Cc: linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Andy Shevchenko,
Benjamin Herrenschmidt, Jeremy Kerr,
openbmc-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <20170405040352.5661-1-joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
The probing of THRE irq behaviour assumes the other end will be reading
bytes out of the buffer in order to probe the port at driver init. In
some cases the other end cannot be relied upon to read these bytes, so
provide a flag for them to skip this step.
Bit 16 was chosen as the flags are a int and the top bits are taken.
Acked-by: Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
---
drivers/tty/serial/8250/8250_port.c | 2 +-
include/linux/serial_core.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 6119516ef5fc..60a6c247340f 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2229,7 +2229,7 @@ int serial8250_do_startup(struct uart_port *port)
}
}
- if (port->irq) {
+ if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) {
unsigned char iir1;
/*
* Test for UARTs that do not reassert THRE when the
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 58484fb35cc8..260245deec94 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -195,6 +195,7 @@ struct uart_port {
#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15))
#define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ )
+#define UPF_NO_THRE_TEST ((__force upf_t) (1 << 19))
/* Port has hardware-assisted h/w flow control */
#define UPF_AUTO_CTS ((__force upf_t) (1 << 20))
#define UPF_AUTO_RTS ((__force upf_t) (1 << 21))
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 2/2] drivers/serial: Add driver for Aspeed virtual UART
From: Joel Stanley @ 2017-04-05 4:03 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Mark Rutland, Rob Herring
Cc: Jeremy Kerr, linux-serial, linux-kernel, devicetree,
Andy Shevchenko, Benjamin Herrenschmidt, openbmc
In-Reply-To: <20170405040352.5661-1-joel@jms.id.au>
From: Jeremy Kerr <jk@ozlabs.org>
This change adds a driver for the 16550-based Aspeed virtual UART
device. We use a similar process to the of_serial driver for device
probe, but expose some VUART-specific functions through sysfs too.
The VUART is two UART 'front ends' connected by their FIFO (no actual
serial line in between). One is on the BMC side (management controller)
and one is on the host CPU side.
This driver is for the BMC side. The sysfs files allow the BMC
userspace, which owns the system configuration policy, to specify at
what IO port and interrupt number the host side will appear to the host
on the Host <-> BMC LPC bus. It could be different on a different system
(though most of them use 3f8/4).
OpenPOWER host firmware doesn't like it when the host-side of the
VUART's FIFO is not drained. This driver only disables host TX discard
mode when the port is in use. We set the VUART enabled bit when we bind
to the device, and clear it on unbind.
We don't want to do this on open/release, as the host may be using this
bit to configure serial output modes, which is independent of whether
the devices has been opened by BMC userspace.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Acked-by: Rob Herring <robh@kernel.org>
---
v2:
- Use attribute groups and DEVICE_ATTR_RW
- Use platform_get_resource/devm_ioremap_resource
- of_find_property -> of_property_read_bool
- Drop unncessary 0xff mask
- Fix comment style
- Use BIT and GENMASK where pssible
- Move to 8250 directory
- Rename ast -> aspeed to match other Aspeed drivers
- Add documentation of sysfs file
- Add detail to the commit message
- add Rob's ack for the binding change
---
Documentation/ABI/stable/sysfs-driver-aspeed-vuart | 15 +
Documentation/devicetree/bindings/serial/8250.txt | 2 +
drivers/tty/serial/8250/Kconfig | 10 +
drivers/tty/serial/8250/Makefile | 1 +
drivers/tty/serial/8250/aspeed-vuart.c | 341 +++++++++++++++++++++
5 files changed, 369 insertions(+)
create mode 100644 Documentation/ABI/stable/sysfs-driver-aspeed-vuart
create mode 100644 drivers/tty/serial/8250/aspeed-vuart.c
diff --git a/Documentation/ABI/stable/sysfs-driver-aspeed-vuart b/Documentation/ABI/stable/sysfs-driver-aspeed-vuart
new file mode 100644
index 000000000000..8062953ce77b
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-driver-aspeed-vuart
@@ -0,0 +1,15 @@
+What: /sys/bus/platform/drivers/aspeed-vuart/*/lpc_address
+Date: April 2017
+Contact: Jeremy Kerr <jk@ozlabs.org>
+Description: Configures which IO port the host side of the UART
+ will appear on the host <-> BMC LPC bus.
+Users: OpenBMC. Proposed changes should be mailed to
+ openbmc@lists.ozlabs.org
+
+What: /sys/bus/platform/drivers/aspeed-vuart*/sirq
+Date: April 2017
+Contact: Jeremy Kerr <jk@ozlabs.org>
+Description: Configures which interrupt number the host side of
+ the UART will appear on the host <-> BMC LPC bus.
+Users: OpenBMC. Proposed changes should be mailed to
+ openbmc@lists.ozlabs.org
diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt
index 10276a46ecef..656733949309 100644
--- a/Documentation/devicetree/bindings/serial/8250.txt
+++ b/Documentation/devicetree/bindings/serial/8250.txt
@@ -20,6 +20,8 @@ Required properties:
- "fsl,16550-FIFO64"
- "fsl,ns16550"
- "ti,da830-uart"
+ - "aspeed,ast2400-vuart"
+ - "aspeed,ast2500-vuart"
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index a65fb8197aec..fb217f02ec94 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -220,6 +220,16 @@ config SERIAL_8250_ACCENT
To compile this driver as a module, choose M here: the module
will be called 8250_accent.
+config SERIAL_8250_ASPEED_VUART
+ tristate "Aspeed Virtual UART"
+ depends on SERIAL_8250
+ depends on OF
+ help
+ If you want to use the virtual UART (VUART) device on Aspeed
+ BMC platforms, enable this option. This enables the 16550A-
+ compatible device on the local LPC bus, giving a UART device
+ with no physical RS232 connections.
+
config SERIAL_8250_BOCA
tristate "Support Boca cards"
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 2f30f9ecdb1b..405d720b51c7 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_SERIAL_8250_EXAR) += 8250_exar.o
obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
+obj-$(CONFIG_SERIAL_8250_ASPEED_VUART) += aspeed-vuart.o
obj-$(CONFIG_SERIAL_8250_BCM2835AUX) += 8250_bcm2835aux.o
obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
diff --git a/drivers/tty/serial/8250/aspeed-vuart.c b/drivers/tty/serial/8250/aspeed-vuart.c
new file mode 100644
index 000000000000..261b3dbaa7c1
--- /dev/null
+++ b/drivers/tty/serial/8250/aspeed-vuart.c
@@ -0,0 +1,341 @@
+/*
+ * Serial Port driver for Aspeed VUART device
+ *
+ * Copyright (C) 2016 Jeremy Kerr <jk@ozlabs.org>, IBM Corp.
+ * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp.
+ *
+ * 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/device.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+
+#include "8250.h"
+
+#define ASPEED_VUART_GCRA 0x20
+#define ASPEED_VUART_GCRA_VUART_EN BIT(0)
+#define ASPEED_VUART_GCRA_HOST_TX_DISCARD BIT(5)
+#define ASPEED_VUART_GCRB 0x24
+#define ASPEED_VUART_GCRB_HOST_SIRQ_MASK GENMASK(7, 4)
+#define ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT 4
+#define ASPEED_VUART_ADDRL 0x28
+#define ASPEED_VUART_ADDRH 0x2c
+
+struct aspeed_vuart {
+ struct device *dev;
+ void __iomem *regs;
+ struct clk *clk;
+ int line;
+};
+
+/*
+ * The VUART is basically two UART 'front ends' connected by their FIFO
+ * (no actual serial line in between). One is on the BMC side (management
+ * controller) and one is on the host CPU side.
+ *
+ * It allows the BMC to provide to the host a "UART" that pipes into
+ * the BMC itself and can then be turned by the BMC into a network console
+ * of some sort for example.
+ *
+ * This driver is for the BMC side. The sysfs files allow the BMC
+ * userspace which owns the system configuration policy, to specify
+ * at what IO port and interrupt number the host side will appear
+ * to the host on the Host <-> BMC LPC bus. It could be different on a
+ * different system (though most of them use 3f8/4).
+ */
+
+static ssize_t lpc_address_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct aspeed_vuart *vuart = dev_get_drvdata(dev);
+ u16 addr;
+
+ addr = (readb(vuart->regs + ASPEED_VUART_ADDRH) << 8) |
+ (readb(vuart->regs + ASPEED_VUART_ADDRL));
+
+ return snprintf(buf, PAGE_SIZE - 1, "0x%x\n", addr);
+}
+
+static ssize_t lpc_address_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct aspeed_vuart *vuart = dev_get_drvdata(dev);
+ unsigned long val;
+ int err;
+
+ err = kstrtoul(buf, 0, &val);
+ if (err)
+ return err;
+
+ writeb(val >> 8, vuart->regs + ASPEED_VUART_ADDRH);
+ writeb(val >> 0, vuart->regs + ASPEED_VUART_ADDRL);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(lpc_address);
+
+static ssize_t sirq_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct aspeed_vuart *vuart = dev_get_drvdata(dev);
+ u8 reg;
+
+ reg = readb(vuart->regs + ASPEED_VUART_GCRB);
+ reg &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
+ reg >>= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT;
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg);
+}
+
+static ssize_t sirq_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct aspeed_vuart *vuart = dev_get_drvdata(dev);
+ unsigned long val;
+ int err;
+ u8 reg;
+
+ err = kstrtoul(buf, 0, &val);
+ if (err)
+ return err;
+
+ val <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT;
+ val &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
+
+ reg = readb(vuart->regs + ASPEED_VUART_GCRB);
+ reg &= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
+ reg |= val;
+ writeb(reg, vuart->regs + ASPEED_VUART_GCRB);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(sirq);
+
+static struct attribute *aspeed_vuart_attrs[] = {
+ &dev_attr_sirq.attr,
+ &dev_attr_lpc_address.attr,
+ NULL,
+};
+
+static const struct attribute_group aspeed_vuart_attr_group = {
+ .attrs = aspeed_vuart_attrs,
+};
+
+static void aspeed_vuart_set_enabled(struct aspeed_vuart *vuart, bool enabled)
+{
+ u8 reg;
+
+ reg = readb(vuart->regs + ASPEED_VUART_GCRA);
+ reg &= ~ASPEED_VUART_GCRA_VUART_EN;
+ if (enabled)
+ reg |= ASPEED_VUART_GCRA_VUART_EN;
+ writeb(reg, vuart->regs + ASPEED_VUART_GCRA);
+}
+
+static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart *vuart,
+ bool discard)
+{
+ u8 reg;
+
+ reg = readb(vuart->regs + ASPEED_VUART_GCRA);
+
+ /* if the HOST_TX_DISCARD bit is set, discard is *disabled* */
+ reg &= ~ASPEED_VUART_GCRA_HOST_TX_DISCARD;
+ if (!discard)
+ reg |= ASPEED_VUART_GCRA_HOST_TX_DISCARD;
+
+ writeb(reg, vuart->regs + ASPEED_VUART_GCRA);
+}
+
+static int aspeed_vuart_startup(struct uart_port *uart_port)
+{
+ struct uart_8250_port *uart_8250_port = up_to_u8250p(uart_port);
+ struct aspeed_vuart *vuart = uart_8250_port->port.private_data;
+ int rc;
+
+ rc = serial8250_do_startup(uart_port);
+ if (rc)
+ return rc;
+
+ aspeed_vuart_set_host_tx_discard(vuart, false);
+
+ return 0;
+}
+
+static void aspeed_vuart_shutdown(struct uart_port *uart_port)
+{
+ struct uart_8250_port *uart_8250_port = up_to_u8250p(uart_port);
+ struct aspeed_vuart *vuart = uart_8250_port->port.private_data;
+
+ aspeed_vuart_set_host_tx_discard(vuart, true);
+
+ serial8250_do_shutdown(uart_port);
+}
+
+static int aspeed_vuart_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port port;
+ struct resource *res;
+ struct aspeed_vuart *vuart;
+ struct device_node *np;
+ u32 clk, prop;
+ int rc;
+
+ np = pdev->dev.of_node;
+
+ vuart = devm_kzalloc(&pdev->dev, sizeof(*vuart), GFP_KERNEL);
+ if (!vuart)
+ return -ENOMEM;
+
+ vuart->dev = &pdev->dev;
+
+ /* The 8510 core creates the mapping, which we grab a reference to
+ * for VUART-specific registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ vuart->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(vuart->regs))
+ return PTR_ERR(vuart->regs);
+
+ memset(&port, 0, sizeof(port));
+ port.port.private_data = vuart;
+ port.port.membase = vuart->regs;
+ port.port.mapbase = res->start;
+ port.port.mapsize = resource_size(res);
+ port.port.startup = aspeed_vuart_startup;
+ port.port.shutdown = aspeed_vuart_shutdown;
+ port.port.dev = &pdev->dev;
+
+ rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
+ if (rc < 0)
+ return rc;
+
+ if (of_property_read_u32(np, "clock-frequency", &clk)) {
+ vuart->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(vuart->clk)) {
+ dev_warn(&pdev->dev,
+ "clk or clock-frequency not defined\n");
+ return PTR_ERR(vuart->clk);
+ }
+
+ rc = clk_prepare_enable(vuart->clk);
+ if (rc < 0)
+ return rc;
+
+ clk = clk_get_rate(vuart->clk);
+ }
+
+ /* If current-speed was set, then try not to change it. */
+ if (of_property_read_u32(np, "current-speed", &prop) == 0)
+ port.port.custom_divisor = clk / (16 * prop);
+
+ /* Check for shifted address mapping */
+ if (of_property_read_u32(np, "reg-offset", &prop) == 0)
+ port.port.mapbase += prop;
+
+ /* Check for registers offset within the devices address range */
+ if (of_property_read_u32(np, "reg-shift", &prop) == 0)
+ port.port.regshift = prop;
+
+ /* Check for fifo size */
+ if (of_property_read_u32(np, "fifo-size", &prop) == 0)
+ port.port.fifosize = prop;
+
+ /* Check for a fixed line number */
+ rc = of_alias_get_id(np, "serial");
+ if (rc >= 0)
+ port.port.line = rc;
+
+ port.port.irq = irq_of_parse_and_map(np, 0);
+ port.port.irqflags = IRQF_SHARED;
+ port.port.iotype = UPIO_MEM;
+ if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
+ switch (prop) {
+ case 1:
+ port.port.iotype = UPIO_MEM;
+ break;
+ case 4:
+ port.port.iotype = of_device_is_big_endian(np) ?
+ UPIO_MEM32BE : UPIO_MEM32;
+ break;
+ default:
+ dev_warn(&pdev->dev, "unsupported reg-io-width (%d)\n",
+ prop);
+ rc = -EINVAL;
+ goto err_clk_disable;
+ }
+ }
+
+ port.port.type = PORT_16550A;
+ port.port.uartclk = clk;
+ port.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
+ | UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_NO_THRE_TEST;
+
+ if (of_property_read_bool(np, "no-loopback-test"))
+ port.port.flags |= UPF_SKIP_TEST;
+
+ if (port.port.fifosize)
+ port.capabilities = UART_CAP_FIFO;
+
+ if (of_property_read_bool(np, "auto-flow-control"))
+ port.capabilities |= UART_CAP_AFE;
+
+ rc = serial8250_register_8250_port(&port);
+ if (rc < 0)
+ goto err_clk_disable;
+
+ vuart->line = rc;
+
+ aspeed_vuart_set_enabled(vuart, true);
+ aspeed_vuart_set_host_tx_discard(vuart, true);
+ platform_set_drvdata(pdev, vuart);
+
+ return 0;
+
+err_clk_disable:
+ clk_disable_unprepare(vuart->clk);
+ irq_dispose_mapping(port.port.irq);
+ return rc;
+}
+
+static int aspeed_vuart_remove(struct platform_device *pdev)
+{
+ struct aspeed_vuart *vuart = platform_get_drvdata(pdev);
+
+ aspeed_vuart_set_enabled(vuart, false);
+ serial8250_unregister_port(vuart->line);
+ sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
+ clk_disable_unprepare(vuart->clk);
+
+ return 0;
+}
+
+static const struct of_device_id aspeed_vuart_table[] = {
+ { .compatible = "aspeed,ast2400-vuart" },
+ { .compatible = "aspeed,ast2500-vuart" },
+ { },
+};
+
+static struct platform_driver aspeed_vuart_driver = {
+ .driver = {
+ .name = "aspeed-vuart",
+ .of_match_table = aspeed_vuart_table,
+ },
+ .probe = aspeed_vuart_probe,
+ .remove = aspeed_vuart_remove,
+};
+
+module_platform_driver(aspeed_vuart_driver);
+
+MODULE_AUTHOR("Jeremy Kerr <jk@ozlabs.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Driver for Aspeed VUART device");
--
2.11.0
^ permalink raw reply related
* Re: [PATCH] mmc: core: add mmc-card hardware reset enable support
From: Jaehoon Chung @ 2017-04-05 4:40 UTC (permalink / raw)
To: Richard Leitner, ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
Cc: shawn.lin-TNX95d0MmH7DzftRWevZcw,
adrian.hunter-ral2JQCrhuEAvxtiuMwx3w,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
linux-mmc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, dev-M/VWbR8SM2SsTnJN9+BGXg
In-Reply-To: <1491315394-7568-1-git-send-email-richard.leitner-WcANXNA0UjBBDgjK7y7TUQ@public.gmane.org>
Hi,
On 04/04/2017 11:16 PM, Richard Leitner wrote:
> Some eMMCs disable their hardware reset line (RST_N) by default. To enable
> it the host must set the corresponding bit in ECSD. An example for such
> a device is the Micron MTFCxGACAANA-4M.
>
> This patch adds a new mmc-card devicetree property to let the host enable
> this feature during card initialization.
>
> Signed-off-by: Richard Leitner <richard.leitner-WcANXNA0UjBBDgjK7y7TUQ@public.gmane.org>
> ---
> Documentation/devicetree/bindings/mmc/mmc-card.txt | 3 +++
> drivers/mmc/core/mmc.c | 21 +++++++++++++++++++++
> 2 files changed, 24 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.txt b/Documentation/devicetree/bindings/mmc/mmc-card.txt
> index a70fcd6..8590a40 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc-card.txt
> +++ b/Documentation/devicetree/bindings/mmc/mmc-card.txt
> @@ -12,6 +12,9 @@ Required properties:
> Optional properties:
> -broken-hpi : Use this to indicate that the mmc-card has a broken hpi
> implementation, and that hpi should not be used
> +-enable-hw-reset : some eMMC devices have disabled the hw reset functionality
> + (RST_N_FUNCTION) by default. By adding this property the
> + host will enable it during initialization.
As i know, RST_N_FUNCTION is controlled bit[1:0]
0x0 : RST_n disabled (by default)
0x1 : permanently enabled
0x2 : permanently disabled
I think that it needs to add the description about these..
>
> Example:
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index b502601..518d0e3 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -1520,9 +1520,16 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> int err;
> u32 cid[4];
> u32 rocr;
> + struct device_node *np;
> + bool enable_rst_n = false;
>
> WARN_ON(!host->claimed);
>
> + np = mmc_of_find_child_device(host, 0);
> + if (np && of_device_is_compatible(np, "mmc-card"))
> + enable_rst_n = of_property_read_bool(np, "enable-hw-reset");
> + of_node_put(np);
> +
> /* Set correct bus mode for MMC before attempting init */
> if (!mmc_host_is_spi(host))
> mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN);
> @@ -1810,6 +1817,20 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
> }
> }
>
> + /*
> + * try to enable RST_N if requested
> + * This is needed because some eMMC chips disable this function by
> + * default.
> + */
> + if (enable_rst_n) {
> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> + EXT_CSD_RST_N_FUNCTION, EXT_CSD_RST_N_ENABLED,
> + card->ext_csd.generic_cmd6_time);
> + if (err && err != -EBADMSG)
> + pr_warn("%s: Enabling RST_N feature failed\n",
> + mmc_hostname(card->host));
> + }
If enabled hw-reset, it doesn't need to re-enable this bit.
i didn't check the mmc-util..
If mmc-util provides the changing this, the using mmc-util is better than this.
Best Regards,
Jaehoon Chung
> +
> if (!oldcard)
> host->card = card;
>
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 0/6] clk: qcom: CPU clock driver for msm8996
From: Rajendra Nayak @ 2017-04-05 4:55 UTC (permalink / raw)
To: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rajendra Nayak
This series adds support for the CPU clocks on msm8996 devices.
A previous post of RFC can be found here
https://patchwork.kernel.org/patch/9355925/
Rajendra Nayak (5):
clk: qcom: Make clk_alpha_pll_configure available to modules
clk: qcom: Add CPU clock driver for msm8996
clk: qcom: cpu-8996: Add support to switch to alternate PLL
clk: qcom: cpu-8996: Add support to switch below 600Mhz
arm64: dts: msm8996: Add CPU clock controller node
Taniya Das (1):
clk: qcom: Fix .set_rate to handle alpha PLLs w/wo dynamic update
.../devicetree/bindings/clock/qcom,kryocc.txt | 17 +
arch/arm64/boot/dts/qcom/msm8996.dtsi | 6 +
drivers/clk/qcom/Kconfig | 8 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/clk-alpha-pll.c | 72 +++-
drivers/clk/qcom/clk-alpha-pll.h | 5 +
drivers/clk/qcom/clk-cpu-8996.c | 440 +++++++++++++++++++++
7 files changed, 538 insertions(+), 11 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/6] clk: qcom: Fix .set_rate to handle alpha PLLs w/wo dynamic update
From: Rajendra Nayak @ 2017-04-05 4:55 UTC (permalink / raw)
To: sboyd, mturquette
Cc: linux-clk, linux-arm-msm, devicetree, Taniya Das, Rajendra Nayak
In-Reply-To: <1491368129-24721-1-git-send-email-rnayak@codeaurora.org>
From: Taniya Das <tdas@codeaurora.org>
Alpha PLLs which do not support dynamic update feature
need to be explicitly disabled before a rate change.
The ones which do support dynamic update do so within a
single vco range, so add a min/max freq check for such
PLLs so they fall in the vco range.
Signed-off-by: Taniya Das <tdas@codeaurora.org>
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
drivers/clk/qcom/clk-alpha-pll.c | 71 +++++++++++++++++++++++++++++++++-------
drivers/clk/qcom/clk-alpha-pll.h | 5 +++
2 files changed, 65 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 47a1da3..ecb9e7f 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -376,19 +376,46 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
return alpha_pll_calc_rate(prate, l, a);
}
-static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long prate)
+static int alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate,
+ int (*enable)(struct clk_hw *hw),
+ void (*disable)(struct clk_hw *hw))
{
+ bool enabled;
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
const struct pll_vco *vco;
u32 l, off = pll->offset;
u64 a;
rate = alpha_pll_round_rate(rate, prate, &l, &a);
- vco = alpha_pll_find_vco(pll, rate);
- if (!vco) {
- pr_err("alpha pll not in a valid vco range\n");
- return -EINVAL;
+ enabled = clk_hw_is_enabled(hw);
+
+ if (pll->flags & SUPPORTS_DYNAMIC_UPDATE) {
+ /*
+ * PLLs which support dynamic updates support one single
+ * vco range, between min_rate and max_rate supported
+ */
+ if (rate < pll->min_rate || rate > pll->max_rate) {
+ pr_err("alpha pll rate outside supported min/max range\n");
+ return -EINVAL;
+ }
+ } else {
+ /*
+ * All alpha PLLs which do not support dynamic update,
+ * should be disabled before a vco update.
+ */
+ if (enabled)
+ disable(hw);
+
+ vco = alpha_pll_find_vco(pll, rate);
+ if (!vco) {
+ pr_err("alpha pll not in a valid vco range\n");
+ return -EINVAL;
+ }
+
+ regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
+ PLL_VCO_MASK << PLL_VCO_SHIFT,
+ vco->val << PLL_VCO_SHIFT);
}
regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
@@ -401,16 +428,29 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, a >> 32);
}
- regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
- PLL_VCO_MASK << PLL_VCO_SHIFT,
- vco->val << PLL_VCO_SHIFT);
-
regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, PLL_ALPHA_EN,
PLL_ALPHA_EN);
+ if (!(pll->flags & SUPPORTS_DYNAMIC_UPDATE) && enabled)
+ enable(hw);
+
return 0;
}
+static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate)
+{
+ return alpha_pll_set_rate(hw, rate, prate, clk_alpha_pll_enable,
+ clk_alpha_pll_disable);
+}
+
+static int clk_alpha_pll_hwfsm_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate)
+{
+ return alpha_pll_set_rate(hw, rate, prate, clk_alpha_pll_hwfsm_enable,
+ clk_alpha_pll_hwfsm_disable);
+}
+
static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
@@ -420,6 +460,15 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_freq, max_freq;
rate = alpha_pll_round_rate(rate, *prate, &l, &a);
+
+ if (pll->flags & SUPPORTS_DYNAMIC_UPDATE) {
+ if (rate < pll->min_rate)
+ rate = pll->min_rate;
+ else if (rate > pll->max_rate)
+ rate = pll->max_rate;
+ return rate;
+ }
+
if (alpha_pll_find_vco(pll, rate))
return rate;
@@ -445,7 +494,7 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
.is_enabled = clk_alpha_pll_hwfsm_is_enabled,
.recalc_rate = clk_alpha_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
- .set_rate = clk_alpha_pll_set_rate,
+ .set_rate = clk_alpha_pll_hwfsm_set_rate,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index d6e1ee2..7aaa11c 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -27,6 +27,8 @@ struct pll_vco {
* struct clk_alpha_pll - phase locked loop (PLL)
* @offset: base address of registers
* @vco_table: array of VCO settings
+ * @min_rate: Minimim rate for PLLs with single VCO range
+ * @max_rate: Maximun rate for PLLs with single VCO range
* @clkr: regmap clock handle
*/
struct clk_alpha_pll {
@@ -37,8 +39,11 @@ struct clk_alpha_pll {
#define SUPPORTS_OFFLINE_REQ BIT(0)
#define SUPPORTS_16BIT_ALPHA BIT(1)
#define SUPPORTS_FSM_MODE BIT(2)
+#define SUPPORTS_DYNAMIC_UPDATE BIT(3)
u8 flags;
+ unsigned long min_rate;
+ unsigned long max_rate;
struct clk_regmap clkr;
};
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH 2/6] clk: qcom: Make clk_alpha_pll_configure available to modules
From: Rajendra Nayak @ 2017-04-05 4:55 UTC (permalink / raw)
To: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rajendra Nayak
In-Reply-To: <1491368129-24721-1-git-send-email-rnayak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Allow clk_alpha_pll_configure to be called from loadable
kernel modules.
Signed-off-by: Rajendra Nayak <rnayak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
drivers/clk/qcom/clk-alpha-pll.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index ecb9e7f..7b06e21 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -141,6 +141,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
if (pll->flags & SUPPORTS_FSM_MODE)
qcom_pll_set_fsm_mode(regmap, off + PLL_MODE, 6, 0);
}
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
{
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 3/6] clk: qcom: Add CPU clock driver for msm8996
From: Rajendra Nayak @ 2017-04-05 4:55 UTC (permalink / raw)
To: sboyd, mturquette; +Cc: linux-clk, linux-arm-msm, devicetree, Rajendra Nayak
In-Reply-To: <1491368129-24721-1-git-send-email-rnayak@codeaurora.org>
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below
+-------+
XO | |
+------------------>0 |
| |
PLL/2 | SMUX +----+
+------->1 | |
| | | |
| +-------+ | +-------+
| +---->0 |
| | |
+---------------+ | +----------->1 | CPU clk
|Primary PLL +----+ PLL_EARLY | | +------>
| +------+-----------+ +------>2 PMUX |
+---------------+ | | | |
| +------+ | +-->3 |
+--^+ ACD +-----+ | +-------+
+---------------+ +------+ |
|Alt PLL | |
| +---------------------------+
+---------------+ PLL_EARLY
The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.
The primary PLL operates on a single VCO range, between 600Mhz
and 3Ghz. However the CPUs do support OPPs with frequencies
between 300Mhz and 600Mhz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.
So for frequencies above 600Mhz we follow the following path
Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300Mhz and 600Mhz we follow
Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Support for this is added in a subsequent patch as well.
ACD stands for Adaptive Clock Distribution and is used to
detect voltage droops. We do not add support for ACD as yet.
This can be added at a later point as needed.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
.../devicetree/bindings/clock/qcom,kryocc.txt | 17 +
drivers/clk/qcom/Kconfig | 8 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/clk-cpu-8996.c | 388 +++++++++++++++++++++
4 files changed, 414 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
diff --git a/Documentation/devicetree/bindings/clock/qcom,kryocc.txt b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
new file mode 100644
index 0000000..c45de03
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
@@ -0,0 +1,17 @@
+Qualcomm CPUSS clock controller for Kryo CPUs
+----------------------------------------------------
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+ "qcom,apcc-msm8996"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+
+Example:
+ kryocc: clock-controller@6400000 {
+ compatible = "qcom,apcc-msm8996";
+ reg = <0x6400000 0x90000>;
+ #clock-cells = <1>;
+ };
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 5fb8d74..94d4a8f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -187,3 +187,11 @@ config MSM_MMCC_8996
Support for the multimedia clock controller on msm8996 devices.
Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc.
+
+config MSM_APCC_8996
+ tristate "MSM8996 CPU Clock Controller"
+ depends on COMMON_CLK_QCOM
+ help
+ Support for the CPU clock controller on msm8996 devices.
+ Say Y if you want to support CPU clock scaling using CPUfreq
+ drivers for dyanmic power management.
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 1c3e222..bc452a6 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -30,5 +30,6 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
+obj-$(CONFIG_MSM_APCC_8996) += clk-cpu-8996.o
obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index 0000000..bc60111
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "clk-alpha-pll.h"
+
+#define VCO(a, b, c) { \
+ .val = a,\
+ .min_freq = b,\
+ .max_freq = c,\
+}
+
+#define DIV_2_INDEX 0
+#define PLL_INDEX 1
+#define ACD_INDEX 2
+#define ALT_INDEX 3
+
+/* PLLs */
+
+static const struct alpha_pll_config hfpll_config = {
+ .l = 60,
+ .config_ctl_val = 0x200d4828,
+ .config_ctl_hi_val = 0x006,
+ .pre_div_mask = BIT(12),
+ .post_div_mask = 0x3 << 8,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_pll = {
+ .offset = 0x80000,
+ .min_rate = 600000000,
+ .max_rate = 3000000000,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_16BIT_ALPHA
+ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "perfcl_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+static struct clk_alpha_pll pwrcl_pll = {
+ .offset = 0x0,
+ .min_rate = 600000000,
+ .max_rate = 3000000000,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_16BIT_ALPHA
+ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pwrcl_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+static const struct pll_vco alt_pll_vco_modes[] = {
+ VCO(3, 250000000, 500000000),
+ VCO(2, 500000000, 750000000),
+ VCO(1, 750000000, 1000000000),
+ VCO(0, 1000000000, 2150400000),
+};
+
+static const struct alpha_pll_config altpll_config = {
+ .l = 16,
+ .vco_val = 0x3 << 20,
+ .vco_mask = 0x3 << 20,
+ .config_ctl_val = 0x4001051b,
+ .post_div_mask = 0x3 << 8,
+ .post_div_val = 0x1,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_alt_pll = {
+ .offset = 0x80100,
+ .vco_table = alt_pll_vco_modes,
+ .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+ .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_alt_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+static struct clk_alpha_pll pwrcl_alt_pll = {
+ .offset = 0x100,
+ .vco_table = alt_pll_vco_modes,
+ .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+ .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_alt_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+/* Mux'es */
+
+struct clk_cpu_8996_mux {
+ u32 reg;
+ u32 shift;
+ u32 width;
+ struct clk_hw *pll;
+ struct clk_regmap clkr;
+};
+
+static inline
+struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
+{
+ return container_of(to_clk_regmap(hw), struct clk_cpu_8996_mux, clkr);
+}
+
+static u8 clk_cpu_8996_mux_get_parent(struct clk_hw *hw)
+{
+ unsigned int val;
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ unsigned int mask = GENMASK(cpuclk->width - 1, 0);
+
+ regmap_read(clkr->regmap, cpuclk->reg, &val);
+
+ val >>= cpuclk->shift;
+ val &= mask;
+
+ return val;
+}
+
+static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ unsigned int val;
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ unsigned int mask = GENMASK(cpuclk->width + cpuclk->shift - 1,
+ cpuclk->shift);
+
+ val = index;
+ val = cpuclk->shift;
+
+ return regmap_update_bits(clkr->regmap, cpuclk->reg, mask, val);
+}
+
+static int
+clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ struct clk_hw *parent = cpuclk->pll;
+
+ if (!cpuclk->pll)
+ return -EINVAL;
+
+ req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
+ req->best_parent_hw = parent;
+
+ return 0;
+}
+
+const struct clk_ops clk_cpu_8996_mux_ops = {
+ .set_parent = clk_cpu_8996_mux_set_parent,
+ .get_parent = clk_cpu_8996_mux_get_parent,
+ .determine_rate = clk_cpu_8996_mux_determine_rate,
+};
+
+static struct clk_cpu_8996_mux pwrcl_smux = {
+ .reg = 0x40,
+ .shift = 2,
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_smux",
+ .parent_names = (const char *[]){
+ "xo",
+ "pwrcl_pll_main",
+ },
+ .num_parents = 2,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux perfcl_smux = {
+ .reg = 0x80040,
+ .shift = 2,
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_smux",
+ .parent_names = (const char *[]){
+ "xo",
+ "perfcl_pll_main",
+ },
+ .num_parents = 2,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux pwrcl_pmux = {
+ .reg = 0x40,
+ .shift = 0,
+ .width = 2,
+ .pll = &pwrcl_pll.clkr.hw,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_pmux",
+ .parent_names = (const char *[]){
+ "pwrcl_smux",
+ "pwrcl_pll",
+ "pwrcl_pll_acd",
+ "pwrcl_alt_pll",
+ },
+ .num_parents = 4,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux perfcl_pmux = {
+ .reg = 0x80040,
+ .shift = 0,
+ .width = 2,
+ .pll = &perfcl_pll.clkr.hw,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_pmux",
+ .parent_names = (const char *[]){
+ "perfcl_smux",
+ "perfcl_pll",
+ "pwrcl_pll_acd",
+ "perfcl_alt_pll",
+ },
+ .num_parents = 4,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct regmap_config cpu_msm8996_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x80210,
+ .fast_io = true,
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
+static const struct of_device_id match_table[] = {
+ { .compatible = "qcom,apcc-msm8996" },
+ {}
+};
+
+struct clk_regmap *clks[] = {
+ /* PLLs */
+ &perfcl_pll.clkr,
+ &pwrcl_pll.clkr,
+ &perfcl_alt_pll.clkr,
+ &pwrcl_alt_pll.clkr,
+ /* MUXs */
+ &perfcl_smux.clkr,
+ &pwrcl_smux.clkr,
+ &perfcl_pmux.clkr,
+ &pwrcl_pmux.clkr,
+};
+
+struct clk_hw_clks {
+ unsigned int num;
+ struct clk_hw *hws[];
+};
+
+static int
+qcom_cpu_clk_msm8996_register_clks(struct device *dev, struct clk_hw_clks *hws,
+ struct regmap *regmap)
+{
+ int i, ret;
+
+ hws->hws[0] = clk_hw_register_fixed_factor(dev, "perfcl_pll_main",
+ "perfcl_pll",
+ CLK_SET_RATE_PARENT, 1, 2);
+ perfcl_smux.pll = hws->hws[0];
+
+ hws->hws[1] = clk_hw_register_fixed_factor(dev, "pwrcl_pll_main",
+ "pwrcl_pll",
+ CLK_SET_RATE_PARENT, 1, 2);
+ pwrcl_smux.pll = hws->hws[1];
+
+ hws->num = 2;
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ ret = devm_clk_register_regmap(dev, clks[i]);
+ if (ret)
+ return ret;
+ }
+
+ clk_alpha_pll_configure(&perfcl_pll, regmap, &hfpll_config);
+ clk_alpha_pll_configure(&pwrcl_pll, regmap, &hfpll_config);
+ clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
+ clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+
+ return ret;
+}
+
+static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
+{
+ int ret;
+ void __iomem *base;
+ struct resource *res;
+ struct regmap *regmap_cpu;
+ struct clk_hw_clks *hws;
+ struct clk_hw_onecell_data *data;
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+
+ data = devm_kzalloc(dev, sizeof(*data) + 2 * sizeof(struct clk_hw *),
+ GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ hws = devm_kzalloc(dev, sizeof(*hws) + 2 * sizeof(struct clk_hw *),
+ GFP_KERNEL);
+ if (!hws)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ regmap_cpu = devm_regmap_init_mmio(dev, base,
+ &cpu_msm8996_regmap_config);
+ if (IS_ERR(regmap_cpu))
+ return PTR_ERR(regmap_cpu);
+
+ ret = qcom_cpu_clk_msm8996_register_clks(dev, hws, regmap_cpu);
+ if (ret)
+ return ret;
+
+ data->hws[0] = &pwrcl_pmux.clkr.hw;
+ data->hws[1] = &perfcl_pmux.clkr.hw;
+
+ data->num = 2;
+
+ platform_set_drvdata(pdev, hws);
+
+ return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, data);
+}
+
+static int qcom_cpu_clk_msm8996_driver_remove(struct platform_device *pdev)
+{
+ int i;
+ struct device *dev = &pdev->dev;
+ struct clk_hw_clks *hws = platform_get_drvdata(pdev);
+
+ for (i = 0; i < hws->num; i++)
+ clk_hw_unregister_fixed_rate(hws->hws[i]);
+
+ of_clk_del_provider(dev->of_node);
+
+ return 0;
+}
+
+static struct platform_driver qcom_cpu_clk_msm8996_driver = {
+ .probe = qcom_cpu_clk_msm8996_driver_probe,
+ .remove = qcom_cpu_clk_msm8996_driver_remove,
+ .driver = {
+ .name = "qcom-apcc-msm8996",
+ .of_match_table = match_table,
+ },
+};
+
+module_platform_driver(qcom_cpu_clk_msm8996_driver);
+
+MODULE_ALIAS("platform:apcc-msm8996");
+MODULE_DESCRIPTION("QCOM MSM8996 CPU clock Driver");
+MODULE_LICENSE("GPL v2");
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH 4/6] clk: qcom: cpu-8996: Add support to switch to alternate PLL
From: Rajendra Nayak @ 2017-04-05 4:55 UTC (permalink / raw)
To: sboyd, mturquette; +Cc: linux-clk, linux-arm-msm, devicetree, Rajendra Nayak
In-Reply-To: <1491368129-24721-1-git-send-email-rnayak@codeaurora.org>
Each of the CPU clusters on msm8996 and powered via a primary
PLL and a secondary PLL. The primary PLL is what drivers the
CPU clk, except for times when we are reprogramming the PLL
itself, when we temporarily switch to an alternate PLL.
Use clock rate change notifiers to support this.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
drivers/clk/qcom/clk-cpu-8996.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index bc60111..9bb25be 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -119,10 +119,14 @@ struct clk_cpu_8996_mux {
u32 reg;
u32 shift;
u32 width;
+ struct notifier_block nb;
struct clk_hw *pll;
struct clk_regmap clkr;
};
+#define to_clk_cpu_8996_mux_nb(_nb) \
+ container_of(_nb, struct clk_cpu_8996_mux, nb)
+
static inline
struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
{
@@ -173,6 +177,27 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
return 0;
}
+int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ int ret;
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+ break;
+ case POST_RATE_CHANGE:
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, PLL_INDEX);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return notifier_from_errno(ret);
+};
+
const struct clk_ops clk_cpu_8996_mux_ops = {
.set_parent = clk_cpu_8996_mux_set_parent,
.get_parent = clk_cpu_8996_mux_get_parent,
@@ -216,6 +241,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
.shift = 0,
.width = 2,
.pll = &pwrcl_pll.clkr.hw,
+ .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
.parent_names = (const char *[]){
@@ -235,6 +261,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
.shift = 0,
.width = 2,
.pll = &perfcl_pll.clkr.hw,
+ .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
.parent_names = (const char *[]){
@@ -310,6 +337,14 @@ struct clk_hw_clks {
clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+ ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
+ if (ret)
+ return ret;
+
+ ret = clk_notifier_register(perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
+ if (ret)
+ return ret;
+
return ret;
}
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH 5/6] clk: qcom: cpu-8996: Add support to switch below 600Mhz
From: Rajendra Nayak @ 2017-04-05 4:55 UTC (permalink / raw)
To: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rajendra Nayak
In-Reply-To: <1491368129-24721-1-git-send-email-rnayak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
The CPU clock controllers primary PLL operates on a single VCO range,
between 600Mhz and 3Ghz. However the CPUs do support OPPs with
frequencies between 300Mhz and 600Mhz. In order to support running the
CPUs at those frequencies we end up having to lock the PLL at twice the
rate and drive the CPU clk via the PLL/2 output and SMUX.
So for frequencies above 600Mhz we follow the following path
Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300Mhz and 600Mhz we follow
Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Signed-off-by: Rajendra Nayak <rnayak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
drivers/clk/qcom/clk-cpu-8996.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 9bb25be..79db4e8 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -28,6 +28,7 @@
#define PLL_INDEX 1
#define ACD_INDEX 2
#define ALT_INDEX 3
+#define DIV_2_THRESHOLD 600000000
/* PLLs */
@@ -121,6 +122,7 @@ struct clk_cpu_8996_mux {
u32 width;
struct notifier_block nb;
struct clk_hw *pll;
+ struct clk_hw *pll_div_2;
struct clk_regmap clkr;
};
@@ -171,6 +173,13 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
if (!cpuclk->pll)
return -EINVAL;
+ if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+ if (req->rate < (DIV_2_THRESHOLD / 2))
+ return -EINVAL;
+
+ parent = cpuclk->pll_div_2;
+ }
+
req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
req->best_parent_hw = parent;
@@ -182,13 +191,19 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
{
int ret;
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+ struct clk_notifier_data *cnd = data;
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
break;
case POST_RATE_CHANGE:
- ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, PLL_INDEX);
+ if (cnd->new_rate < DIV_2_THRESHOLD)
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+ DIV_2_INDEX);
+ else
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+ PLL_INDEX);
break;
default:
ret = 0;
@@ -241,6 +256,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
.shift = 0,
.width = 2,
.pll = &pwrcl_pll.clkr.hw,
+ .pll_div_2 = &pwrcl_smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
@@ -261,6 +277,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
.shift = 0,
.width = 2,
.pll = &perfcl_pll.clkr.hw,
+ .pll_div_2 = &perfcl_smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 6/6] arm64: dts: msm8996: Add CPU clock controller node
From: Rajendra Nayak @ 2017-04-05 4:55 UTC (permalink / raw)
To: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rajendra Nayak
In-Reply-To: <1491368129-24721-1-git-send-email-rnayak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Add the DT node for Kryo CPU clock controller on msm8996
devices.
Signed-off-by: Rajendra Nayak <rnayak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
arch/arm64/boot/dts/qcom/msm8996.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index ed7223d..baae195 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -311,6 +311,12 @@
reg = <0x300000 0x90000>;
};
+ kryocc: clock-controller@6400000 {
+ compatible = "qcom,apcc-msm8996";
+ reg = <0x6400000 0x90000>;
+ #clock-cells = <1>;
+ };
+
blsp1_spi0: spi@07575000 {
compatible = "qcom,spi-qup-v2.2.1";
reg = <0x07575000 0x600>;
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: Re: [PATCH v3 04/11] drm/sun4i: abstract the layer type
From: Icenowy Zheng @ 2017-04-05 5:23 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: linux-arm-kernel, Sean Paul, linux-sunxi, Rob Herring,
linux-kernel, devicetree, Jernej Skrabec, Maxime Ripard,
linux-clk, dri-devel
2017年4月5日 10:27于 Chen-Yu Tsai <wens@csie.org>写道:
>
> On Wed, Apr 5, 2017 at 3:53 AM, Icenowy Zheng <icenowy@aosc.io> wrote:
> >
> >
> > 在 2017年04月05日 03:28, Sean Paul 写道:
> >>
> >> On Thu, Mar 30, 2017 at 03:46:06AM +0800, Icenowy Zheng wrote:
> >>>
> >>> As we are going to add support for the Allwinner DE2 Mixer in sun4i-drm
> >>> driver, we will finally have two types of layer.
> >>>
> >>> Abstract the layer type to void * and a ops struct, which contains the
> >>> only function used by crtc -- get the drm_plane struct of the layer.
> >>>
> >>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> >>> ---
> >>> Refactored patch in v3.
> >>>
> >>> drivers/gpu/drm/sun4i/sun4i_crtc.c | 19 +++++++++++--------
> >>> drivers/gpu/drm/sun4i/sun4i_crtc.h | 3 ++-
> >>> drivers/gpu/drm/sun4i/sun4i_layer.c | 19 ++++++++++++++++++-
> >>> drivers/gpu/drm/sun4i/sun4i_layer.h | 2 +-
> >>> drivers/gpu/drm/sun4i/sunxi_layer.h | 17 +++++++++++++++++
> >>> 5 files changed, 49 insertions(+), 11 deletions(-)
> >>> create mode 100644 drivers/gpu/drm/sun4i/sunxi_layer.h
> >>>
> >>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c
> >>> b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> >>> index 3c876c3a356a..33854ee7f636 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
> >>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> >>> @@ -29,6 +29,7 @@
> >>> #include "sun4i_crtc.h"
> >>> #include "sun4i_drv.h"
> >>> #include "sun4i_layer.h"
> >>> +#include "sunxi_layer.h"
> >>> #include "sun4i_tcon.h"
> >>>
> >>> static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc,
> >>> @@ -149,7 +150,7 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device
> >>> *drm,
> >>> scrtc->tcon = tcon;
> >>>
> >>> /* Create our layers */
> >>> - scrtc->layers = sun4i_layers_init(drm, scrtc->backend);
> >>> + scrtc->layers = (void **)sun4i_layers_init(drm, scrtc);
> >>> if (IS_ERR(scrtc->layers)) {
> >>> dev_err(drm->dev, "Couldn't create the planes\n");
> >>> return NULL;
> >>> @@ -157,14 +158,15 @@ struct sun4i_crtc *sun4i_crtc_init(struct
> >>> drm_device *drm,
> >>>
> >>> /* find primary and cursor planes for drm_crtc_init_with_planes
> >>> */
> >>> for (i = 0; scrtc->layers[i]; i++) {
> >>> - struct sun4i_layer *layer = scrtc->layers[i];
> >>> + void *layer = scrtc->layers[i];
> >>> + struct drm_plane *plane =
> >>> scrtc->layer_ops->get_plane(layer);
> >>>
> >>> - switch (layer->plane.type) {
> >>> + switch (plane->type) {
> >>> case DRM_PLANE_TYPE_PRIMARY:
> >>> - primary = &layer->plane;
> >>> + primary = plane;
> >>> break;
> >>> case DRM_PLANE_TYPE_CURSOR:
> >>> - cursor = &layer->plane;
> >>> + cursor = plane;
> >>> break;
> >>> default:
> >>> break;
> >>> @@ -190,10 +192,11 @@ struct sun4i_crtc *sun4i_crtc_init(struct
> >>> drm_device *drm,
> >>> /* Set possible_crtcs to this crtc for overlay planes */
> >>> for (i = 0; scrtc->layers[i]; i++) {
> >>> uint32_t possible_crtcs =
> >>> BIT(drm_crtc_index(&scrtc->crtc));
> >>> - struct sun4i_layer *layer = scrtc->layers[i];
> >>> + void *layer = scrtc->layers[i];
> >>> + struct drm_plane *plane =
> >>> scrtc->layer_ops->get_plane(layer);
> >>>
> >>> - if (layer->plane.type == DRM_PLANE_TYPE_OVERLAY)
> >>> - layer->plane.possible_crtcs = possible_crtcs;
> >>> + if (plane->type == DRM_PLANE_TYPE_OVERLAY)
> >>> + plane->possible_crtcs = possible_crtcs;
> >>> }
> >>>
> >>> return scrtc;
> >>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.h
> >>> b/drivers/gpu/drm/sun4i/sun4i_crtc.h
> >>> index 230cb8f0d601..a4036ee44cf8 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.h
> >>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.h
> >>> @@ -19,7 +19,8 @@ struct sun4i_crtc {
> >>>
> >>> struct sun4i_backend *backend;
> >>> struct sun4i_tcon *tcon;
> >>> - struct sun4i_layer **layers;
> >>> + void **layers;
> >>> + const struct sunxi_layer_ops *layer_ops;
> >>
> >>
> >> I think you should probably take a different approach to abstract the
> >> layer
> >> type. How about creating
> >>
> >> struct sunxi_layer {
> >> struct drm_plane plane;
> >> }
> >>
> >> base and then subclassing that for sun4i and sun8i? By doing this you can
> >> avoid
> >> the nasty casting and you can also get rid of the get_plane() hook and
> >> layer_ops.
> >
> >
> > For the situation that using ** things are easily to get weird.
>
> That code could be reworked, by initializing the layers directly within
> the crtc init code. If you look at rockchip's drm driver, you'll see
> they do this. There is a good reason to do it this way, as you need
> to first create the primary and cursor layers, pass them in when you
> create the crtc, then initialize any additional layers with the
> possible_crtcs bitmap.
But furthurly maybe more layers will be created for DE2 mixer, and may even depends on mixer type (On A83T/H3/A64/H5 mixer1 has fewer channel than mixer0).
>
> In our driver we are currently initializing all layers, then going
> back and filling in possible_crtcs for the extra layers.
>
> And as Maxime and I mentioned in the other thread, we don't really
> need to keep a reference to **layers.
>
> Regards
> ChenYu
>
> >
> >>
> >> Sean
> >>
> >>
> >>
> >>> };
> >>>
> >>> static inline struct sun4i_crtc *drm_crtc_to_sun4i_crtc(struct drm_crtc
> >>> *crtc)
> >>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c
> >>> b/drivers/gpu/drm/sun4i/sun4i_layer.c
> >>> index f26bde5b9117..bc4a70d6968b 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
> >>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
> >>> @@ -16,7 +16,9 @@
> >>> #include <drm/drmP.h>
> >>>
> >>> #include "sun4i_backend.h"
> >>> +#include "sun4i_crtc.h"
> >>> #include "sun4i_layer.h"
> >>> +#include "sunxi_layer.h"
> >>>
> >>> struct sun4i_plane_desc {
> >>> enum drm_plane_type type;
> >>> @@ -100,6 +102,17 @@ static const struct sun4i_plane_desc
> >>> sun4i_backend_planes[] = {
> >>> },
> >>> };
> >>>
> >>> +static struct drm_plane *sun4i_layer_get_plane(void *layer)
> >>> +{
> >>> + struct sun4i_layer *sun4i_layer = layer;
> >>> +
> >>> + return &sun4i_layer->plane;
> >>> +}
> >>> +
> >>> +static const struct sunxi_layer_ops layer_ops = {
> >>> + .get_plane = sun4i_layer_get_plane,
> >>> +};
> >>> +
> >>> static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
> >>> struct sun4i_backend
> >>> *backend,
> >>> const struct
> >>> sun4i_plane_desc *plane)
> >>> @@ -129,9 +142,10 @@ static struct sun4i_layer
> >>> *sun4i_layer_init_one(struct drm_device *drm,
> >>> }
> >>>
> >>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
> >>> - struct sun4i_backend *backend)
> >>> + struct sun4i_crtc *crtc)
> >>> {
> >>> struct sun4i_layer **layers;
> >>> + struct sun4i_backend *backend = crtc->backend;
> >>> int i;
> >>>
> >>> layers = devm_kcalloc(drm->dev, ARRAY_SIZE(sun4i_backend_planes)
> >>> + 1,
> >>> @@ -181,5 +195,8 @@ struct sun4i_layer **sun4i_layers_init(struct
> >>> drm_device *drm,
> >>> layers[i] = layer;
> >>> };
> >>>
> >>> + /* Assign layer ops to the CRTC */
> >>> + crtc->layer_ops = &layer_ops;
> >>> +
> >>> return layers;
> >>> }
> >>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h
> >>> b/drivers/gpu/drm/sun4i/sun4i_layer.h
> >>> index 4be1f0919df2..425eea7b9e3b 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.h
> >>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.h
> >>> @@ -27,6 +27,6 @@ plane_to_sun4i_layer(struct drm_plane *plane)
> >>> }
> >>>
> >>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
> >>> - struct sun4i_backend *backend);
> >>> + struct sun4i_crtc *crtc);
> >>>
> >>> #endif /* _SUN4I_LAYER_H_ */
> >>> diff --git a/drivers/gpu/drm/sun4i/sunxi_layer.h
> >>> b/drivers/gpu/drm/sun4i/sunxi_layer.h
> >>> new file mode 100644
> >>> index 000000000000..d8838ec39299
> >>> --- /dev/null
> >>> +++ b/drivers/gpu/drm/sun4i/sunxi_layer.h
> >>> @@ -0,0 +1,17 @@
> >>> +/*
> >>> + * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
> >>> + *
> >>> + * 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_LAYER_H_
> >>> +#define _SUNXI_LAYER_H_
> >>> +
> >>> +struct sunxi_layer_ops {
> >>> + struct drm_plane *(*get_plane)(void *layer);
> >>> +};
> >>> +
> >>> +#endif /* _SUNXI_LAYER_H_ */
> >>> --
> >>> 2.12.0
> >>>
> >>>
> >>> _______________________________________________
> >>> linux-arm-kernel mailing list
> >>> linux-arm-kernel@lists.infradead.org
> >>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> >>
> >>
> >
> > --
> > 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@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
--
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@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [linux-sunxi] Re: [PATCH v3 04/11] drm/sun4i: abstract the layer type
From: Icenowy Zheng @ 2017-04-05 5:23 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: devicetree, Jernej Skrabec, linux-kernel, dri-devel, linux-sunxi,
Rob Herring, Maxime Ripard, linux-clk, linux-arm-kernel
2017年4月5日 10:27于 Chen-Yu Tsai <wens@csie.org>写道:
>
> On Wed, Apr 5, 2017 at 3:53 AM, Icenowy Zheng <icenowy@aosc.io> wrote:
> >
> >
> > 在 2017年04月05日 03:28, Sean Paul 写道:
> >>
> >> On Thu, Mar 30, 2017 at 03:46:06AM +0800, Icenowy Zheng wrote:
> >>>
> >>> As we are going to add support for the Allwinner DE2 Mixer in sun4i-drm
> >>> driver, we will finally have two types of layer.
> >>>
> >>> Abstract the layer type to void * and a ops struct, which contains the
> >>> only function used by crtc -- get the drm_plane struct of the layer.
> >>>
> >>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> >>> ---
> >>> Refactored patch in v3.
> >>>
> >>> drivers/gpu/drm/sun4i/sun4i_crtc.c | 19 +++++++++++--------
> >>> drivers/gpu/drm/sun4i/sun4i_crtc.h | 3 ++-
> >>> drivers/gpu/drm/sun4i/sun4i_layer.c | 19 ++++++++++++++++++-
> >>> drivers/gpu/drm/sun4i/sun4i_layer.h | 2 +-
> >>> drivers/gpu/drm/sun4i/sunxi_layer.h | 17 +++++++++++++++++
> >>> 5 files changed, 49 insertions(+), 11 deletions(-)
> >>> create mode 100644 drivers/gpu/drm/sun4i/sunxi_layer.h
> >>>
> >>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c
> >>> b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> >>> index 3c876c3a356a..33854ee7f636 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
> >>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> >>> @@ -29,6 +29,7 @@
> >>> #include "sun4i_crtc.h"
> >>> #include "sun4i_drv.h"
> >>> #include "sun4i_layer.h"
> >>> +#include "sunxi_layer.h"
> >>> #include "sun4i_tcon.h"
> >>>
> >>> static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc,
> >>> @@ -149,7 +150,7 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device
> >>> *drm,
> >>> scrtc->tcon = tcon;
> >>>
> >>> /* Create our layers */
> >>> - scrtc->layers = sun4i_layers_init(drm, scrtc->backend);
> >>> + scrtc->layers = (void **)sun4i_layers_init(drm, scrtc);
> >>> if (IS_ERR(scrtc->layers)) {
> >>> dev_err(drm->dev, "Couldn't create the planes\n");
> >>> return NULL;
> >>> @@ -157,14 +158,15 @@ struct sun4i_crtc *sun4i_crtc_init(struct
> >>> drm_device *drm,
> >>>
> >>> /* find primary and cursor planes for drm_crtc_init_with_planes
> >>> */
> >>> for (i = 0; scrtc->layers[i]; i++) {
> >>> - struct sun4i_layer *layer = scrtc->layers[i];
> >>> + void *layer = scrtc->layers[i];
> >>> + struct drm_plane *plane =
> >>> scrtc->layer_ops->get_plane(layer);
> >>>
> >>> - switch (layer->plane.type) {
> >>> + switch (plane->type) {
> >>> case DRM_PLANE_TYPE_PRIMARY:
> >>> - primary = &layer->plane;
> >>> + primary = plane;
> >>> break;
> >>> case DRM_PLANE_TYPE_CURSOR:
> >>> - cursor = &layer->plane;
> >>> + cursor = plane;
> >>> break;
> >>> default:
> >>> break;
> >>> @@ -190,10 +192,11 @@ struct sun4i_crtc *sun4i_crtc_init(struct
> >>> drm_device *drm,
> >>> /* Set possible_crtcs to this crtc for overlay planes */
> >>> for (i = 0; scrtc->layers[i]; i++) {
> >>> uint32_t possible_crtcs =
> >>> BIT(drm_crtc_index(&scrtc->crtc));
> >>> - struct sun4i_layer *layer = scrtc->layers[i];
> >>> + void *layer = scrtc->layers[i];
> >>> + struct drm_plane *plane =
> >>> scrtc->layer_ops->get_plane(layer);
> >>>
> >>> - if (layer->plane.type == DRM_PLANE_TYPE_OVERLAY)
> >>> - layer->plane.possible_crtcs = possible_crtcs;
> >>> + if (plane->type == DRM_PLANE_TYPE_OVERLAY)
> >>> + plane->possible_crtcs = possible_crtcs;
> >>> }
> >>>
> >>> return scrtc;
> >>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.h
> >>> b/drivers/gpu/drm/sun4i/sun4i_crtc.h
> >>> index 230cb8f0d601..a4036ee44cf8 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.h
> >>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.h
> >>> @@ -19,7 +19,8 @@ struct sun4i_crtc {
> >>>
> >>> struct sun4i_backend *backend;
> >>> struct sun4i_tcon *tcon;
> >>> - struct sun4i_layer **layers;
> >>> + void **layers;
> >>> + const struct sunxi_layer_ops *layer_ops;
> >>
> >>
> >> I think you should probably take a different approach to abstract the
> >> layer
> >> type. How about creating
> >>
> >> struct sunxi_layer {
> >> struct drm_plane plane;
> >> }
> >>
> >> base and then subclassing that for sun4i and sun8i? By doing this you can
> >> avoid
> >> the nasty casting and you can also get rid of the get_plane() hook and
> >> layer_ops.
> >
> >
> > For the situation that using ** things are easily to get weird.
>
> That code could be reworked, by initializing the layers directly within
> the crtc init code. If you look at rockchip's drm driver, you'll see
> they do this. There is a good reason to do it this way, as you need
> to first create the primary and cursor layers, pass them in when you
> create the crtc, then initialize any additional layers with the
> possible_crtcs bitmap.
But furthurly maybe more layers will be created for DE2 mixer, and may even depends on mixer type (On A83T/H3/A64/H5 mixer1 has fewer channel than mixer0).
>
> In our driver we are currently initializing all layers, then going
> back and filling in possible_crtcs for the extra layers.
>
> And as Maxime and I mentioned in the other thread, we don't really
> need to keep a reference to **layers.
>
> Regards
> ChenYu
>
> >
> >>
> >> Sean
> >>
> >>
> >>
> >>> };
> >>>
> >>> static inline struct sun4i_crtc *drm_crtc_to_sun4i_crtc(struct drm_crtc
> >>> *crtc)
> >>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c
> >>> b/drivers/gpu/drm/sun4i/sun4i_layer.c
> >>> index f26bde5b9117..bc4a70d6968b 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
> >>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
> >>> @@ -16,7 +16,9 @@
> >>> #include <drm/drmP.h>
> >>>
> >>> #include "sun4i_backend.h"
> >>> +#include "sun4i_crtc.h"
> >>> #include "sun4i_layer.h"
> >>> +#include "sunxi_layer.h"
> >>>
> >>> struct sun4i_plane_desc {
> >>> enum drm_plane_type type;
> >>> @@ -100,6 +102,17 @@ static const struct sun4i_plane_desc
> >>> sun4i_backend_planes[] = {
> >>> },
> >>> };
> >>>
> >>> +static struct drm_plane *sun4i_layer_get_plane(void *layer)
> >>> +{
> >>> + struct sun4i_layer *sun4i_layer = layer;
> >>> +
> >>> + return &sun4i_layer->plane;
> >>> +}
> >>> +
> >>> +static const struct sunxi_layer_ops layer_ops = {
> >>> + .get_plane = sun4i_layer_get_plane,
> >>> +};
> >>> +
> >>> static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
> >>> struct sun4i_backend
> >>> *backend,
> >>> const struct
> >>> sun4i_plane_desc *plane)
> >>> @@ -129,9 +142,10 @@ static struct sun4i_layer
> >>> *sun4i_layer_init_one(struct drm_device *drm,
> >>> }
> >>>
> >>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
> >>> - struct sun4i_backend *backend)
> >>> + struct sun4i_crtc *crtc)
> >>> {
> >>> struct sun4i_layer **layers;
> >>> + struct sun4i_backend *backend = crtc->backend;
> >>> int i;
> >>>
> >>> layers = devm_kcalloc(drm->dev, ARRAY_SIZE(sun4i_backend_planes)
> >>> + 1,
> >>> @@ -181,5 +195,8 @@ struct sun4i_layer **sun4i_layers_init(struct
> >>> drm_device *drm,
> >>> layers[i] = layer;
> >>> };
> >>>
> >>> + /* Assign layer ops to the CRTC */
> >>> + crtc->layer_ops = &layer_ops;
> >>> +
> >>> return layers;
> >>> }
> >>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h
> >>> b/drivers/gpu/drm/sun4i/sun4i_layer.h
> >>> index 4be1f0919df2..425eea7b9e3b 100644
> >>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.h
> >>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.h
> >>> @@ -27,6 +27,6 @@ plane_to_sun4i_layer(struct drm_plane *plane)
> >>> }
> >>>
> >>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
> >>> - struct sun4i_backend *backend);
> >>> + struct sun4i_crtc *crtc);
> >>>
> >>> #endif /* _SUN4I_LAYER_H_ */
> >>> diff --git a/drivers/gpu/drm/sun4i/sunxi_layer.h
> >>> b/drivers/gpu/drm/sun4i/sunxi_layer.h
> >>> new file mode 100644
> >>> index 000000000000..d8838ec39299
> >>> --- /dev/null
> >>> +++ b/drivers/gpu/drm/sun4i/sunxi_layer.h
> >>> @@ -0,0 +1,17 @@
> >>> +/*
> >>> + * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
> >>> + *
> >>> + * 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_LAYER_H_
> >>> +#define _SUNXI_LAYER_H_
> >>> +
> >>> +struct sunxi_layer_ops {
> >>> + struct drm_plane *(*get_plane)(void *layer);
> >>> +};
> >>> +
> >>> +#endif /* _SUNXI_LAYER_H_ */
> >>> --
> >>> 2.12.0
> >>>
> >>>
> >>> _______________________________________________
> >>> linux-arm-kernel mailing list
> >>> linux-arm-kernel@lists.infradead.org
> >>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> >>
> >>
> >
> > --
> > 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@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [PATCH 1/1] ARM: dts: armada-xp-linksys-mamba: use wan instead of internet for DSA port
From: Ralph Sennhauser @ 2017-04-05 5:28 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Ralph Sennhauser, Jason Cooper, Andrew Lunn, Gregory Clement,
Sebastian Hesselbarth, Rob Herring, Mark Rutland, Russell King,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
The LEDs for the "wan" port are already labeled "mamba:amber:wan" resp.
"mamba:white:wan". So besides being an outlier with regard to the rest
of the product line (see table below) changing the label fixes an
internal inconsistency as well.
This will be visible in user space. Given commit cb4f71c42988 ("ARM:
dts: armada-38x: change order of ethernet DT nodes on Armada 38x") it's
expected to happen anyway. Commit 499400c9ac20 ("ARM: dts:
armada-xp-linksys-mamba: Utilize new DSA binding") switches to the new
bindings, use this opportunity to do it now rather than later.
|-----------------------------------------------------------------|
| Labels used for the case and those used for the DSA ports |
|-----------------------------------------------------------------|
| case labels | armada-385-linksys-* | armada-xp-linksys-mamba |
|---------------|-----------------------|-------------------------|
| internet | wan | internet |
| 1 | lan1 | lan1 |
| 2 | lan2 | lan2 |
| 3 | lan3 | lan3 |
| 4 | lan4 | lan4 |
|-----------------------------------------------------------------|
Signed-off-by: Ralph Sennhauser <ralph.sennhauser-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
Hi everybody,
I underestimated the urge of people to make all the same before. While I do not
particularly like this sort of change I see it coming anyway. So this patch is
meant to make it a deliberate decision so it no longer is an item lurking in
the shadows. Whether this patch gets taken or rejected my goal is reached.
In hindsight wan would have been the better choice.
Ralph
arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
index 9efcf59..0143aed 100644
--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -354,7 +354,7 @@
port@4 {
reg = <4>;
- label = "internet";
+ label = "wan";
};
port@5 {
@@ -452,7 +452,7 @@
port@4 {
reg = <4>;
- label = "internet";
+ label = "wan";
};
port@5 {
--
2.10.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [linux-sunxi] [PATCH 02/11] arm64: allwinner: a64: add NMI controller on A64
From: Maxime Ripard @ 2017-04-05 6:11 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Icenowy Zheng, Lee Jones, Rob Herring, Liam Girdwood, devicetree,
linux-sunxi, linux-kernel, linux-arm-kernel
In-Reply-To: <CAGb2v67BucT8=FTgem3AmSU9XJA7OHoTCq3t3wBzDWyuwzZqaA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 642 bytes --]
On Wed, Apr 05, 2017 at 11:51:45AM +0800, Chen-Yu Tsai wrote:
> On Wed, Apr 5, 2017 at 2:01 AM, Icenowy Zheng <icenowy@aosc.io> wrote:
> > Allwinner A64 SoC features a NMI controller, which is usually connected
> > to the AXP PMIC.
> >
> > Add support for it.
> >
> > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>
> This might not be the best representation of the R_INTC block. Though
> we'd need to change it for all SoCs if we want to be accurate. For now,
What do you think would be a good representation?
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* cpu of_node links broken
From: Wesley Terpstra @ 2017-04-05 6:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt, devicetree-u79uwXL29TY76Z2rM5mHXA
In commit 5590f3196b293574a12be58d06d5e1120d8856ec symlinks from
devices to their OF node were added. Unfortunately, the code looks for
them in cpu_dev_init before they exist (of_core_init has not run).
This results in:
[ 0.010000] cpu cpu0: Error -2 creating of_node link
I don't know if this code used to work and it got broken, but as of
4.6 it does not work and still does not work in 4.11. Moving
of_core_init() before platform_bus_init() in driver_init()
[drivers/base/init.c] fixes the problem for me.
Is there any downside to reordering these function calls?
--
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 10/11] arm64: allwinner: a64: enable AXP803 regulators for Pine64
From: Maxime Ripard @ 2017-04-05 6:13 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Lee Jones, Rob Herring, Chen-Yu Tsai, Liam Girdwood,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170404180145.12897-11-icenowy-h8G6r0blFSE@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 3286 bytes --]
On Wed, Apr 05, 2017 at 02:01:44AM +0800, Icenowy Zheng wrote:
> Add support of AXP803 regulators in the Pine64 device tree, in order to
> enable many future functionalities, e.g. Wi-Fi.
>
> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> ---
> .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 109 +++++++++++++++++++++
> 1 file changed, 109 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> index 2132d8e6cb3d..7da074f95065 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> @@ -106,6 +106,115 @@
> };
> };
>
> +#include "axp803.dtsi"
> +
> +®_aldo1 {
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-name = "vcc-csi";
> +};
> +
> +®_aldo2 {
> + regulator-always-on;
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-name = "vcc-pl";
> +};
> +
> +®_aldo3 {
> + regulator-always-on;
> + regulator-min-microvolt = <2700000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-name = "vcc-pll-avcc";
> +};
> +
> +®_dc1sw {
> + regulator-name = "vcc-phy";
> +};
> +
> +®_dcdc1 {
> + regulator-always-on;
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-name = "vcc-3v3";
> +};
> +
> +®_dcdc2 {
> + regulator-always-on;
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1300000>;
> + regulator-name = "vdd-cpux";
> +};
> +
> +/* DCDC3 is polyphased with DCDC2 */
> +
> +®_dcdc5 {
> + regulator-always-on;
> + regulator-min-microvolt = <1500000>;
> + regulator-max-microvolt = <1500000>;
> + regulator-name = "vcc-dram";
> +};
> +
> +®_dcdc6 {
> + regulator-always-on;
> + regulator-min-microvolt = <1100000>;
> + regulator-max-microvolt = <1100000>;
> + regulator-name = "vdd-sys";
> +};
> +
> +®_dldo1 {
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-name = "vcc-hdmi";
> +};
> +
> +®_dldo2 {
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-name = "vcc-mipi";
> +};
> +
> +®_dldo3 {
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-name = "avdd-csi";
> +};
> +
> +®_dldo4 {
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-name = "vcc-wifi";
> +};
> +
> +®_eldo1 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-name = "cpvdd";
> +};
> +
> +®_eldo3 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-name = "vdd-1v8-csi";
> +};
> +
> +®_fldo1 {
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-name = "vcc-1v2-hsic";
> +};
> +
> +®_fldo2 {
> + regulator-always-on;
> + regulator-min-microvolt = <1100000>;
> + regulator-max-microvolt = <1100000>;
> + regulator-name = "vdd-cpus";
> +};
Why do you need to always power the AR100 on?
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: Re: [PATCH 10/11] arm64: allwinner: a64: enable AXP803 regulators for Pine64
From: Icenowy Zheng @ 2017-04-05 6:15 UTC (permalink / raw)
To: Maxime Ripard
Cc: Rob Herring, linux-kernel, devicetree-u79uwXL29TY76Z2rM5mHXA,
Lee Jones, Liam Girdwood,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Chen-Yu Tsai
2017年4月5日 14:13于 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>写道:
>
> On Wed, Apr 05, 2017 at 02:01:44AM +0800, Icenowy Zheng wrote:
> > Add support of AXP803 regulators in the Pine64 device tree, in order to
> > enable many future functionalities, e.g. Wi-Fi.
> >
> > Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> > ---
> > .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 109 +++++++++++++++++++++
> > 1 file changed, 109 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> > index 2132d8e6cb3d..7da074f95065 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> > @@ -106,6 +106,115 @@
> > };
> > };
> >
> > +#include "axp803.dtsi"
> > +
> > +®_aldo1 {
> > + regulator-min-microvolt = <2800000>;
> > + regulator-max-microvolt = <2800000>;
> > + regulator-name = "vcc-csi";
> > +};
> > +
> > +®_aldo2 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1800000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-pl";
> > +};
> > +
> > +®_aldo3 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <2700000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-pll-avcc";
> > +};
> > +
> > +®_dc1sw {
> > + regulator-name = "vcc-phy";
> > +};
> > +
> > +®_dcdc1 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-3v3";
> > +};
> > +
> > +®_dcdc2 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1000000>;
> > + regulator-max-microvolt = <1300000>;
> > + regulator-name = "vdd-cpux";
> > +};
> > +
> > +/* DCDC3 is polyphased with DCDC2 */
> > +
> > +®_dcdc5 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1500000>;
> > + regulator-max-microvolt = <1500000>;
> > + regulator-name = "vcc-dram";
> > +};
> > +
> > +®_dcdc6 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1100000>;
> > + regulator-max-microvolt = <1100000>;
> > + regulator-name = "vdd-sys";
> > +};
> > +
> > +®_dldo1 {
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-hdmi";
> > +};
> > +
> > +®_dldo2 {
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-mipi";
> > +};
> > +
> > +®_dldo3 {
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "avdd-csi";
> > +};
> > +
> > +®_dldo4 {
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-wifi";
> > +};
> > +
> > +®_eldo1 {
> > + regulator-min-microvolt = <1800000>;
> > + regulator-max-microvolt = <1800000>;
> > + regulator-name = "cpvdd";
> > +};
> > +
> > +®_eldo3 {
> > + regulator-min-microvolt = <1800000>;
> > + regulator-max-microvolt = <1800000>;
> > + regulator-name = "vdd-1v8-csi";
> > +};
> > +
> > +®_fldo1 {
> > + regulator-min-microvolt = <1200000>;
> > + regulator-max-microvolt = <1200000>;
> > + regulator-name = "vcc-1v2-hsic";
> > +};
> > +
> > +®_fldo2 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1100000>;
> > + regulator-max-microvolt = <1100000>;
> > + regulator-name = "vdd-cpus";
> > +};
>
> Why do you need to always power the AR100 on?
It's for CPUS power domain, not the AR100 processor.
Kill it will lead to instantly system hang.
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
> For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [linux-sunxi] Re: [PATCH 10/11] arm64: allwinner: a64: enable AXP803 regulators for Pine64
From: Icenowy Zheng @ 2017-04-05 6:15 UTC (permalink / raw)
To: Maxime Ripard
Cc: Rob Herring, linux-kernel, devicetree, Lee Jones, Liam Girdwood,
linux-arm-kernel, linux-sunxi, Chen-Yu Tsai
2017年4月5日 14:13于 Maxime Ripard <maxime.ripard@free-electrons.com>写道:
>
> On Wed, Apr 05, 2017 at 02:01:44AM +0800, Icenowy Zheng wrote:
> > Add support of AXP803 regulators in the Pine64 device tree, in order to
> > enable many future functionalities, e.g. Wi-Fi.
> >
> > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> > ---
> > .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 109 +++++++++++++++++++++
> > 1 file changed, 109 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> > index 2132d8e6cb3d..7da074f95065 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> > @@ -106,6 +106,115 @@
> > };
> > };
> >
> > +#include "axp803.dtsi"
> > +
> > +®_aldo1 {
> > + regulator-min-microvolt = <2800000>;
> > + regulator-max-microvolt = <2800000>;
> > + regulator-name = "vcc-csi";
> > +};
> > +
> > +®_aldo2 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1800000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-pl";
> > +};
> > +
> > +®_aldo3 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <2700000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-pll-avcc";
> > +};
> > +
> > +®_dc1sw {
> > + regulator-name = "vcc-phy";
> > +};
> > +
> > +®_dcdc1 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-3v3";
> > +};
> > +
> > +®_dcdc2 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1000000>;
> > + regulator-max-microvolt = <1300000>;
> > + regulator-name = "vdd-cpux";
> > +};
> > +
> > +/* DCDC3 is polyphased with DCDC2 */
> > +
> > +®_dcdc5 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1500000>;
> > + regulator-max-microvolt = <1500000>;
> > + regulator-name = "vcc-dram";
> > +};
> > +
> > +®_dcdc6 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1100000>;
> > + regulator-max-microvolt = <1100000>;
> > + regulator-name = "vdd-sys";
> > +};
> > +
> > +®_dldo1 {
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-hdmi";
> > +};
> > +
> > +®_dldo2 {
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-mipi";
> > +};
> > +
> > +®_dldo3 {
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "avdd-csi";
> > +};
> > +
> > +®_dldo4 {
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-name = "vcc-wifi";
> > +};
> > +
> > +®_eldo1 {
> > + regulator-min-microvolt = <1800000>;
> > + regulator-max-microvolt = <1800000>;
> > + regulator-name = "cpvdd";
> > +};
> > +
> > +®_eldo3 {
> > + regulator-min-microvolt = <1800000>;
> > + regulator-max-microvolt = <1800000>;
> > + regulator-name = "vdd-1v8-csi";
> > +};
> > +
> > +®_fldo1 {
> > + regulator-min-microvolt = <1200000>;
> > + regulator-max-microvolt = <1200000>;
> > + regulator-name = "vcc-1v2-hsic";
> > +};
> > +
> > +®_fldo2 {
> > + regulator-always-on;
> > + regulator-min-microvolt = <1100000>;
> > + regulator-max-microvolt = <1100000>;
> > + regulator-name = "vdd-cpus";
> > +};
>
> Why do you need to always power the AR100 on?
It's for CPUS power domain, not the AR100 processor.
Kill it will lead to instantly system hang.
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
>
> --
> 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@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* RE: [PATCH 1/2 v2] dt-bindings: qoriq-clock: Add coreclk
From: Andy Tang @ 2017-04-05 6:16 UTC (permalink / raw)
To: mturquette@baylibre.com, sboyd@codeaurora.org
Cc: robh+dt@kernel.org, mark.rutland@arm.com,
linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Scott Wood
In-Reply-To: <1489977443-33582-1-git-send-email-andy.tang@nxp.com>
Hello Stephen and Michael,
Do you have any comments on this patch set which was acked by Rob?
Regards,
Andy
> -----Original Message-----
> From: Yuantian Tang [mailto:andy.tang@nxp.com]
> Sent: Monday, March 20, 2017 10:37 AM
> To: mturquette@baylibre.com
> Cc: sboyd@codeaurora.org; robh+dt@kernel.org; mark.rutland@arm.com;
> linux-clk@vger.kernel.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Scott Wood
> <oss@buserror.net>; Andy Tang <andy.tang@nxp.com>
> Subject: [PATCH 1/2 v2] dt-bindings: qoriq-clock: Add coreclk
>
> From: Scott Wood <oss@buserror.net>
>
> ls1012a has separate input root clocks for core PLLs versus the platform PLL,
> with the latter described as sysclk in the hw docs.
> Update the qoriq-clock binding to allow a second input clock, named
> "coreclk". If present, this clock will be used for the core PLLs.
>
> Signed-off-by: Scott Wood <oss@buserror.net>
> Signed-off-by: Tang Yuantian <andy.tang@nxp.com>
> Acked-by: Rob Herring <robh@kernel.org>
> ---
> v2:
> -- change the author to Scott
> Documentation/devicetree/bindings/clock/qoriq-clock.txt | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/qoriq-clock.txt
> b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
> index aa3526f..119cafd 100644
> --- a/Documentation/devicetree/bindings/clock/qoriq-clock.txt
> +++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
> @@ -56,6 +56,11 @@ Optional properties:
> - clocks: If clock-frequency is not specified, sysclk may be provided
> as an input clock. Either clock-frequency or clocks must be
> provided.
> + A second input clock, called "coreclk", may be provided if
> + core PLLs are based on a different input clock from the
> + platform PLL.
> +- clock-names: Required if a coreclk is present. Valid names are
> + "sysclk" and "coreclk".
>
> 2. Clock Provider
>
> @@ -72,6 +77,7 @@ second cell is the clock index for the specified type.
> 2 hwaccel index (n in CLKCGnHWACSR)
> 3 fman 0 for fm1, 1 for fm2
> 4 platform pll 0=pll, 1=pll/2, 2=pll/3, 3=pll/4
> + 5 coreclk must be 0
>
> 3. Example
>
> --
> 2.1.0.27.g96db324
^ permalink raw reply
* Re: [PATCH 02/11] arm64: allwinner: a64: add NMI controller on A64
From: Chen-Yu Tsai @ 2017-04-05 6:20 UTC (permalink / raw)
To: Maxime Ripard
Cc: Chen-Yu Tsai, Icenowy Zheng, Lee Jones, Rob Herring,
Liam Girdwood, devicetree, linux-sunxi, linux-kernel,
linux-arm-kernel
In-Reply-To: <20170405061137.n66ectbkl7a2fv5f@lukather>
On Wed, Apr 5, 2017 at 2:11 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> On Wed, Apr 05, 2017 at 11:51:45AM +0800, Chen-Yu Tsai wrote:
>> On Wed, Apr 5, 2017 at 2:01 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
>> > Allwinner A64 SoC features a NMI controller, which is usually connected
>> > to the AXP PMIC.
>> >
>> > Add support for it.
>> >
>> > Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>>
>> This might not be the best representation of the R_INTC block. Though
>> we'd need to change it for all SoCs if we want to be accurate. For now,
>
> What do you think would be a good representation?
My gut feeling is that this is the old INTC from sun4/5i. It's supposed
to be the interrupt controller for the embedded low power core. I've not
done a thorough comparison though.
ChenYu
^ permalink raw reply
* Re: [PATCH v4 0/6] ARM: dts: sunxi: Add CAN node and can0_pins_a pinctrl settings
From: Maxime Ripard @ 2017-04-05 6:22 UTC (permalink / raw)
To: Patrick Menschel
Cc: robh+dt, mark.rutland, linux, wens, devicetree, linux-arm-kernel,
linux-kernel, linux-can
In-Reply-To: <1491330992-9876-1-git-send-email-menschel.p@posteo.de>
[-- Attachment #1: Type: text/plain, Size: 828 bytes --]
On Tue, Apr 04, 2017 at 08:36:26PM +0200, Patrick Menschel wrote:
> The Allwinner A10/A20 SoCs have an on-board CAN (Controller Area Network)
> controller. This patch adds the CAN core to the SoC's include files,
> sun4i-a10.dtsi and sun7i-a20.dtsi.
>
> On linux-can mailing list was a discussion about updating the device tree bindings
> https://lkml.org/lkml/2015/9/17/220
> but it did not progress past writing the documentation file.
> Documentation/devicetree/bindings/net/can/sun4i_can.txt
>
> The CAN controller can be enabled in a board specific dts file as
> described in the documentation file or by using a device tree overlay.
Applied 1 and 4. The others were already merged.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH] mmc: core: add mmc-card hardware reset enable support
From: Richard Leitner @ 2017-04-05 6:23 UTC (permalink / raw)
To: Jaehoon Chung, ulf.hansson, robh+dt, mark.rutland
Cc: shawn.lin, adrian.hunter, linus.walleij, linux-mmc, linux-kernel,
devicetree, dev
In-Reply-To: <ea610a5c-3857-14f8-3039-414bee724223@samsung.com>
On 04/05/2017 06:40 AM, Jaehoon Chung wrote:
> Hi,
>
> On 04/04/2017 11:16 PM, Richard Leitner wrote:
>> Some eMMCs disable their hardware reset line (RST_N) by default. To enable
>> it the host must set the corresponding bit in ECSD. An example for such
>> a device is the Micron MTFCxGACAANA-4M.
>>
>> This patch adds a new mmc-card devicetree property to let the host enable
>> this feature during card initialization.
>>
>> Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
>> ---
>> Documentation/devicetree/bindings/mmc/mmc-card.txt | 3 +++
>> drivers/mmc/core/mmc.c | 21 +++++++++++++++++++++
>> 2 files changed, 24 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.txt b/Documentation/devicetree/bindings/mmc/mmc-card.txt
>> index a70fcd6..8590a40 100644
>> --- a/Documentation/devicetree/bindings/mmc/mmc-card.txt
>> +++ b/Documentation/devicetree/bindings/mmc/mmc-card.txt
>> @@ -12,6 +12,9 @@ Required properties:
>> Optional properties:
>> -broken-hpi : Use this to indicate that the mmc-card has a broken hpi
>> implementation, and that hpi should not be used
>> +-enable-hw-reset : some eMMC devices have disabled the hw reset functionality
>> + (RST_N_FUNCTION) by default. By adding this property the
>> + host will enable it during initialization.
>
> As i know, RST_N_FUNCTION is controlled bit[1:0]
> 0x0 : RST_n disabled (by default)
> 0x1 : permanently enabled
> 0x2 : permanently disabled
>
> I think that it needs to add the description about these..
Ok.
>>
>> Example:
>>
>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>> index b502601..518d0e3 100644
>> --- a/drivers/mmc/core/mmc.c
>> +++ b/drivers/mmc/core/mmc.c
>> @@ -1520,9 +1520,16 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>> int err;
>> u32 cid[4];
>> u32 rocr;
>> + struct device_node *np;
>> + bool enable_rst_n = false;
>>
>> WARN_ON(!host->claimed);
>>
>> + np = mmc_of_find_child_device(host, 0);
>> + if (np && of_device_is_compatible(np, "mmc-card"))
>> + enable_rst_n = of_property_read_bool(np, "enable-hw-reset");
>> + of_node_put(np);
>> +
>> /* Set correct bus mode for MMC before attempting init */
>> if (!mmc_host_is_spi(host))
>> mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN);
>> @@ -1810,6 +1817,20 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
>> }
>> }
>>
>> + /*
>> + * try to enable RST_N if requested
>> + * This is needed because some eMMC chips disable this function by
>> + * default.
>> + */
>> + if (enable_rst_n) {
>> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> + EXT_CSD_RST_N_FUNCTION, EXT_CSD_RST_N_ENABLED,
>> + card->ext_csd.generic_cmd6_time);
>> + if (err && err != -EBADMSG)
>> + pr_warn("%s: Enabling RST_N feature failed\n",
>> + mmc_hostname(card->host));
>> + }
>
> If enabled hw-reset, it doesn't need to re-enable this bit.
Ok. I can add a check to prevent setting it, if it is set already.
> i didn't check the mmc-util..
> If mmc-util provides the changing this, the using mmc-util is better than this.
mmc-utils is providing a enable/disable hwreset feature. But as this
setting is required for my hardware to allow rebooting it, I thought it
would be better if it's in the kernel. So I/the hw doesn't have to
depend on userspace tools.
Nonetheless you're the experts, therefore if you say it shouldn't be in
the kernel/dt I'd be fine with that too. ;-)
^ permalink raw reply
* Re: [PATCH 1/2] doc: Add bindings document for Xilinx LogiCore PR Decoupler
From: Michal Simek @ 2017-04-05 6:26 UTC (permalink / raw)
To: Moritz Fischer, Rob Herring
Cc: Alan Tull, Greg Kroah-Hartman, Linux Kernel Mailing List,
linux-fpga, Moritz Fischer, Michal Simek, Sören Brinkmann,
Devicetree List
In-Reply-To: <CAAtXAHe0qnu7Ub6sing4VUgFa-tkdvH767kNbZnu1S5THHS2oQ@mail.gmail.com>
On 5.4.2017 01:36, Moritz Fischer wrote:
> On Thu, Mar 30, 2017 at 05:44:29PM -0500, Rob Herring wrote:
>> On Fri, Mar 24, 2017 at 10:33:20AM -0500, Alan Tull wrote:
>>> From: Moritz Fischer <mdf@kernel.org>
>>
>> Please use "dt-bindings: fpga: ..." for the subject.
>>
>>
>>>
>>> This adds the binding documentation for the Xilinx LogiCORE PR
>>> Decoupler soft core.
>>>
>>> Signed-off-by: Moritz Fischer <mdf@kernel.org>
>>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
>>> Acked-by: Alan Tull <atull@kernel.org>
>>
>> I'm confused why you are sending these instead of Moritz? If it goes
>> through you, then it should have your S-o-B too.
>
> Do you want me to resend this Alan (with Rob's suggestions)?
>>
>>> Cc: Sören Brinkmann <soren.brinkmann@xilinx.com>
>>> Cc: linux-kernel@vger.kernel.org
>>> Cc: devicetree@vger.kernel.org
>>> ---
>>> .../bindings/fpga/xilinx-pr-decoupler.txt | 35 ++++++++++++++++++++++
>>> 1 file changed, 35 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
>>> new file mode 100644
>>> index 000000000000..2c527ac30398
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
>>> @@ -0,0 +1,35 @@
>>> +Xilinx LogiCORE Partial Reconfig Decoupler Softcore
>>> +
>>> +The Xilinx LogiCORE Partial Reconfig Decoupler manages one or more
>>> +decouplers / fpga bridges.
>>> +The controller can decouple/disable the bridges which prevents signal
>>> +changes from passing through the bridge. The controller can also
>>> +couple / enable the bridges which allows traffic to pass through the
>>> +bridge normally.
>>> +
>>> +The Driver supports only MMIO handling. A PR region can have multiple
>>> +PR Decouplers which can be handled independently or chained via decouple/
>>> +decouple_status signals.
>>> +
>>> +Required properties:
>>> +- compatible : Should contain "xlnx,pr-decoupler-1.00" or "xlnx,pr-decoupler"
>>
>> I'd drop xlnx,pr-decoupler, but in any case, it should not be OR rather
>> "followed by". Plus the example has both.
>
> Michal wanted to have both, so I put both. Personally I don't care. I
> think they have some downstream stuff that relied on it.
Agree with Rob with using "followed by" instead of or.
M
^ permalink raw reply
* Re: cpu of_node links broken
From: Benjamin Herrenschmidt @ 2017-04-05 6:41 UTC (permalink / raw)
To: Wesley Terpstra, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAMgXwThQk=3V1HQ8YpoY57mpY0SrdyfAwS5szpsqwkS-r=FPAw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, 2017-04-04 at 23:12 -0700, Wesley Terpstra wrote:
> In commit 5590f3196b293574a12be58d06d5e1120d8856ec symlinks from
> devices to their OF node were added.
Yup. I did that ;)
> Unfortunately, the code looks for them in cpu_dev_init before they
> exist (of_core_init has not run).
> This results in:
> [ 0.010000] cpu cpu0: Error -2 creating of_node link
>
> I don't know if this code used to work and it got broken, but as of
> 4.6 it does not work and still does not work in 4.11. Moving
> of_core_init() before platform_bus_init() in driver_init()
> [drivers/base/init.c] fixes the problem for me.
>
> Is there any downside to reordering these function calls?
Interesting. I've never seen that error, I wonder if that's because
we fail to link the CPU to an OF node to begin with on our platforms.
I agree though. of_core_init() should probably be called before
we create any device that might have an OF node reference.
In fact we should probably be able to move it right before
platform_bus_init(). Something like this (untested):
[PATCH] drivers/base: Initialize OF sysfs core before creating devices
Devices might try to create symlinks to device-tree nodes,
thus all devices that have OF node linkages should be created
after of_core_init() has been called.
This especially includes cpu_dev_init().
Reported-by: Wesley Terpstra <wesley-SpMDHPYPyPbQT0dZR+AlfA@public.gmane.org>
Signed-off-when-somebody-tests-it-by: Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
---
diff --git a/drivers/base/init.c b/drivers/base/init.c
index 48c0e22..f65d686 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -28,6 +28,13 @@ void __init driver_init(void)
firmware_init();
hypervisor_init();
+ /*
+ * This relies on the firmware_kobj already existing
+ * and should be done before any device that might have
+ * an OF link is created
+ */
+ of_core_init();
+
/* These are also core pieces, but must come after the
* core core pieces.
*/
@@ -35,5 +42,4 @@ void __init driver_init(void)
cpu_dev_init();
memory_dev_init();
container_dev_init();
- of_core_init();
}
Cheers,
Ben.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: cpu of_node links broken
From: Wesley Terpstra @ 2017-04-05 6:49 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1491374467.4166.81.camel-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
On Tue, Apr 4, 2017 at 11:41 PM, Benjamin Herrenschmidt
<benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org> wrote:
>> [ 0.010000] cpu cpu0: Error -2 creating of_node link
> Interesting. I've never seen that error, I wonder if that's because
> we fail to link the CPU to an OF node to begin with on our platforms.
You can find quite a few dmesg traces on google that include the
warning. It affects at least nios2, microblaze and riscv.
It's because the 'sd' pointer in the of_node's kobject is null, which
causes sysfs_do_create_link_sd to return -ENOENT. AFAICT, it's null
because the device tree nodes have not yet been linked into sysfs;
that is what of_core_init() does.
> Devices might try to create symlinks to device-tree nodes,
> thus all devices that have OF node linkages should be created
> after of_core_init() has been called.
Your proposed patch fixes the warning for me on riscv.
--
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
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