* [PATCH 2/3] devicetree: bq27425: add documentation for bq27425 fuel gauge
From: Matt Ranostay @ 2016-12-26 5:44 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA
Cc: Sebastian Reichel, Tony Lindgren, Matt Ranostay
In-Reply-To: <20161226054442.23599-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
.../devicetree/bindings/power/bq27425.txt | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/bq27425.txt
diff --git a/Documentation/devicetree/bindings/power/bq27425.txt b/Documentation/devicetree/bindings/power/bq27425.txt
new file mode 100644
index 000000000000..f09f787a9378
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/bq27425.txt
@@ -0,0 +1,25 @@
+* TI BQ27425 Fuel Gauge
+
+http://www.ti.com/lit/ds/symlink/bq27425-g2a.pdf
+
+Please note that if any of the optional properties are defined
+then all settings must be.
+
+Required properties:
+- compatible: Should be "ti,bq27425"
+- reg: integer, i2c of the device
+
+Optional properties:
+- ti,design-capacity: integer of mAh of the battery
+- ti,design-energy: integer of the mWh of the battery
+- ti,terminate-voltage: integer of mV of the dead voltage of
+ the battery
+
+bq27425 {
+ compatible = "ti,bq27425";
+ reg = <0x55>;
+
+ ti,design-capacity = <1360>;
+ ti,design-energy = <4970>;
+ ti,terminate-voltage = <3200>;
+};
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/3] bq27xxx_battery: add BQ27425 chip id
From: Matt Ranostay @ 2016-12-26 5:44 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA
Cc: Sebastian Reichel, Tony Lindgren, Matt Ranostay
In-Reply-To: <20161226054442.23599-1-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
drivers/power/supply/bq27xxx_battery.c | 24 ++++++++++++++++++++++--
drivers/power/supply/bq27xxx_battery_i2c.c | 2 +-
include/linux/power/bq27xxx_battery.h | 3 ++-
3 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 08c36b8e04bd..721cf6f67874 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -259,6 +259,25 @@ static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_DCAP] = 0x3c,
[BQ27XXX_REG_AP] = 0x18,
},
+ [BQ27425] = {
+ [BQ27XXX_REG_CTRL] = 0x00,
+ [BQ27XXX_REG_TEMP] = 0x02,
+ [BQ27XXX_REG_INT_TEMP] = 0x1e,
+ [BQ27XXX_REG_VOLT] = 0x04,
+ [BQ27XXX_REG_AI] = 0x10,
+ [BQ27XXX_REG_FLAGS] = 0x06,
+ [BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_NAC] = 0x08,
+ [BQ27XXX_REG_FCC] = 0x0e,
+ [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_SOC] = 0x1c,
+ [BQ27XXX_REG_DCAP] = 0x3c,
+ [BQ27XXX_REG_AP] = 0x18,
+ },
};
static enum power_supply_property bq27000_battery_props[] = {
@@ -427,6 +446,7 @@ static struct {
BQ27XXX_PROP(BQ27541, bq27541_battery_props),
BQ27XXX_PROP(BQ27545, bq27545_battery_props),
BQ27XXX_PROP(BQ27421, bq27421_battery_props),
+ BQ27XXX_PROP(BQ27425, bq27421_battery_props),
};
static DEFINE_MUTEX(bq27xxx_list_lock);
@@ -677,7 +697,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
if (di->chip == BQ27500 || di->chip == BQ27510 ||
di->chip == BQ27541 || di->chip == BQ27545)
return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);
- if (di->chip == BQ27530 || di->chip == BQ27421)
+ if (di->chip == BQ27530 || di->chip == BQ27421 || di->chip == BQ27425)
return flags & BQ27XXX_FLAG_OT;
return false;
@@ -688,7 +708,7 @@ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)
*/
static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)
{
- if (di->chip == BQ27530 || di->chip == BQ27421)
+ if (di->chip == BQ27530 || di->chip == BQ27421 || di->chip == BQ27425)
return flags & BQ27XXX_FLAG_UT;
return false;
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index 5c5c3a6f9923..27143230839a 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -159,9 +159,9 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27742", BQ27541 },
{ "bq27545", BQ27545 },
{ "bq27421", BQ27421 },
- { "bq27425", BQ27421 },
{ "bq27441", BQ27421 },
{ "bq27621", BQ27421 },
+ { "bq27425", BQ27425 },
{},
};
MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index bed9557b69e7..14ecac158150 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -9,7 +9,8 @@ enum bq27xxx_chip {
BQ27530, /* bq27530, bq27531 */
BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
BQ27545, /* bq27545 */
- BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
+ BQ27421, /* bq27421, bq27441, bq27621 */
+ BQ27425, /* bq27425 */
};
/**
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 0/3] power: bq27xxx: add support for NVRAM R/W access
From: Matt Ranostay @ 2016-12-26 5:44 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA
Cc: Sebastian Reichel, Tony Lindgren, Matt Ranostay
Enable access to the NVRAM for the bq27425 chipset which allows to
update the battery metrics that are used in the state machine.
This allows adjustments of a termination voltage, design energy, and
design voltage.
Matt Ranostay (3):
bq27xxx_battery: add BQ27425 chip id
devicetree: bq27425: add documentation for bq27425 fuel gauge
power: bq27xxx: add support for NVRAM R/W access
.../devicetree/bindings/power/bq27425.txt | 25 ++
drivers/power/supply/bq27xxx_battery.c | 24 +-
drivers/power/supply/bq27xxx_battery_i2c.c | 336 ++++++++++++++++++++-
include/linux/power/bq27xxx_battery.h | 7 +-
4 files changed, 388 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/bq27425.txt
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [RFC PATCH 6/6] ARM64: exynos: add the pcie node for TM2
From: Jaehoon Chung @ 2016-12-26 5:20 UTC (permalink / raw)
To: linux-pci
Cc: devicetree, linux-kernel, linux-samsung-soc, bhelgaas, robh+dt,
mark.rutland, kgene, krzk, javier, kishon, will.deacon,
catalin.marinas, cpgs, Jaehoon Chung
In-Reply-To: <20161226052029.10552-1-jh80.chung@samsung.com>
Add the Exxynos5433 pcie node for TM2.
This pcie device is used for supporting WiFi.
And some gpios are already requested from pinctrl. so it doesn't need to
initialize.
GPJ2-0 is used for supplying to WiFi PCIe chip.
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
---
arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi | 7 +++++++
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 11 +++++++++--
arch/arm64/boot/dts/exynos/exynos5433.dtsi | 23 ++++++++++++++++++++++
3 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
index ad71247..3e8b728 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
@@ -183,6 +183,13 @@
interrupt-controller;
#interrupt-cells = <2>;
};
+
+ pcie_wlanen: pcie-wlanen {
+ samsung,pins = "gpj2-0";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
};
&pinctrl_finger {
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
index f21bdc2..c84a2ad 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -737,6 +737,15 @@
bus-width = <4>;
};
+&pcie {
+ assigned-clocks = <&cmu_fsys CLK_MOUT_SCLK_PCIE_100_USER>,
+ <&cmu_top CLK_MOUT_SCLK_PCIE_100>;
+ assigned-clock-parents = <&cmu_top CLK_SCLK_PCIE_100_FSYS>,
+ <&cmu_top CLK_MOUT_BUS_PLL_USER>;
+ assigned-clock-rates = <0>, <100000000>;
+ status = "okay";
+};
+
&pinctrl_alive {
pinctrl-names = "default";
pinctrl-0 = <&initial_alive>;
@@ -836,7 +845,6 @@
pinctrl-0 = <&initial_ese>;
initial_ese: initial-state {
- PIN(IN, gpj2-0, DOWN, LV1);
PIN(IN, gpj2-1, DOWN, LV1);
PIN(IN, gpj2-2, DOWN, LV1);
};
@@ -851,7 +859,6 @@
PIN(IN, gpr3-1, DOWN, LV1);
PIN(IN, gpr3-2, DOWN, LV1);
PIN(IN, gpr3-3, DOWN, LV1);
- PIN(IN, gpr3-7, NONE, LV1);
};
};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index 2a15f18..da287f4 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -1457,6 +1457,29 @@
samsung,fsys-sysreg = <&syscon_fsys>;
status = "okay";
};
+
+ pcie: pcie@15700000 {
+ compatible = "samsung,exynos5433-pcie", "snps,dw-pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "intr";
+ clocks = <&cmu_fsys CLK_PCIE>,
+ <&cmu_fsys CLK_PCLK_PCIE_PHY>;
+ clock-names = "pcie", "pcie_bus";
+ num-lanes = <1>;
+ pinctrl-names = "default";
+ phys = <&pcie_phy>;
+ phy-names = "pcie-phy";
+ pinctrl-0 = <&pcie_bus &pcie_wlanen>;
+ reg = <0x156b0000 0x1000>, <0x15700000 0x1000>,
+ <0x0c000000 0x1000>;
+ reg-names = "elbi", "dbi", "config";
+ ranges = <0x81000000 0 0 0x0c001000 0 0x00010000
+ 0x82000000 0 0x0c011000 0x0c011000 0 0x3feefff>;
+ status = "disabled";
+ };
};
timer: timer {
--
2.10.2
^ permalink raw reply related
* [RFC PATCH 5/6] Documentation: pci: add the exynos5433-pcie binding
From: Jaehoon Chung @ 2016-12-26 5:20 UTC (permalink / raw)
To: linux-pci
Cc: devicetree, linux-kernel, linux-samsung-soc, bhelgaas, robh+dt,
mark.rutland, kgene, krzk, javier, kishon, will.deacon,
catalin.marinas, cpgs, Jaehoon Chung
In-Reply-To: <20161226052029.10552-1-jh80.chung@samsung.com>
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
---
.../devicetree/bindings/pci/exynos5433-pcie.txt | 36 ++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/exynos5433-pcie.txt
diff --git a/Documentation/devicetree/bindings/pci/exynos5433-pcie.txt b/Documentation/devicetree/bindings/pci/exynos5433-pcie.txt
new file mode 100644
index 0000000..932a847
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/exynos5433-pcie.txt
@@ -0,0 +1,36 @@
+* Samsung Exynos5433 PCIe interface
+
+This PCIe host controller is based on the Synopsis Designware PCIe IP
+and thus inherits all the common properties defined in designware-pcie.txt.
+
+Required properties:
+- compatible: "samsung,exynos5433-pcie"
+- reg: base addresses and lengths of the pcie controller,
+ the phy controller, additional register for the phy controller.
+- reg-names: Must be "elbi", "phy" and "dbi" for each regs
+- interrupt-names: Must be "intr" for legacy interrupt pin.
+
+Other common properites refer to
+ Documentation/devicetree/binding/pci/designware-pcie.txt
+
+Example:
+
+ pcie: pcie@15700000 {
+ compatible ="samsung,exynos5433-pcie", "snps,dw-pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "intr";
+ clocks = <&cmu_fsys CLK_PCIE>, <&cmu_fsys CLK_PCLK_PCIE_PHY>;
+ clock-names = "pcie", "pcie_bus";
+ num-lanes = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_bus>;
+ reg = <0x156b0000 0x1000>, <0x15680000 0x1000>,
+ <0x15700000 0x1000>, <0x0c000000 0x1000>;
+ reg-names = "elbi", "phy", "dbi", "config";
+ ranges = <0x81000000 0 0 0x0c001000 0 0x00010000
+ 0x82000000 0 0x0c011000 0x0c011000 0 0x3feefff>;
+ status = "disabled";
+ };
--
2.10.2
^ permalink raw reply related
* [RFC PATCH 4/6] PCI: exynos5433: Add new exynos pci host controller for Exynos5433
From: Jaehoon Chung @ 2016-12-26 5:20 UTC (permalink / raw)
To: linux-pci-u79uwXL29TY76Z2rM5mHXA
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, kgene-DgEjT+Ai2ygdnm+yROfE0A,
krzk-DgEjT+Ai2ygdnm+yROfE0A, javier-JPH+aEBZ4P+UEJcrhfAQsw,
kishon-l0cyMroinI0, will.deacon-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, cpgs-Sze3O3UU22JBDgjK7y7TUQ,
Jaehoon Chung
In-Reply-To: <20161226052029.10552-1-jh80.chung-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Exynos5433 supports the PCIe.
This patch adds new pci-exynos5433.c file for Exynos ARM64.
Signed-off-by: Jaehoon Chung <jh80.chung-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
drivers/pci/host/Kconfig | 9 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pci-exynos5433.c | 338 ++++++++++++++++++++++++++++++++++++++
3 files changed, 348 insertions(+)
create mode 100644 drivers/pci/host/pci-exynos5433.c
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index d7e7c0a..3d77d0b 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -60,6 +60,15 @@ config PCI_EXYNOS
select PCIEPORTBUS
select PCIE_DW
+config PCI_EXYNOS5433
+ bool "Samsung Exynos5433 PCIe controller"
+ depends on ARCH_EXYNOS && ARM64
+ depends on PCI_MSI_IRQ_DOMAIN
+ select PCIEPORTBUS
+ select PCIE_DW
+ help
+ If you want support for Exynos5433 PCIe host controller, say Y.
+
config PCI_IMX6
bool "Freescale i.MX6 PCIe controller"
depends on SOC_IMX6Q
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 084cb49..2168de2 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
+obj-$(CONFIG_PCI_EXYNOS5433) += pci-exynos5433.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
diff --git a/drivers/pci/host/pci-exynos5433.c b/drivers/pci/host/pci-exynos5433.c
new file mode 100644
index 0000000..ff254ca
--- /dev/null
+++ b/drivers/pci/host/pci-exynos5433.c
@@ -0,0 +1,338 @@
+/*
+ * PCIe host controller driver for Samsung EXYNOS5433 SoCs
+ *
+ * Copyright (C) 2016 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/resource.h>
+#include <linux/signal.h>
+#include <linux/types.h>
+#include <linux/mfd/syscon.h>
+#include <linux/phy/phy.h>
+
+#include "pcie-designware.h"
+
+#define to_exynos_pcie(x) container_of(x, struct exynos_pcie, pp)
+
+/* Pcie structure for Exynos specific data */
+struct exynos_pcie {
+ void __iomem *elbi_base;
+ struct clk *clk;
+ struct clk *bus_clk;
+ struct pcie_port pp;
+ struct phy *phy;
+};
+
+/* PCIe ELBI registers */
+#define PCIE_IRQ_PULSE 0x000
+#define IRQ_INTA_ASSERT BIT(0)
+#define IRQ_INTB_ASSERT BIT(2)
+#define IRQ_INTC_ASSERT BIT(4)
+#define IRQ_INTD_ASSERT BIT(6)
+#define IRQ_INTX_ASSERT (IRQ_INTA_ASSERT | IRQ_INTB_ASSERT | \
+ IRQ_INTC_ASSERT | IRQ_INTD_ASSERT)
+#define PCIE_IRQ_EN_PULSE 0x00c
+#define PCIE_IRQ_EN_LEVEL 0x010
+#define PCIE_SW_WAKE 0x018
+#define PCIE_BUS_EN BIT(1)
+#define PCIE_APP_LTSSM_ENABLE 0x02c
+#define PCIE_ELBI_LTSSM_ENABLE 0x1
+#define PCIE_ELBI_DEBUG_L 0x074
+#define PCIE_ELBI_XMLH_LINK_UP BIT(4)
+#define PCIE_ELBI_SLV_AWMISC 0x11c
+#define PCIE_ELBI_SLV_ARMISC 0x120
+#define PCIE_ELBI_SLV_DBI_ENABLE BIT(21)
+
+/* DBI register */
+#define PCIE_MISC_CONTROL_1_OFF 0x8BC
+#define DBI_RO_WR_EN BIT(0)
+
+static inline void exynos_pcie_writel(void __iomem *base, u32 val, u32 offset)
+{
+ writel(val, base + offset);
+}
+
+static inline u32 exynos_pcie_readl(void __iomem *base, u32 offset)
+{
+ return readl(base + offset);
+}
+
+static void exynos_pcie_clear_irq_pulse(struct exynos_pcie *ep)
+{
+ u32 val;
+
+ val = exynos_pcie_readl(ep->elbi_base, PCIE_IRQ_PULSE);
+ val &= ~IRQ_INTX_ASSERT;
+ exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_PULSE);
+}
+
+static void exynos_pcie_enable_irq_pulse(struct exynos_pcie *ep)
+{
+ exynos_pcie_writel(ep->elbi_base, IRQ_INTX_ASSERT, PCIE_IRQ_EN_PULSE);
+
+ /* Clear PCIE_IRQ_EN_LEVEL register */
+ exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_LEVEL);
+}
+
+static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
+{
+ struct pcie_port *pp = arg;
+ struct exynos_pcie *ep = to_exynos_pcie(pp);
+
+ exynos_pcie_clear_irq_pulse(ep);
+
+ return IRQ_HANDLED;
+}
+
+static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on)
+{
+ u32 val;
+
+ val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC);
+ if (on)
+ val |= PCIE_ELBI_SLV_DBI_ENABLE;
+ else
+ val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
+ exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC);
+}
+
+static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *ep, bool on)
+{
+ u32 val;
+
+ val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC);
+ if (on)
+ val |= PCIE_ELBI_SLV_DBI_ENABLE;
+ else
+ val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
+ exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC);
+}
+
+static int exynos_pcie_establish_link(struct exynos_pcie *ep)
+{
+ struct pcie_port *pp = &ep->pp;
+ u32 val;
+
+ if (dw_pcie_link_up(pp)) {
+ dev_info(pp->dev, "Link already up\n");
+ return 0;
+ }
+
+ phy_power_on(ep->phy);
+
+ /* Exynos Pcie assert PHY reset and init */
+ phy_init(ep->phy);
+
+ val = exynos_pcie_readl(ep->elbi_base, PCIE_SW_WAKE);
+ val &= ~PCIE_BUS_EN;
+ exynos_pcie_writel(ep->elbi_base, val, PCIE_SW_WAKE);
+
+ /*
+ * Enable DBI_RO_WR_EN bit.
+ * - When set to 1, some RO and HWinit bits are wriatble from
+ * the local application through the DBI.
+ */
+ dw_pcie_writel_rc(pp, PCIE_MISC_CONTROL_1_OFF, DBI_RO_WR_EN);
+
+ /* Setup root complex */
+ dw_pcie_setup_rc(pp);
+
+ /* assert LTSSM enable */
+ exynos_pcie_writel(ep->elbi_base, PCIE_ELBI_LTSSM_ENABLE,
+ PCIE_APP_LTSSM_ENABLE);
+
+ return dw_pcie_wait_for_link(pp);
+}
+
+
+static int exynos_pcie_link_up(struct pcie_port *pp)
+{
+ struct exynos_pcie *ep = to_exynos_pcie(pp);
+ u32 val;
+
+ /* Check the Receive Transaction Layer Handler */
+ val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_DEBUG_L);
+
+ return (val & PCIE_ELBI_XMLH_LINK_UP);
+}
+
+static void exynos_pcie_host_init(struct pcie_port *pp)
+{
+ struct exynos_pcie *ep = to_exynos_pcie(pp);
+
+ exynos_pcie_enable_irq_pulse(ep);
+ exynos_pcie_establish_link(ep);
+}
+
+static u32 exynos_pcie_readl_rc(struct pcie_port *pp, u32 reg)
+{
+ struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
+ u32 val;
+
+ exynos_pcie_sideband_dbi_r_mode(exynos_pcie, true);
+ val = readl(pp->dbi_base + reg);
+ exynos_pcie_sideband_dbi_r_mode(exynos_pcie, false);
+ return val;
+}
+
+static void exynos_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val)
+{
+ struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
+
+ exynos_pcie_sideband_dbi_w_mode(exynos_pcie, true);
+ writel(val, pp->dbi_base + reg);
+ exynos_pcie_sideband_dbi_w_mode(exynos_pcie, false);
+}
+
+static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
+ u32 *val)
+{
+ struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
+ int ret;
+
+ exynos_pcie_sideband_dbi_r_mode(exynos_pcie, true);
+ ret = dw_pcie_cfg_read(pp->dbi_base + where, size, val);
+ exynos_pcie_sideband_dbi_r_mode(exynos_pcie, false);
+ return ret;
+}
+
+static int exynos_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
+ u32 val)
+{
+ struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
+ int ret;
+
+ exynos_pcie_sideband_dbi_w_mode(exynos_pcie, true);
+ ret = dw_pcie_cfg_write(pp->dbi_base + where, size, val);
+ exynos_pcie_sideband_dbi_w_mode(exynos_pcie, false);
+ return ret;
+}
+
+static struct pcie_host_ops exynos_pcie_host_ops = {
+ .readl_rc = exynos_pcie_readl_rc,
+ .writel_rc = exynos_pcie_writel_rc,
+ .rd_own_conf = exynos_pcie_rd_own_conf,
+ .wr_own_conf = exynos_pcie_wr_own_conf,
+ .host_init = exynos_pcie_host_init,
+ .link_up = exynos_pcie_link_up,
+};
+
+static int __init exynos_pcie_probe(struct platform_device *pdev)
+{
+ struct exynos_pcie *exynos_pcie;
+ struct pcie_port *pp;
+ struct resource *res;
+ int ret;
+
+ exynos_pcie = devm_kzalloc(&pdev->dev, sizeof(*exynos_pcie),
+ GFP_KERNEL);
+ if (!exynos_pcie)
+ return -ENOMEM;
+
+ pp = &exynos_pcie->pp;
+ pp->dev = &pdev->dev;
+
+ exynos_pcie->clk = devm_clk_get(&pdev->dev, "pcie");
+ if (IS_ERR(exynos_pcie->clk)) {
+ dev_err(&pdev->dev, "Failed to get pcie rc clock\n");
+ return PTR_ERR(exynos_pcie->clk);
+ }
+ ret = clk_prepare_enable(exynos_pcie->clk);
+ if (ret)
+ return ret;
+
+ exynos_pcie->bus_clk = devm_clk_get(&pdev->dev, "pcie_bus");
+ if (IS_ERR(exynos_pcie->bus_clk)) {
+ dev_err(&pdev->dev, "Failed to get pcie bus clock\n");
+ ret = PTR_ERR(exynos_pcie->bus_clk);
+ goto fail_clk;
+ }
+ ret = clk_prepare_enable(exynos_pcie->bus_clk);
+ if (ret)
+ goto fail_clk;
+
+ /* External Local Bus interface(ELBI) Register */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
+ exynos_pcie->elbi_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(exynos_pcie->elbi_base)) {
+ ret = PTR_ERR(exynos_pcie->elbi_base);
+ goto fail_bus_clk;
+ }
+
+ /* Data Bus Interface(DBI) Register */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+ pp->dbi_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pp->dbi_base)) {
+ ret = PTR_ERR(pp->dbi_base);
+ goto fail_bus_clk;
+ }
+
+ exynos_pcie->phy = devm_phy_get(&pdev->dev, "pcie-phy");
+ if (IS_ERR(exynos_pcie->phy)) {
+ if (PTR_ERR(exynos_pcie->phy) != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Can't find the pcie-phy\n");
+ return PTR_ERR(exynos_pcie->phy);
+ }
+
+ pp->irq = platform_get_irq_byname(pdev, "intr");
+ if (!pp->irq) {
+ dev_err(&pdev->dev, "failed to get irq\n");
+ ret = -ENODEV;
+ goto fail_bus_clk;
+ }
+ ret = devm_request_irq(&pdev->dev, pp->irq, exynos_pcie_irq_handler,
+ IRQF_SHARED, "exynos-pcie", exynos_pcie);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request irq\n");
+ goto fail_bus_clk;
+ }
+
+ pp->root_bus_nr = -1;
+ pp->ops = &exynos_pcie_host_ops;
+
+ ret = dw_pcie_host_init(pp);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to initialize host\n");
+ goto fail_bus_clk;
+ }
+
+ platform_set_drvdata(pdev, exynos_pcie);
+
+ return 0;
+
+fail_bus_clk:
+ clk_disable_unprepare(exynos_pcie->bus_clk);
+fail_clk:
+ clk_disable_unprepare(exynos_pcie->clk);
+ return ret;
+}
+
+static const struct of_device_id exynos_pcie_of_match[] = {
+ { .compatible = "samsung,exynos5433-pcie", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_pcie_of_match);
+
+static struct platform_driver exynos_pcie_driver = {
+ .probe = exynos_pcie_probe,
+ .driver = {
+ .name = "exynos5433-pcie",
+ .of_match_table = exynos_pcie_of_match,
+ },
+};
+builtin_platform_driver(exynos_pcie_driver);
--
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
* [RFC PATCH 3/6] ARM64: dts: exynos5433: add the pcie_phy node for PCIe
From: Jaehoon Chung @ 2016-12-26 5:20 UTC (permalink / raw)
To: linux-pci-u79uwXL29TY76Z2rM5mHXA
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, kgene-DgEjT+Ai2ygdnm+yROfE0A,
krzk-DgEjT+Ai2ygdnm+yROfE0A, javier-JPH+aEBZ4P+UEJcrhfAQsw,
kishon-l0cyMroinI0, will.deacon-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, cpgs-Sze3O3UU22JBDgjK7y7TUQ,
Jaehoon Chung
In-Reply-To: <20161226052029.10552-1-jh80.chung-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
To use the generic PHY framework, adds the pcie_phy node.
Signed-off-by: Jaehoon Chung <jh80.chung-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
arch/arm64/boot/dts/exynos/exynos5433.dtsi | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index 64226d5..2a15f18 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -805,6 +805,11 @@
reg = <0x145f0000 0x1038>;
};
+ syscon_fsys: syscon@156f0000 {
+ compatible = "syscon";
+ reg = <0x156f0000 0x1044>;
+ };
+
gsc_0: video-scaler@13C00000 {
compatible = "samsung,exynos5433-gsc";
reg = <0x13c00000 0x1000>;
@@ -1443,6 +1448,15 @@
status = "disabled";
};
};
+
+ pcie_phy: pcie-phy@15680000 {
+ #phy-cells = <0>;
+ compatible = "samsung,exynos5433-pcie-phy";
+ reg = <0x15680000 0x1000>;
+ samsung,pmureg-phandle = <&pmu_system_controller>;
+ samsung,fsys-sysreg = <&syscon_fsys>;
+ status = "okay";
+ };
};
timer: timer {
--
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
* [RFC PATCH 2/6] Documetation: samsung-phy: add the exynos-pcie-phy binding
From: Jaehoon Chung @ 2016-12-26 5:20 UTC (permalink / raw)
To: linux-pci
Cc: devicetree, linux-kernel, linux-samsung-soc, bhelgaas, robh+dt,
mark.rutland, kgene, krzk, javier, kishon, will.deacon,
catalin.marinas, cpgs, Jaehoon Chung
In-Reply-To: <20161226052029.10552-1-jh80.chung@samsung.com>
Adds the exynos-pcie-phy binding for Exynos PCIe PHY.
This is for using generic PHY framework.
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
---
.../devicetree/bindings/phy/samsung-phy.txt | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 9872ba8..eb1085e 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -191,3 +191,24 @@ Example:
usbdrdphy0 = &usb3_phy0;
usbdrdphy1 = &usb3_phy1;
};
+
+Samsung Exynos SoC series PCIe PHY controller
+--------------------------------------------------
+Required properties:
+- compatible : Should be set to "samsung,exynos5433-pcie-phy"
+- #phy-cells : must be zero
+- reg : a list of registers usd by phy driver
+
+Optional properites:
+-samsung,pmureg-phandle - handle to syscon used to control PMU registers
+-samsung,fsys-sysreg - handle to syscon used to control the system registers
+
+Example:
+ pcie_phy: pcie-phy@15680000 {
+ #phy-cells = <0>;
+ compatible = "samsung,exynos5433-pcie-phy";
+ reg = <0x15680000 0x1000>;
+ samsung,pmureg-phandle = <&pmu_system_controller>;
+ samsung,fsys-sysreg = <&syscon_fsys>;
+ status = "okay";
+ };
--
2.10.2
^ permalink raw reply related
* [RFC PATCH 1/6] phy: exynos-pcie: Add support for Exynos PCIe phy
From: Jaehoon Chung @ 2016-12-26 5:20 UTC (permalink / raw)
To: linux-pci
Cc: devicetree, linux-kernel, linux-samsung-soc, bhelgaas, robh+dt,
mark.rutland, kgene, krzk, javier, kishon, will.deacon,
catalin.marinas, cpgs, Jaehoon Chung
In-Reply-To: <20161226052029.10552-1-jh80.chung@samsung.com>
This patch supports to use Generic Phy framework for Exynos PCIe phy.
When Exynos that supported the pcie want to use the PCIe,
it needs to control the phy resgister.
But it should be more complex to control in their own PCIe device drivers.
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
---
drivers/phy/Kconfig | 9 ++
drivers/phy/Makefile | 1 +
drivers/phy/phy-exynos-pcie.c | 227 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 237 insertions(+)
create mode 100644 drivers/phy/phy-exynos-pcie.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index fe00f91..94b0433 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -341,6 +341,15 @@ config PHY_EXYNOS5_USBDRD
This driver provides PHY interface for USB 3.0 DRD controller
present on Exynos5 SoC series.
+config PHY_EXYNOS_PCIE
+ bool "Exynos PCIe PHY driver"
+ depends on ARCH_EXYNOS && OF
+ depends on PCI_EXYNOS5433
+ select GENERIC_PHY
+ help
+ Enable PCIe PHY support for Exynos SoC series.
+ This driver provides PHY interface for Exynos PCIe controller.
+
config PHY_PISTACHIO_USB
tristate "IMG Pistachio USB2.0 PHY driver"
depends on MACH_PISTACHIO
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index a534cf5..586344d 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -38,6 +38,7 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
+obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
diff --git a/drivers/phy/phy-exynos-pcie.c b/drivers/phy/phy-exynos-pcie.c
new file mode 100644
index 0000000..0f5eefd
--- /dev/null
+++ b/drivers/phy/phy-exynos-pcie.c
@@ -0,0 +1,227 @@
+/*
+ * Samsung EXYNOS SoC series PCIe PHY driver
+ *
+ * Phy provider for PCIe controller on Exynos SoC series
+ *
+ * Copyright (C) 2016 Samsung Electronics Co., Ltd.
+ * Jaehoon Chung <jh80.chung@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#define PCIE_EXYNOS5433_PMU_PHY_OFFSET 0x730
+#define PCIE_PHY_OFFSET(x) ((x) * 0x4)
+
+/* Sysreg Fsys register offset and bit for Exynos5433 */
+#define PCIE_PHY_MAC_RESET 0x208
+#define PCIE_MAC_RESET_MASK 0xFF
+#define PCIE_MAC_RESET BIT(4)
+#define PCIE_L1SUB_CM_CON 0x1010
+#define PCIE_REFCLK_GATING_EN BIT(0)
+#define PCIE_PHY_COMMON_RESET 0x1020
+#define PCIE_PHY_RESET BIT(0)
+#define PCIE_PHY_GLOBAL_RESET 0x1040
+#define PCIE_GLOBAL_RESET BIT(0)
+#define PCIE_REFCLK BIT(1)
+#define PCIE_REFCLK_MASK 0x16
+#define PCIE_APP_REQ_EXIT_L1_MODE BIT(5)
+
+enum exynos_pcie_phy_data_type {
+ PCIE_PHY_TYPE_EXYNOS5433,
+};
+
+struct exynos_pcie_phy_data {
+ enum exynos_pcie_phy_data_type ctrl_type;
+ u32 pmureg_offset; /* PMU_REG offset */
+ struct phy_ops *ops;
+};
+
+/* for Exynos pcie phy */
+struct exynos_pcie_phy {
+ const struct exynos_pcie_phy_data *drv_data;
+ struct regmap *pmureg;
+ struct regmap *fsysreg;
+ void __iomem *phy_base;
+};
+
+static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset)
+{
+ writel(val, base + offset);
+}
+
+static int exynos_pcie_phy_init(struct phy *phy)
+{
+ struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
+
+ if (ep->fsysreg) {
+ regmap_update_bits(ep->fsysreg, PCIE_PHY_COMMON_RESET,
+ PCIE_PHY_RESET, 1);
+ regmap_update_bits(ep->fsysreg, PCIE_PHY_MAC_RESET,
+ PCIE_MAC_RESET, 0);
+ /* PHY refclk 24MHz */
+ regmap_update_bits(ep->fsysreg, PCIE_PHY_GLOBAL_RESET,
+ PCIE_REFCLK_MASK, PCIE_REFCLK);
+ regmap_update_bits(ep->fsysreg, PCIE_PHY_GLOBAL_RESET,
+ PCIE_GLOBAL_RESET, 0);
+ }
+
+ exynos_pcie_phy_writel(ep->phy_base, 0x11, PCIE_PHY_OFFSET(0x3));
+
+ /* band gap reference on */
+ exynos_pcie_phy_writel(ep->phy_base, 0, PCIE_PHY_OFFSET(0x20));
+ exynos_pcie_phy_writel(ep->phy_base, 0, PCIE_PHY_OFFSET(0x4b));
+
+ /* jitter tunning */
+ exynos_pcie_phy_writel(ep->phy_base, 0x34, PCIE_PHY_OFFSET(0x4));
+ exynos_pcie_phy_writel(ep->phy_base, 0x02, PCIE_PHY_OFFSET(0x7));
+ exynos_pcie_phy_writel(ep->phy_base, 0x41, PCIE_PHY_OFFSET(0x21));
+ exynos_pcie_phy_writel(ep->phy_base, 0x7F, PCIE_PHY_OFFSET(0x14));
+ exynos_pcie_phy_writel(ep->phy_base, 0xC0, PCIE_PHY_OFFSET(0x15));
+ exynos_pcie_phy_writel(ep->phy_base, 0x61, PCIE_PHY_OFFSET(0x36));
+
+ /* D0 uninit.. */
+ exynos_pcie_phy_writel(ep->phy_base, 0x44, PCIE_PHY_OFFSET(0x3D));
+
+ /* 24MHz */
+ exynos_pcie_phy_writel(ep->phy_base, 0x94, PCIE_PHY_OFFSET(0x8));
+ exynos_pcie_phy_writel(ep->phy_base, 0xA7, PCIE_PHY_OFFSET(0x9));
+ exynos_pcie_phy_writel(ep->phy_base, 0x93, PCIE_PHY_OFFSET(0xA));
+ exynos_pcie_phy_writel(ep->phy_base, 0x6B, PCIE_PHY_OFFSET(0xC));
+ exynos_pcie_phy_writel(ep->phy_base, 0xA5, PCIE_PHY_OFFSET(0xF));
+ exynos_pcie_phy_writel(ep->phy_base, 0x34, PCIE_PHY_OFFSET(0x16));
+ exynos_pcie_phy_writel(ep->phy_base, 0xA3, PCIE_PHY_OFFSET(0x17));
+ exynos_pcie_phy_writel(ep->phy_base, 0xA7, PCIE_PHY_OFFSET(0x1A));
+ exynos_pcie_phy_writel(ep->phy_base, 0x71, PCIE_PHY_OFFSET(0x23));
+ exynos_pcie_phy_writel(ep->phy_base, 0x4C, PCIE_PHY_OFFSET(0x24));
+
+ exynos_pcie_phy_writel(ep->phy_base, 0x0E, PCIE_PHY_OFFSET(0x26));
+ exynos_pcie_phy_writel(ep->phy_base, 0x14, PCIE_PHY_OFFSET(0x7));
+ exynos_pcie_phy_writel(ep->phy_base, 0x48, PCIE_PHY_OFFSET(0x43));
+ exynos_pcie_phy_writel(ep->phy_base, 0x44, PCIE_PHY_OFFSET(0x44));
+ exynos_pcie_phy_writel(ep->phy_base, 0x03, PCIE_PHY_OFFSET(0x45));
+ exynos_pcie_phy_writel(ep->phy_base, 0xA7, PCIE_PHY_OFFSET(0x48));
+ exynos_pcie_phy_writel(ep->phy_base, 0x13, PCIE_PHY_OFFSET(0x54));
+ exynos_pcie_phy_writel(ep->phy_base, 0x04, PCIE_PHY_OFFSET(0x31));
+ exynos_pcie_phy_writel(ep->phy_base, 0, PCIE_PHY_OFFSET(0x32));
+
+ if (ep->fsysreg) {
+ regmap_update_bits(ep->fsysreg, PCIE_PHY_COMMON_RESET,
+ PCIE_PHY_RESET, 0);
+ regmap_update_bits(ep->fsysreg, PCIE_PHY_MAC_RESET,
+ PCIE_MAC_RESET_MASK, PCIE_MAC_RESET);
+ }
+
+ return 0;
+}
+
+static int exynos_pcie_phy_power_on(struct phy *phy)
+{
+ struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
+
+ if (ep->pmureg) {
+ if (regmap_update_bits(ep->pmureg, ep->drv_data->pmureg_offset,
+ BIT(0), 1))
+ dev_warn(&phy->dev, "Failed to update regmap bit.\n");
+ }
+
+ if (ep->fsysreg) {
+ regmap_update_bits(ep->fsysreg, PCIE_PHY_GLOBAL_RESET,
+ PCIE_APP_REQ_EXIT_L1_MODE, 0);
+ regmap_update_bits(ep->fsysreg, PCIE_L1SUB_CM_CON,
+ PCIE_REFCLK_GATING_EN, 0);
+ }
+
+ return 0;
+}
+
+static struct phy_ops exynos_phy_ops = {
+ .init = exynos_pcie_phy_init,
+ .power_on = exynos_pcie_phy_power_on,
+};
+
+static const struct exynos_pcie_phy_data exynos5433_pcie_phy_data = {
+ .ctrl_type = PCIE_PHY_TYPE_EXYNOS5433,
+ .pmureg_offset = PCIE_EXYNOS5433_PMU_PHY_OFFSET,
+ .ops = &exynos_phy_ops,
+};
+
+static const struct of_device_id exynos_pcie_phy_match[] = {
+ {
+ .compatible = "samsung,exynos5433-pcie-phy",
+ .data = &exynos5433_pcie_phy_data,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, exynos_pcie_phy_match);
+
+static int exynos_pcie_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct exynos_pcie_phy *exynos_phy;
+ struct phy *generic_phy;
+ struct phy_provider *phy_provider;
+ struct resource *res;
+ const struct exynos_pcie_phy_data *drv_data;
+ const struct of_device_id *match;
+
+ exynos_phy = devm_kzalloc(dev, sizeof(*exynos_phy), GFP_KERNEL);
+ if (!exynos_phy)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ exynos_phy->phy_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(exynos_phy->phy_base))
+ return PTR_ERR(exynos_phy->phy_base);
+
+ exynos_phy->pmureg = syscon_regmap_lookup_by_phandle(np,
+ "samsung,pmureg-phandle");
+ if (IS_ERR(exynos_phy->pmureg)) {
+ dev_warn(&pdev->dev, "pmureg syscon regmap lookup failed.\n");
+ exynos_phy->pmureg = NULL;
+ }
+
+ match = of_match_node(exynos_pcie_phy_match, pdev->dev.of_node);
+ drv_data = match->data;
+ exynos_phy->drv_data = drv_data;
+
+ exynos_phy->fsysreg = syscon_regmap_lookup_by_phandle(np,
+ "samsung,fsys-sysreg");
+ if (IS_ERR(exynos_phy->fsysreg)) {
+ dev_warn(&pdev->dev, "Fsysreg syscon regmap lookup failed.\n");
+ exynos_phy->fsysreg = NULL;
+ }
+
+ generic_phy = devm_phy_create(dev, dev->of_node, drv_data->ops);
+ if (IS_ERR(generic_phy)) {
+ dev_err(dev, "failed to create PHY\n");
+ return PTR_ERR(generic_phy);
+ }
+
+ phy_set_drvdata(generic_phy, exynos_phy);
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static struct platform_driver exynos_pcie_phy_driver = {
+ .probe = exynos_pcie_phy_probe,
+ .driver = {
+ .of_match_table = exynos_pcie_phy_match,
+ .name = "exynos_pcie_phy",
+ }
+};
+module_platform_driver(exynos_pcie_phy_driver);
--
2.10.2
^ permalink raw reply related
* [RFC PATCH 0/6] Support the PCIe for TM2(exynos5433)
From: Jaehoon Chung @ 2016-12-26 5:20 UTC (permalink / raw)
To: linux-pci
Cc: devicetree, linux-kernel, linux-samsung-soc, bhelgaas, robh+dt,
mark.rutland, kgene, krzk, javier, kishon, will.deacon,
catalin.marinas, cpgs, Jaehoon Chung
In-Reply-To: <CGME20161226052030epcas1p45f543765960d14ccf9cd40c2b9cca84b@epcas1p4.samsung.com>
This patchset is for supporting PCIe exynos5433.
TM2(exynos5433) supports the PCIe for WiFi. In driver/pci/host/, there is pci-exynos.c.
But i can't touch anything. The below reasons are why i added the new file.
1. Don't have the exynos5440 TRM
- I can't check anything for exynso5440.
- So i can't touch anything for using PHY generic framework.
2. Can't test the exynos5440 board.
- If used the phy generic framework, can't ensure whether it's working fine or not.
3. There is no maintiain for exynos5440.
- i don't know anywhere pci-exynos5440 is used.
As i know, Bjorn(PCIe Maintainer) agreed about adding the new file.
So i added the new pci-exynos5433 file in driver/pci/host/.
And adds the phy-exynos-pcie.c for using PHY generic framework.
When use the PHY generic framework, controlling pcie is more easier than now.
There are future works,
- Supporting MSI
- If possible, combine the one file to pci-exynos.c
This is based on httt://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git (for-next branch)
(Because PCI git repository doesn't snycrhonize yet.)
The below is working messesage
[ 0.817081] OF: PCI: host bridge /soc/pcie@15700000 ranges:
[ 0.817264] OF: PCI: No bus range found for /soc/pcie@15700000, using [bus 00-ff]
[ 0.821377] OF: PCI: IO 0x0c001000..0x0c010fff -> 0x00000000
[ 0.827270] OF: PCI: MEM 0x0c011000..0x0ffffffe -> 0x0c011000
[ 0.934306] exynos5433-pcie 156b0000.pcie: link up
[ 0.934649] exynos5433-pcie 156b0000.pcie: PCI host bridge to bus 0000:00
[ 0.934867] pci_bus 0000:00: root bus resource [bus 00-ff]
[ 0.935045] pci_bus 0000:00: root bus resource [io 0x0000-0xffff]
[ 0.935243] pci_bus 0000:00: root bus resource [mem 0x0c011000-0x0ffffffe]
[ 0.953719] pci 0000:00:00.0: BAR 8: assigned [mem 0x0c200000-0x0c7fffff]
[ 0.953941] pci 0000:01:00.0: BAR 2: assigned [mem 0x0c400000-0x0c7fffff 64bit]
[ 0.956672] pci 0000:01:00.0: BAR 0: assigned [mem 0x0c200000-0x0c207fff 64bit]
[ 0.963959] pci 0000:00:00.0: PCI bridge to [bus 01]
[ 0.968368] pci 0000:00:00.0: bridge window [mem 0x0c200000-0x0c7fffff]
[ 0.975241] pcieport 0000:00:00.0: of_irq_parse_pci() failed with rc=-22
[ 0.982124] pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
Jaehoon Chung (6):
phy: exynos-pcie: Add support for Exynos PCIe phy
Documetation: samsung-phy: add the exynos-pcie-phy binding
ARM64: dts: exynos5433: add the pcie_phy node for PCIe
PCI: exynos5433: Add new exynos pci host controller for Exynos5433
Documentation: pci: add the exynos5433-pcie binding
ARM64: exynos: add the pcie node for TM2
.../devicetree/bindings/pci/exynos5433-pcie.txt | 36 +++
.../devicetree/bindings/phy/samsung-phy.txt | 21 ++
arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi | 7 +
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 11 +-
arch/arm64/boot/dts/exynos/exynos5433.dtsi | 37 +++
drivers/pci/host/Kconfig | 9 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pci-exynos5433.c | 338 +++++++++++++++++++++
drivers/phy/Kconfig | 9 +
drivers/phy/Makefile | 1 +
drivers/phy/phy-exynos-pcie.c | 227 ++++++++++++++
11 files changed, 695 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/exynos5433-pcie.txt
create mode 100644 drivers/pci/host/pci-exynos5433.c
create mode 100644 drivers/phy/phy-exynos-pcie.c
--
2.10.2
^ permalink raw reply
* [PATCH v3 4/4] clk: rockchip: add new pll-type for rk3328
From: Elaine Zhang @ 2016-12-26 3:45 UTC (permalink / raw)
To: heiko-4mtYJXux2i+zQB+pC5nmwQ, mturquette-rdvid1DuHRBWk0Htik3J/w,
sboyd-sgV2jX0FEOL9JmXXK+q4OQ, xf-TNX95d0MmH7DzftRWevZcw
Cc: mark.rutland-5wv7dgnIgG8, huangtao-TNX95d0MmH7DzftRWevZcw,
devicetree-u79uwXL29TY76Z2rM5mHXA, xxx-TNX95d0MmH7DzftRWevZcw,
Elaine Zhang, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-clk-u79uwXL29TY76Z2rM5mHXA, cl-TNX95d0MmH7DzftRWevZcw
In-Reply-To: <1482723930-5876-1-git-send-email-zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
The rk3328's pll and clock are similar with rk3036's,
it different with pll_mode_mask, the rk3328 soc
pll mode only one bit(rk3036 soc have two bits)
so these should be independent and separate from
the series of rk3328s.
Changes in v3:
fix up the pll type pll_rk3328 description and use
Signed-off-by: Elaine Zhang <zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
drivers/clk/rockchip/clk-pll.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 6ed605776abd..eec51893a7e6 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -29,6 +29,7 @@
#define PLL_MODE_SLOW 0x0
#define PLL_MODE_NORM 0x1
#define PLL_MODE_DEEP 0x2
+#define PLL_RK3328_MODE_MASK 0x1
struct rockchip_clk_pll {
struct clk_hw hw;
@@ -848,7 +849,8 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
struct clk *pll_clk, *mux_clk;
char pll_name[20];
- if (num_parents != 2) {
+ if ((pll_type != pll_rk3328 && num_parents != 2) ||
+ (pll_type == pll_rk3328 && num_parents != 1)) {
pr_err("%s: needs two parent clocks\n", __func__);
return ERR_PTR(-EINVAL);
}
@@ -865,13 +867,17 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
pll_mux = &pll->pll_mux;
pll_mux->reg = ctx->reg_base + mode_offset;
pll_mux->shift = mode_shift;
- pll_mux->mask = PLL_MODE_MASK;
+ if (pll_type == pll_rk3328)
+ pll_mux->mask = PLL_RK3328_MODE_MASK;
+ else
+ pll_mux->mask = PLL_MODE_MASK;
pll_mux->flags = 0;
pll_mux->lock = &ctx->lock;
pll_mux->hw.init = &init;
if (pll_type == pll_rk3036 ||
pll_type == pll_rk3066 ||
+ pll_type == pll_rk3328 ||
pll_type == pll_rk3399)
pll_mux->flags |= CLK_MUX_HIWORD_MASK;
@@ -884,7 +890,10 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
init.flags = CLK_SET_RATE_PARENT;
init.ops = pll->pll_mux_ops;
init.parent_names = pll_parents;
- init.num_parents = ARRAY_SIZE(pll_parents);
+ if (pll_type == pll_rk3328)
+ init.num_parents = 2;
+ else
+ init.num_parents = ARRAY_SIZE(pll_parents);
mux_clk = clk_register(NULL, &pll_mux->hw);
if (IS_ERR(mux_clk))
@@ -918,6 +927,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
switch (pll_type) {
case pll_rk3036:
+ case pll_rk3328:
if (!pll->rate_table || IS_ERR(ctx->grf))
init.ops = &rockchip_rk3036_pll_clk_norate_ops;
else
--
1.9.1
^ permalink raw reply related
* [PATCH v3 3/4] clk: rockchip: add clock controller for rk3328
From: Elaine Zhang @ 2016-12-26 3:45 UTC (permalink / raw)
To: heiko-4mtYJXux2i+zQB+pC5nmwQ, mturquette-rdvid1DuHRBWk0Htik3J/w,
sboyd-sgV2jX0FEOL9JmXXK+q4OQ, xf-TNX95d0MmH7DzftRWevZcw
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linux-clk-u79uwXL29TY76Z2rM5mHXA, huangtao-TNX95d0MmH7DzftRWevZcw,
xxx-TNX95d0MmH7DzftRWevZcw, cl-TNX95d0MmH7DzftRWevZcw,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Elaine Zhang
In-Reply-To: <1482723930-5876-1-git-send-email-zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
Add the clock tree definition for the new rk3328 SoC.
Changes in v3:
fix up the pll parent only xin24m.
Changes in v2:
fix up these *_sample error description.
Signed-off-by: Elaine Zhang <zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
drivers/clk/rockchip/Makefile | 1 +
drivers/clk/rockchip/clk-rk3328.c | 1068 +++++++++++++++++++++++++++++++++++++
drivers/clk/rockchip/clk.h | 23 +
3 files changed, 1092 insertions(+)
create mode 100644 drivers/clk/rockchip/clk-rk3328.c
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 16e098c36f90..68b04bfca282 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -16,5 +16,6 @@ obj-y += clk-rk3036.o
obj-y += clk-rk3188.o
obj-y += clk-rk3228.o
obj-y += clk-rk3288.o
+obj-y += clk-rk3328.o
obj-y += clk-rk3368.o
obj-y += clk-rk3399.o
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
new file mode 100644
index 000000000000..9958ce7d0dcd
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -0,0 +1,1068 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Elaine <zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rk3328-cru.h>
+#include "clk.h"
+
+#define RK3328_GRF_SOC_STATUS0 0x480
+#define RK3328_GRF_MAC_CON1 0x904
+#define RK3328_GRF_MAC_CON2 0x908
+
+enum rk3328_plls {
+ apll, dpll, cpll, gpll, npll,
+};
+
+static struct rockchip_pll_rate_table rk3328_pll_rates[] = {
+ /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+ RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
+ RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0),
+ RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+ RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0),
+ RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+ RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0),
+ RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0),
+ RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0),
+ RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0),
+ RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+ RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0),
+ RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0),
+ RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0),
+ RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
+ RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+ RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0),
+ RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0),
+ RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+ RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0),
+ RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+ RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0),
+ { /* sentinel */ },
+};
+
+static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = {
+ /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+ RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134217),
+ /* vco = 1016064000 */
+ RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671088),
+ /* vco = 983040000 */
+ RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671088),
+ /* vco = 983040000 */
+ RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671088),
+ /* vco = 860156000 */
+ RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797894),
+ /* vco = 903168000 */
+ RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066329),
+ /* vco = 819200000 */
+ { /* sentinel */ },
+};
+
+#define RK3328_DIV_CPU_MASK 0x1f
+#define RK3328_DIV_CPU_SHIFT 8
+
+#define RK3328_DIV_PERI_MASK 0xf
+#define RK3328_DIV_PERI_SHIFT 0
+#define RK3328_DIV_ACLK_MASK 0x7
+#define RK3328_DIV_ACLK_SHIFT 4
+#define RK3328_DIV_HCLK_MASK 0x3
+#define RK3328_DIV_HCLK_SHIFT 8
+#define RK3328_DIV_PCLK_MASK 0x7
+#define RK3328_DIV_PCLK_SHIFT 12
+
+#define RK3328_CLKSEL1(_aclk_core, _pclk_dbg) \
+{ \
+ .reg = RK3328_CLKSEL_CON(1), \
+ .val = HIWORD_UPDATE(_aclk_core, RK3328_DIV_ACLKM_MASK, \
+ RK3328_DIV_ACLKM_SHIFT) | \
+ HIWORD_UPDATE(_pclk_dbg, RK3328_DIV_PCLK_DBG_MASK, \
+ RK3328_DIV_PCLK_DBG_SHIFT), \
+}
+
+#define RK3328_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \
+{ \
+ .prate = _prate, \
+ .divs = { \
+ RK3328_CLKSEL1(_aclk_core, _pclk_dbg), \
+ }, \
+}
+
+static struct rockchip_cpuclk_rate_table rk3328_cpuclk_rates[] __initdata = {
+ RK3328_CPUCLK_RATE(1800000000, 1, 7),
+ RK3328_CPUCLK_RATE(1704000000, 1, 7),
+ RK3328_CPUCLK_RATE(1608000000, 1, 7),
+ RK3328_CPUCLK_RATE(1512000000, 1, 7),
+ RK3328_CPUCLK_RATE(1488000000, 1, 5),
+ RK3328_CPUCLK_RATE(1416000000, 1, 5),
+ RK3328_CPUCLK_RATE(1392000000, 1, 5),
+ RK3328_CPUCLK_RATE(1296000000, 1, 5),
+ RK3328_CPUCLK_RATE(1200000000, 1, 5),
+ RK3328_CPUCLK_RATE(1104000000, 1, 5),
+ RK3328_CPUCLK_RATE(1008000000, 1, 5),
+ RK3328_CPUCLK_RATE(912000000, 1, 5),
+ RK3328_CPUCLK_RATE(816000000, 1, 3),
+ RK3328_CPUCLK_RATE(696000000, 1, 3),
+ RK3328_CPUCLK_RATE(600000000, 1, 3),
+ RK3328_CPUCLK_RATE(408000000, 1, 1),
+ RK3328_CPUCLK_RATE(312000000, 1, 1),
+ RK3328_CPUCLK_RATE(216000000, 1, 1),
+ RK3328_CPUCLK_RATE(96000000, 1, 1),
+};
+
+static const struct rockchip_cpuclk_reg_data rk3328_cpuclk_data = {
+ .core_reg = RK3328_CLKSEL_CON(0),
+ .div_core_shift = 0,
+ .div_core_mask = 0x1f,
+ .mux_core_alt = 1,
+ .mux_core_main = 3,
+ .mux_core_shift = 6,
+ .mux_core_mask = 0x3,
+};
+
+PNAME(mux_pll_p) = { "xin24m" };
+
+PNAME(mux_2plls_p) = { "cpll", "gpll" };
+PNAME(mux_gpll_cpll_p) = { "gpll", "cpll" };
+PNAME(mux_cpll_gpll_apll_p) = { "cpll", "gpll", "apll" };
+PNAME(mux_2plls_xin24m_p) = { "cpll", "gpll", "xin24m" };
+PNAME(mux_2plls_hdmiphy_p) = { "cpll", "gpll",
+ "dummy_hdmiphy" };
+PNAME(mux_4plls_p) = { "cpll", "gpll",
+ "dummy_hdmiphy",
+ "usb480m" };
+PNAME(mux_2plls_u480m_p) = { "cpll", "gpll",
+ "usb480m" };
+PNAME(mux_2plls_24m_u480m_p) = { "cpll", "gpll",
+ "xin24m", "usb480m" };
+
+PNAME(mux_ddrphy_p) = { "dpll", "apll", "cpll" };
+PNAME(mux_armclk_p) = { "apll_core",
+ "gpll_core",
+ "dpll_core",
+ "npll_core"};
+PNAME(mux_hdmiphy_p) = { "hdmi_phy", "xin24m" };
+PNAME(mux_usb480m_p) = { "usb480m_phy",
+ "xin24m" };
+
+PNAME(mux_i2s0_p) = { "clk_i2s0_div",
+ "clk_i2s0_frac",
+ "xin12m",
+ "xin12m" };
+PNAME(mux_i2s1_p) = { "clk_i2s1_div",
+ "clk_i2s1_frac",
+ "clkin_i2s1",
+ "xin12m" };
+PNAME(mux_i2s2_p) = { "clk_i2s2_div",
+ "clk_i2s2_frac",
+ "clkin_i2s2",
+ "xin12m" };
+PNAME(mux_i2s1out_p) = { "clk_i2s1", "xin12m"};
+PNAME(mux_i2s2out_p) = { "clk_i2s2", "xin12m" };
+PNAME(mux_spdif_p) = { "clk_spdif_div",
+ "clk_spdif_frac",
+ "xin12m",
+ "xin12m" };
+PNAME(mux_uart0_p) = { "clk_uart0_div",
+ "clk_uart0_frac",
+ "xin24m" };
+PNAME(mux_uart1_p) = { "clk_uart1_div",
+ "clk_uart1_frac",
+ "xin24m" };
+PNAME(mux_uart2_p) = { "clk_uart2_div",
+ "clk_uart2_frac",
+ "xin24m" };
+
+PNAME(mux_sclk_cif_p) = { "clk_cif_src",
+ "xin24m" };
+PNAME(mux_dclk_lcdc_p) = { "hdmiphy",
+ "dclk_lcdc_src" };
+PNAME(mux_aclk_peri_pre_p) = { "cpll_peri",
+ "gpll_peri",
+ "hdmiphy_peri" };
+PNAME(mux_ref_usb3otg_src_p) = { "xin24m",
+ "clk_usb3otg_ref" };
+PNAME(mux_xin24m_32k_p) = { "xin24m",
+ "clk_rtc32k" };
+PNAME(mux_mac2io_src_p) = { "clk_mac2io_src",
+ "gmac_clkin" };
+PNAME(mux_mac2phy_src_p) = { "clk_mac2phy_src",
+ "phy_50m_out" };
+
+static struct rockchip_pll_clock rk3328_pll_clks[] __initdata = {
+ [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p,
+ 0, RK3328_PLL_CON(0),
+ RK3328_MODE_CON, 0, 4, 0, rk3328_pll_frac_rates),
+ [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
+ 0, RK3328_PLL_CON(8),
+ RK3328_MODE_CON, 4, 3, 0, NULL),
+ [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
+ 0, RK3328_PLL_CON(16),
+ RK3328_MODE_CON, 8, 2, 0, rk3328_pll_rates),
+ [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+ 0, RK3328_PLL_CON(24),
+ RK3328_MODE_CON, 12, 1, 0, rk3328_pll_frac_rates),
+ [npll] = PLL(pll_rk3328, PLL_NPLL, "npll", mux_pll_p,
+ 0, RK3328_PLL_CON(40),
+ RK3328_MODE_CON, 1, 0, 0, rk3328_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch rk3328_i2s0_fracmux __initdata =
+ MUX(0, "i2s0_pre", mux_i2s0_p, CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(6), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3328_i2s1_fracmux __initdata =
+ MUX(0, "i2s1_pre", mux_i2s1_p, CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(8), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3328_i2s2_fracmux __initdata =
+ MUX(0, "i2s2_pre", mux_i2s2_p, CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(10), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3328_spdif_fracmux __initdata =
+ MUX(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(12), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3328_uart0_fracmux __initdata =
+ MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(14), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3328_uart1_fracmux __initdata =
+ MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(16), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3328_uart2_fracmux __initdata =
+ MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(18), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
+ /*
+ * Clock-Architecture Diagram 1
+ */
+
+ DIV(0, "clk_24m", "xin24m", CLK_IGNORE_UNUSED,
+ RK3328_CLKSEL_CON(2), 8, 5, DFLAGS),
+ COMPOSITE(SCLK_RTC32K, "clk_rtc32k", mux_2plls_xin24m_p, 0,
+ RK3328_CLKSEL_CON(38), 14, 2, MFLAGS, 0, 14, DFLAGS,
+ RK3328_CLKGATE_CON(0), 11, GFLAGS),
+ /* PD_MISC */
+ MUX(HDMIPHY, "hdmiphy", mux_hdmiphy_p, CLK_SET_RATE_PARENT,
+ RK3328_MISC_CON, 13, 1, MFLAGS),
+ MUX(USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
+ RK3328_MISC_CON, 15, 1, MFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 2
+ */
+
+ /* PD_CORE */
+ GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(0), 0, GFLAGS),
+ GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(0), 2, GFLAGS),
+ GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(0), 1, GFLAGS),
+ GATE(0, "npll_core", "npll", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(0), 12, GFLAGS),
+ COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
+ RK3328_CLKSEL_CON(1), 0, 4,
+ DFLAGS | CLK_DIVIDER_READ_ONLY,
+ RK3328_CLKGATE_CON(7), 0, GFLAGS),
+ COMPOSITE_NOMUX(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED,
+ RK3328_CLKSEL_CON(1), 4, 3,
+ DFLAGS | CLK_DIVIDER_READ_ONLY,
+ RK3328_CLKGATE_CON(7), 1, GFLAGS),
+ GATE(0, "aclk_core_niu", "aclk_core", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(13), 0, GFLAGS),
+ GATE(0, "aclk_gic400", "aclk_core", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(13), 1, GFLAGS),
+
+ GATE(0, "clk_jtag", "jtag_clkin", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(7), 2, GFLAGS),
+
+ /* PD_GPU */
+ COMPOSITE(0, "aclk_gpu_pre", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(44), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(6), 6, GFLAGS),
+ GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(14), 0, GFLAGS),
+ GATE(0, "aclk_gpu_niu", "aclk_gpu_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(14), 1, GFLAGS),
+
+ /* PD_DDR */
+ COMPOSITE(0, "clk_ddr", mux_ddrphy_p, CLK_IGNORE_UNUSED,
+ RK3328_CLKSEL_CON(3), 8, 2, MFLAGS, 0, 3,
+ DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+ RK3328_CLKGATE_CON(0), 4, GFLAGS),
+ GATE(0, "clk_ddrmsch", "clk_ddr", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(18), 6, GFLAGS),
+ GATE(0, "clk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(18), 5, GFLAGS),
+ GATE(0, "aclk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(18), 4, GFLAGS),
+ GATE(0, "clk_ddrmon", "xin24m", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(0), 6, GFLAGS),
+
+ COMPOSITE(PCLK_DDR, "pclk_ddr", mux_2plls_hdmiphy_p, 0,
+ RK3328_CLKSEL_CON(4), 13, 2, MFLAGS, 8, 3, DFLAGS,
+ RK3328_CLKGATE_CON(7), 4, GFLAGS),
+ GATE(0, "pclk_ddrupctl", "pclk_ddr", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(18), 1, GFLAGS),
+ GATE(0, "pclk_ddr_msch", "pclk_ddr", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(18), 2, GFLAGS),
+ GATE(0, "pclk_ddr_mon", "pclk_ddr", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(18), 3, GFLAGS),
+ GATE(0, "pclk_ddrstdby", "pclk_ddr", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(18), 7, GFLAGS),
+ GATE(0, "pclk_ddr_grf", "pclk_ddr", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(18), 9, GFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 3
+ */
+ /* PD_BUS */
+ COMPOSITE(ACLK_BUS_PRE, "aclk_bus_pre", mux_2plls_hdmiphy_p, 0,
+ RK3328_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(8), 0, GFLAGS),
+ COMPOSITE_NOMUX(HCLK_BUS_PRE, "hclk_bus_pre", "aclk_bus_pre", 0,
+ RK3328_CLKSEL_CON(1), 8, 2, DFLAGS,
+ RK3328_CLKGATE_CON(8), 1, GFLAGS),
+ COMPOSITE_NOMUX(PCLK_BUS_PRE, "pclk_bus_pre", "aclk_bus_pre", 0,
+ RK3328_CLKSEL_CON(1), 12, 3, DFLAGS,
+ RK3328_CLKGATE_CON(8), 2, GFLAGS),
+ GATE(0, "pclk_bus", "pclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(8), 3, GFLAGS),
+ GATE(0, "pclk_phy_pre", "pclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(8), 4, GFLAGS),
+
+ COMPOSITE(SCLK_TSP, "clk_tsp", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(21), 15, 1, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(2), 5, GFLAGS),
+ GATE(0, "clk_hsadc_tsp", "ext_gpio3a2", 0,
+ RK3328_CLKGATE_CON(17), 13, GFLAGS),
+
+ /* PD_I2S */
+ COMPOSITE(0, "clk_i2s0_div", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(6), 15, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(1), 1, GFLAGS),
+ COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div",
+ CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(7), 0,
+ RK3328_CLKGATE_CON(1), 2, GFLAGS,
+ &rk3328_i2s0_fracmux),
+ GATE(SCLK_I2S0, "clk_i2s0", "i2s0_pre", CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(1), 3, GFLAGS),
+
+ COMPOSITE(0, "clk_i2s1_div", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(8), 15, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(1), 4, GFLAGS),
+ COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div",
+ CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(9), 0,
+ RK3328_CLKGATE_CON(1), 5, GFLAGS,
+ &rk3328_i2s1_fracmux),
+ GATE(SCLK_I2S1, "clk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(0), 6, GFLAGS),
+ COMPOSITE_NODIV(SCLK_I2S1_OUT, "i2s1_out", mux_i2s1out_p, 0,
+ RK3328_CLKSEL_CON(8), 12, 1, MFLAGS,
+ RK3328_CLKGATE_CON(1), 7, GFLAGS),
+
+ COMPOSITE(0, "clk_i2s2_div", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(1), 8, GFLAGS),
+ COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div",
+ CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(11), 0,
+ RK3328_CLKGATE_CON(1), 9, GFLAGS,
+ &rk3328_i2s2_fracmux),
+ GATE(SCLK_I2S2, "clk_i2s2", "i2s2_pre", CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(1), 10, GFLAGS),
+ COMPOSITE_NODIV(SCLK_I2S2_OUT, "i2s2_out", mux_i2s2out_p, 0,
+ RK3328_CLKSEL_CON(10), 12, 1, MFLAGS,
+ RK3328_CLKGATE_CON(1), 11, GFLAGS),
+
+ COMPOSITE(0, "clk_spdif_div", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(12), 15, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(1), 12, GFLAGS),
+ COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div",
+ CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(13), 0,
+ RK3328_CLKGATE_CON(1), 13, GFLAGS,
+ &rk3328_spdif_fracmux),
+
+ /* PD_UART */
+ COMPOSITE(0, "clk_uart0_div", mux_2plls_u480m_p, 0,
+ RK3328_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(1), 14, GFLAGS),
+ COMPOSITE(0, "clk_uart1_div", mux_2plls_u480m_p, 0,
+ RK3328_CLKSEL_CON(16), 12, 2, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 0, GFLAGS),
+ COMPOSITE(0, "clk_uart2_div", mux_2plls_u480m_p,
+ 0, RK3328_CLKSEL_CON(18), 12, 2, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 2, GFLAGS),
+ COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div",
+ CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(15), 0,
+ RK3328_CLKGATE_CON(1), 15, GFLAGS,
+ &rk3328_uart0_fracmux),
+ COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div",
+ CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(17), 0,
+ RK3328_CLKGATE_CON(2), 1, GFLAGS,
+ &rk3328_uart1_fracmux),
+ COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div",
+ CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(19), 0,
+ RK3328_CLKGATE_CON(2), 3, GFLAGS,
+ &rk3328_uart2_fracmux),
+
+ /*
+ * Clock-Architecture Diagram 4
+ */
+ COMPOSITE(SCLK_I2C0, "clk_i2c0", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(34), 7, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 9, GFLAGS),
+ COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(34), 15, 1, MFLAGS, 8, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 10, GFLAGS),
+ COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(35), 7, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 11, GFLAGS),
+ COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(35), 15, 1, MFLAGS, 8, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 12, GFLAGS),
+ COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 4, GFLAGS),
+ COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "clk_24m", 0,
+ RK3328_CLKSEL_CON(22), 0, 10, DFLAGS,
+ RK3328_CLKGATE_CON(2), 6, GFLAGS),
+ COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "clk_24m", 0,
+ RK3328_CLKSEL_CON(23), 0, 10, DFLAGS,
+ RK3328_CLKGATE_CON(2), 14, GFLAGS),
+ COMPOSITE(SCLK_SPI, "clk_spi", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(24), 7, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 7, GFLAGS),
+ COMPOSITE(SCLK_PWM, "clk_pwm", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(24), 15, 1, MFLAGS, 8, 7, DFLAGS,
+ RK3328_CLKGATE_CON(2), 8, GFLAGS),
+ COMPOSITE(SCLK_OTP, "clk_otp", mux_2plls_xin24m_p, 0,
+ RK3328_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 6, DFLAGS,
+ RK3328_CLKGATE_CON(3), 8, GFLAGS),
+ COMPOSITE(SCLK_EFUSE, "clk_efuse", mux_2plls_xin24m_p, 0,
+ RK3328_CLKSEL_CON(5), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(2), 13, GFLAGS),
+ COMPOSITE(SCLK_PDM, "clk_pdm", mux_cpll_gpll_apll_p,
+ CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(20), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(2), 15, GFLAGS),
+
+ GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0,
+ RK3328_CLKGATE_CON(8), 5, GFLAGS),
+ GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0,
+ RK3328_CLKGATE_CON(8), 6, GFLAGS),
+ GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0,
+ RK3328_CLKGATE_CON(8), 7, GFLAGS),
+ GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0,
+ RK3328_CLKGATE_CON(8), 8, GFLAGS),
+ GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0,
+ RK3328_CLKGATE_CON(8), 9, GFLAGS),
+ GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0,
+ RK3328_CLKGATE_CON(8), 10, GFLAGS),
+
+ COMPOSITE(SCLK_WIFI, "clk_wifi", mux_2plls_u480m_p, 0,
+ RK3328_CLKSEL_CON(52), 6, 2, MFLAGS, 0, 6, DFLAGS,
+ RK3328_CLKGATE_CON(0), 10, GFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 5
+ */
+ /* PD_VIDEO */
+ COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(6), 0, GFLAGS),
+ FACTOR_GATE(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre",
+ 0, 1, 4,
+ RK3328_CLKGATE_CON(11), 0, GFLAGS),
+ GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(24), 0, GFLAGS),
+ GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(24), 1, GFLAGS),
+ GATE(0, "aclk_rkvdec_niu", "aclk_rkvdec_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(24), 2, GFLAGS),
+ GATE(0, "hclk_rkvdec_niu", "hclk_rkvdec_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(24), 3, GFLAGS),
+
+ COMPOSITE(SCLK_VDEC_CABAC, "sclk_vdec_cabac", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(48), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(6), 1, GFLAGS),
+
+ COMPOSITE(SCLK_VDEC_CORE, "sclk_vdec_core", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(6), 2, GFLAGS),
+
+ COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(50), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(6), 5, GFLAGS),
+ FACTOR_GATE(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4,
+ RK3328_CLKGATE_CON(11), 8, GFLAGS),
+ GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(23), 0, GFLAGS),
+ GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(23), 1, GFLAGS),
+ GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(23), 2, GFLAGS),
+ GATE(0, "hclk_vpu_niu", "hclk_vpu_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(23), 3, GFLAGS),
+
+ COMPOSITE(ACLK_RKVENC, "aclk_rkvenc", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(51), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(6), 3, GFLAGS),
+ FACTOR_GATE(HCLK_RKVENC, "hclk_rkvenc", "aclk_rkvenc", 0, 1, 4,
+ RK3328_CLKGATE_CON(11), 4, GFLAGS),
+ GATE(0, "aclk_rkvenc_niu", "aclk_rkvenc", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(25), 0, GFLAGS),
+ GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(25), 1, GFLAGS),
+ GATE(ACLK_H265, "aclk_h265", "aclk_rkvenc", 0,
+ RK3328_CLKGATE_CON(25), 0, GFLAGS),
+ GATE(PCLK_H265, "pclk_h265", "hclk_rkvenc", 0,
+ RK3328_CLKGATE_CON(25), 1, GFLAGS),
+ GATE(ACLK_H264, "aclk_h264", "aclk_rkvenc", 0,
+ RK3328_CLKGATE_CON(25), 0, GFLAGS),
+ GATE(HCLK_H264, "hclk_h264", "hclk_rkvenc", 0,
+ RK3328_CLKGATE_CON(25), 1, GFLAGS),
+ GATE(ACLK_AXISRAM, "aclk_axisram", "aclk_rkvenc", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(25), 0, GFLAGS),
+
+ COMPOSITE(SCLK_VENC_CORE, "sclk_venc_core", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(51), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(6), 4, GFLAGS),
+
+ COMPOSITE(SCLK_VENC_DSP, "sclk_venc_dsp", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(52), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(6), 7, GFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 6
+ */
+ /* PD_VIO */
+ COMPOSITE(ACLK_VIO_PRE, "aclk_vio_pre", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(37), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(5), 2, GFLAGS),
+ DIV(HCLK_VIO_PRE, "hclk_vio_pre", "aclk_vio_pre", 0,
+ RK3328_CLKSEL_CON(37), 8, 5, DFLAGS),
+
+ COMPOSITE(ACLK_RGA_PRE, "aclk_rga_pre", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(5), 0, GFLAGS),
+ COMPOSITE(SCLK_RGA, "clk_rga", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(5), 1, GFLAGS),
+ COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", mux_4plls_p, 0,
+ RK3328_CLKSEL_CON(39), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(5), 5, GFLAGS),
+ GATE(0, "clk_hdmi_sfc", "xin24m", 0,
+ RK3328_CLKGATE_CON(5), 4, GFLAGS),
+
+ COMPOSITE_NODIV(0, "clk_cif_src", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(42), 7, 1, MFLAGS,
+ RK3328_CLKGATE_CON(5), 3, GFLAGS),
+ COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cif_out", mux_sclk_cif_p,
+ CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(42), 5, 1, MFLAGS, 0, 5, DFLAGS),
+
+ COMPOSITE(DCLK_LCDC_SRC, "dclk_lcdc_src", mux_gpll_cpll_p, 0,
+ RK3328_CLKSEL_CON(40), 0, 1, MFLAGS, 8, 8, DFLAGS,
+ RK3328_CLKGATE_CON(5), 6, GFLAGS),
+ DIV(DCLK_HDMIPHY, "dclk_hdmiphy", "dclk_lcdc_src", 0,
+ RK3328_CLKSEL_CON(40), 3, 3, DFLAGS),
+ MUX(DCLK_LCDC, "dclk_lcdc", mux_dclk_lcdc_p, 0,
+ RK3328_CLKSEL_CON(40), 1, 1, MFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 7
+ */
+ /* PD_PERI */
+ GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(4), 0, GFLAGS),
+ GATE(0, "cpll_peri", "cpll", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(4), 1, GFLAGS),
+ GATE(0, "hdmiphy_peri", "hdmiphy", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(4), 2, GFLAGS),
+ COMPOSITE_NOGATE(ACLK_PERI_PRE, "aclk_peri_pre", mux_aclk_peri_pre_p, 0,
+ RK3328_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS),
+ COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_pre",
+ CLK_IGNORE_UNUSED,
+ RK3328_CLKSEL_CON(29), 0, 2, DFLAGS,
+ RK3328_CLKGATE_CON(10), 2, GFLAGS),
+ COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_pre",
+ CLK_IGNORE_UNUSED,
+ RK3328_CLKSEL_CON(29), 4, 3, DFLAGS,
+ RK3328_CLKGATE_CON(10), 1, GFLAGS),
+ GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre",
+ CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT,
+ RK3328_CLKGATE_CON(10), 0, GFLAGS),
+
+ COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_2plls_24m_u480m_p, 0,
+ RK3328_CLKSEL_CON(30), 8, 2, MFLAGS, 0, 8, DFLAGS,
+ RK3328_CLKGATE_CON(4), 3, GFLAGS),
+
+ COMPOSITE(SCLK_SDIO, "clk_sdio", mux_2plls_24m_u480m_p, 0,
+ RK3328_CLKSEL_CON(31), 8, 2, MFLAGS, 0, 8, DFLAGS,
+ RK3328_CLKGATE_CON(4), 4, GFLAGS),
+
+ COMPOSITE(SCLK_EMMC, "clk_emmc", mux_2plls_24m_u480m_p, 0,
+ RK3328_CLKSEL_CON(32), 8, 2, MFLAGS, 0, 8, DFLAGS,
+ RK3328_CLKGATE_CON(4), 5, GFLAGS),
+
+ COMPOSITE(SCLK_SDMMC_EXT, "clk_sdmmc_ext",
+ mux_2plls_24m_u480m_p, 0,
+ RK3328_CLKSEL_CON(43), 8, 2, MFLAGS, 0, 8, DFLAGS,
+ RK3328_CLKGATE_CON(4), 10, GFLAGS),
+
+ COMPOSITE(SCLK_REF_USB3OTG_SRC, "clk_ref_usb3otg_src", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(45), 7, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3328_CLKGATE_CON(4), 9, GFLAGS),
+
+ MUX(SCLK_REF_USB3OTG, "clk_ref_usb3otg",
+ mux_ref_usb3otg_src_p, CLK_SET_RATE_PARENT,
+ RK3328_CLKSEL_CON(45), 8, 1, MFLAGS),
+
+ GATE(SCLK_USB3OTG_REF, "clk_usb3otg_ref", "xin24m", 0,
+ RK3328_CLKGATE_CON(4), 7, GFLAGS),
+
+ COMPOSITE(SCLK_USB3OTG_SUSPEND, "clk_usb3otg_suspend",
+ mux_xin24m_32k_p, 0,
+ RK3328_CLKSEL_CON(33), 15, 1, MFLAGS, 0, 10, DFLAGS,
+ RK3328_CLKGATE_CON(4), 8, GFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 8
+ */
+ /* PD_GMAC */
+
+ COMPOSITE(ACLK_GMAC, "aclk_gmac", mux_2plls_hdmiphy_p, 0,
+ RK3328_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(3), 2, GFLAGS),
+ COMPOSITE_NOMUX(PCLK_GMAC, "pclk_gmac", "aclk_gmac", 0,
+ RK3328_CLKSEL_CON(25), 8, 3, DFLAGS,
+ RK3328_CLKGATE_CON(9), 0, GFLAGS),
+
+ COMPOSITE(SCLK_MAC2IO_SRC, "clk_mac2io_src", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(27), 7, 1, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(3), 1, GFLAGS),
+ GATE(SCLK_MAC2IO_REF, "clk_mac2io_ref", "clk_mac2io", 0,
+ RK3328_CLKGATE_CON(9), 7, GFLAGS),
+ GATE(SCLK_MAC2IO_RX, "clk_mac2io_rx", "clk_mac2io", 0,
+ RK3328_CLKGATE_CON(9), 4, GFLAGS),
+ GATE(SCLK_MAC2IO_TX, "clk_mac2io_tx", "clk_mac2io", 0,
+ RK3328_CLKGATE_CON(9), 5, GFLAGS),
+ GATE(SCLK_MAC2IO_REFOUT, "clk_mac2io_refout", "clk_mac2io", 0,
+ RK3328_CLKGATE_CON(9), 6, GFLAGS),
+ COMPOSITE(SCLK_MAC2IO_OUT, "clk_mac2io_out", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(27), 15, 1, MFLAGS, 8, 5, DFLAGS,
+ RK3328_CLKGATE_CON(3), 5, GFLAGS),
+
+ COMPOSITE(SCLK_MAC2PHY_SRC, "clk_mac2phy_src", mux_2plls_p, 0,
+ RK3328_CLKSEL_CON(26), 7, 1, MFLAGS, 0, 5, DFLAGS,
+ RK3328_CLKGATE_CON(3), 0, GFLAGS),
+ GATE(SCLK_MAC2PHY_REF, "clk_mac2phy_ref", "clk_mac2phy", 0,
+ RK3328_CLKGATE_CON(9), 3, GFLAGS),
+ GATE(SCLK_MAC2PHY_RXTX, "clk_mac2phy_rxtx", "clk_mac2phy", 0,
+ RK3328_CLKGATE_CON(9), 1, GFLAGS),
+ COMPOSITE_NOMUX(SCLK_MAC2PHY_OUT, "clk_mac2phy_out", "clk_mac2phy", 0,
+ RK3328_CLKSEL_CON(26), 8, 2, DFLAGS,
+ RK3328_CLKGATE_CON(9), 2, GFLAGS),
+
+ FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+
+ /*
+ * Clock-Architecture Diagram 9
+ */
+
+ /* PD_VOP */
+ GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0,
+ RK3328_CLKGATE_CON(21), 10, GFLAGS),
+ GATE(0, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(22), 3, GFLAGS),
+ GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0,
+ RK3328_CLKGATE_CON(21), 2, GFLAGS),
+ GATE(0, "aclk_vop_niu", "aclk_vop_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(21), 4, GFLAGS),
+
+ GATE(ACLK_IEP, "aclk_iep", "aclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(21), 6, GFLAGS),
+ GATE(ACLK_CIF, "aclk_cif", "aclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(21), 8, GFLAGS),
+ GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(21), 15, GFLAGS),
+ GATE(0, "aclk_vio_niu", "aclk_vio_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(22), 2, GFLAGS),
+
+ GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(21), 3, GFLAGS),
+ GATE(0, "hclk_vop_niu", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(21), 5, GFLAGS),
+ GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(21), 7, GFLAGS),
+ GATE(HCLK_CIF, "hclk_cif", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(21), 9, GFLAGS),
+ GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(21), 11, GFLAGS),
+ GATE(0, "hclk_ahb1tom", "hclk_vio_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(21), 12, GFLAGS),
+ GATE(0, "pclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(21), 13, GFLAGS),
+ GATE(0, "hclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(21), 14, GFLAGS),
+ GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(22), 0, GFLAGS),
+ GATE(HCLK_VIO, "hclk_vio", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(22), 1, GFLAGS),
+ GATE(PCLK_HDMI, "pclk_hdmi", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(22), 4, GFLAGS),
+ GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0,
+ RK3328_CLKGATE_CON(22), 5, GFLAGS),
+
+ /* PD_PERI */
+ GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(19), 11, GFLAGS),
+ GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0,
+ RK3328_CLKGATE_CON(19), 4, GFLAGS),
+
+ GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0,
+ RK3328_CLKGATE_CON(19), 0, GFLAGS),
+ GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0,
+ RK3328_CLKGATE_CON(19), 1, GFLAGS),
+ GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0,
+ RK3328_CLKGATE_CON(19), 2, GFLAGS),
+ GATE(HCLK_SDMMC_EXT, "hclk_sdmmc_ext", "hclk_peri", 0,
+ RK3328_CLKGATE_CON(19), 15, GFLAGS),
+ GATE(HCLK_HOST0, "hclk_host0", "hclk_peri", 0,
+ RK3328_CLKGATE_CON(19), 6, GFLAGS),
+ GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_peri", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(19), 7, GFLAGS),
+ GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0,
+ RK3328_CLKGATE_CON(19), 8, GFLAGS),
+ GATE(HCLK_OTG_PMU, "hclk_otg_pmu", "hclk_peri", 0,
+ RK3328_CLKGATE_CON(19), 9, GFLAGS),
+ GATE(0, "hclk_peri_niu", "hclk_peri", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(19), 12, GFLAGS),
+ GATE(0, "pclk_peri_niu", "hclk_peri", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(19), 13, GFLAGS),
+
+ /* PD_GMAC */
+ GATE(ACLK_MAC2PHY, "aclk_mac2phy", "aclk_gmac", 0,
+ RK3328_CLKGATE_CON(26), 0, GFLAGS),
+ GATE(ACLK_MAC2IO, "aclk_mac2io", "aclk_gmac", 0,
+ RK3328_CLKGATE_CON(26), 2, GFLAGS),
+ GATE(0, "aclk_gmac_niu", "aclk_gmac", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(26), 4, GFLAGS),
+ GATE(PCLK_MAC2PHY, "pclk_mac2phy", "pclk_gmac", 0,
+ RK3328_CLKGATE_CON(26), 1, GFLAGS),
+ GATE(PCLK_MAC2IO, "pclk_mac2io", "pclk_gmac", 0,
+ RK3328_CLKGATE_CON(26), 3, GFLAGS),
+ GATE(0, "pclk_gmac_niu", "pclk_gmac", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(26), 5, GFLAGS),
+
+ /* PD_BUS */
+ GATE(0, "aclk_bus_niu", "aclk_bus_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(15), 12, GFLAGS),
+ GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(15), 11, GFLAGS),
+ GATE(ACLK_TSP, "aclk_tsp", "aclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(17), 12, GFLAGS),
+ GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(15), 0, GFLAGS),
+ GATE(ACLK_DMAC, "aclk_dmac_bus", "aclk_bus_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(15), 1, GFLAGS),
+
+ GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(15), 2, GFLAGS),
+ GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(15), 3, GFLAGS),
+ GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(15), 4, GFLAGS),
+ GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(15), 5, GFLAGS),
+ GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(15), 6, GFLAGS),
+ GATE(HCLK_TSP, "hclk_tsp", "hclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(17), 11, GFLAGS),
+ GATE(HCLK_CRYPTO_MST, "hclk_crypto_mst", "hclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(15), 7, GFLAGS),
+ GATE(HCLK_CRYPTO_SLV, "hclk_crypto_slv", "hclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(15), 8, GFLAGS),
+ GATE(0, "hclk_bus_niu", "hclk_bus_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(15), 13, GFLAGS),
+ GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0,
+ RK3328_CLKGATE_CON(28), 0, GFLAGS),
+
+ GATE(0, "pclk_bus_niu", "pclk_bus", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(15), 14, GFLAGS),
+ GATE(0, "pclk_efuse", "pclk_bus", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(15), 9, GFLAGS),
+ GATE(0, "pclk_otp", "pclk_bus", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(28), 4, GFLAGS),
+ GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(15), 10, GFLAGS),
+ GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 0, GFLAGS),
+ GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 1, GFLAGS),
+ GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 2, GFLAGS),
+ GATE(PCLK_TIMER, "pclk_timer0", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 3, GFLAGS),
+ GATE(0, "pclk_stimer", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 4, GFLAGS),
+ GATE(PCLK_SPI, "pclk_spi", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 5, GFLAGS),
+ GATE(PCLK_PWM, "pclk_rk_pwm", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 6, GFLAGS),
+ GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 7, GFLAGS),
+ GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 8, GFLAGS),
+ GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 9, GFLAGS),
+ GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 10, GFLAGS),
+ GATE(PCLK_UART0, "pclk_uart0", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 11, GFLAGS),
+ GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 12, GFLAGS),
+ GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 13, GFLAGS),
+ GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 14, GFLAGS),
+ GATE(PCLK_DCF, "pclk_dcf", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(16), 15, GFLAGS),
+ GATE(PCLK_GRF, "pclk_grf", "pclk_bus", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 0, GFLAGS),
+ GATE(0, "pclk_cru", "pclk_bus", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 4, GFLAGS),
+ GATE(0, "pclk_sgrf", "pclk_bus", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 6, GFLAGS),
+ GATE(0, "pclk_sim", "pclk_bus", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 10, GFLAGS),
+ GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0,
+ RK3328_CLKGATE_CON(17), 15, GFLAGS),
+ GATE(0, "pclk_pmu", "pclk_bus", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(28), 3, GFLAGS),
+
+ GATE(PCLK_USB3PHY_OTG, "pclk_usb3phy_otg", "pclk_phy_pre", 0,
+ RK3328_CLKGATE_CON(28), 1, GFLAGS),
+ GATE(PCLK_USB3PHY_PIPE, "pclk_usb3phy_pipe", "pclk_phy_pre", 0,
+ RK3328_CLKGATE_CON(28), 2, GFLAGS),
+ GATE(PCLK_USB3_GRF, "pclk_usb3_grf", "pclk_phy_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 2, GFLAGS),
+ GATE(PCLK_USB2_GRF, "pclk_usb2_grf", "pclk_phy_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 14, GFLAGS),
+ GATE(0, "pclk_ddrphy", "pclk_phy_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 13, GFLAGS),
+ GATE(0, "pclk_acodecphy", "pclk_phy_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 5, GFLAGS),
+ GATE(PCLK_HDMIPHY, "pclk_hdmiphy", "pclk_phy_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 7, GFLAGS),
+ GATE(0, "pclk_vdacphy", "pclk_phy_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(17), 8, GFLAGS),
+ GATE(0, "pclk_phy_niu", "pclk_phy_pre", CLK_IGNORE_UNUSED,
+ RK3328_CLKGATE_CON(15), 15, GFLAGS),
+
+ /* PD_MMC */
+ MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc",
+ RK3328_SDMMC_CON0, 1),
+ MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc",
+ RK3328_SDMMC_CON1, 1),
+
+ MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio",
+ RK3328_SDIO_CON0, 1),
+ MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio",
+ RK3328_SDIO_CON1, 1),
+
+ MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc",
+ RK3328_EMMC_CON0, 1),
+ MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc",
+ RK3328_EMMC_CON1, 1),
+
+ MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "sclk_sdmmc_ext",
+ RK3328_SDMMC_EXT_CON0, 1),
+ MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "sclk_sdmmc_ext",
+ RK3328_SDMMC_EXT_CON1, 1),
+};
+
+static struct rockchip_clk_branch rk3328_clk_grf_branches[] __initdata = {
+ /*
+ * GRF CRU Clock-Architecture
+ */
+ MUX(SCLK_MAC2IO, "clk_mac2io", mux_mac2io_src_p, 0,
+ RK3328_GRF_MAC_CON1, 10, 1, MFLAGS),
+ MUX(SCLK_MAC2PHY, "clk_mac2phy", mux_mac2phy_src_p, 0,
+ RK3328_GRF_MAC_CON2, 10, 1, MFLAGS),
+};
+
+static const char *const rk3328_critical_clocks[] __initconst = {
+ "aclk_bus",
+ "pclk_bus",
+ "hclk_bus",
+ "aclk_peri",
+ "hclk_peri",
+ "pclk_peri",
+ "pclk_dbg",
+ "aclk_core_niu",
+ "aclk_gic400",
+ "aclk_intmem",
+ "hclk_rom",
+ "pclk_grf",
+ "pclk_cru",
+ "pclk_sgrf",
+ "pclk_timer0",
+ "clk_timer0",
+ "pclk_ddr_msch",
+ "pclk_ddr_mon",
+ "pclk_ddr_grf",
+ "clk_ddrupctl",
+ "clk_ddrmsch",
+ "hclk_ahb1tom",
+ "clk_jtag",
+ "pclk_ddrphy",
+ "pclk_pmu",
+ "hclk_otg_pmu",
+ "aclk_rga_niu",
+ "pclk_vio_h2p",
+ "hclk_vio_h2p",
+};
+
+static void __iomem *rk3328_cru_base;
+
+void rk3328_dump_cru(void)
+{
+ if (rk3328_cru_base) {
+ pr_warn("CRU:\n");
+ print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET,
+ 32, 4, rk3328_cru_base,
+ 0x400, false);
+ }
+}
+EXPORT_SYMBOL_GPL(rk3328_dump_cru);
+
+static int rk3328_clk_panic(struct notifier_block *this,
+ unsigned long ev, void *ptr)
+{
+ rk3328_dump_cru();
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block rk3328_clk_panic_block = {
+ .notifier_call = rk3328_clk_panic,
+};
+
+static void __init rk3328_clk_init(struct device_node *np)
+{
+ struct rockchip_clk_provider *ctx;
+ void __iomem *reg_base;
+
+ reg_base = of_iomap(np, 0);
+ if (!reg_base) {
+ pr_err("%s: could not map cru region\n", __func__);
+ return;
+ }
+
+ rk3328_cru_base = reg_base;
+
+ ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+ if (IS_ERR(ctx)) {
+ pr_err("%s: rockchip clk init failed\n", __func__);
+ iounmap(reg_base);
+ return;
+ }
+
+ rockchip_clk_register_plls(ctx, rk3328_pll_clks,
+ ARRAY_SIZE(rk3328_pll_clks),
+ RK3328_GRF_SOC_STATUS0);
+ rockchip_clk_register_branches(ctx, rk3328_clk_branches,
+ ARRAY_SIZE(rk3328_clk_branches));
+ rockchip_clk_protect_critical(rk3328_critical_clocks,
+ ARRAY_SIZE(rk3328_critical_clocks));
+
+ rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
+ mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
+ &rk3328_cpuclk_data, rk3328_cpuclk_rates,
+ ARRAY_SIZE(rk3328_cpuclk_rates));
+
+ rockchip_register_softrst(np, 11, reg_base + RK3328_SOFTRST_CON(0),
+ ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+ rockchip_register_restart_notifier(ctx, RK3328_GLB_SRST_FST, NULL);
+
+ rockchip_clk_of_add_provider(np, ctx);
+
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &rk3328_clk_panic_block);
+}
+
+CLK_OF_DECLARE(rk3328_cru, "rockchip,rk3328-cru", rk3328_clk_init);
+
+static void __init rk3328_grf_clk_init(struct device_node *np)
+{
+ struct rockchip_clk_provider *ctx;
+ void __iomem *reg_base;
+
+ reg_base = of_iomap(np, 0);
+ if (!reg_base) {
+ pr_err("%s: could not map cru pmu region\n", __func__);
+ return;
+ }
+
+ ctx = rockchip_clk_init(np, reg_base, CLKGRF_NR_CLKS);
+ if (IS_ERR(ctx)) {
+ pr_err("%s: rockchip pmu clk init failed\n", __func__);
+ return;
+ }
+
+ rockchip_clk_register_branches(ctx, rk3328_clk_grf_branches,
+ ARRAY_SIZE(rk3328_clk_grf_branches));
+
+ rockchip_clk_of_add_provider(np, ctx);
+}
+
+CLK_OF_DECLARE(rk3328_cru_grf, "rockchip,rk3328-grf", rk3328_grf_clk_init);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index d67eecc4ade9..7225997f8d52 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -91,6 +91,28 @@
#define RK3288_EMMC_CON0 0x218
#define RK3288_EMMC_CON1 0x21c
+#define RK3328_PLL_CON(x) RK2928_PLL_CON(x)
+#define RK3328_CLKSEL_CON(x) ((x) * 0x4 + 0x100)
+#define RK3328_CLKGATE_CON(x) ((x) * 0x4 + 0x200)
+#define RK3328_GRFCLKSEL_CON(x) ((x) * 0x4 + 0x100)
+#define RK3328_GLB_SRST_FST 0x9c
+#define RK3328_GLB_SRST_SND 0x98
+#define RK3328_SOFTRST_CON(x) ((x) * 0x4 + 0x300)
+#define RK3328_MODE_CON 0x80
+#define RK3328_MISC_CON 0x84
+#define RK3328_DIV_ACLKM_MASK 0x7
+#define RK3328_DIV_ACLKM_SHIFT 4
+#define RK3328_DIV_PCLK_DBG_MASK 0xf
+#define RK3328_DIV_PCLK_DBG_SHIFT 0
+#define RK3328_SDMMC_CON0 0x380
+#define RK3328_SDMMC_CON1 0x384
+#define RK3328_SDIO_CON0 0x388
+#define RK3328_SDIO_CON1 0x38c
+#define RK3328_EMMC_CON0 0x390
+#define RK3328_EMMC_CON1 0x394
+#define RK3328_SDMMC_EXT_CON0 0x398
+#define RK3328_SDMMC_EXT_CON1 0x39C
+
#define RK3368_PLL_CON(x) RK2928_PLL_CON(x)
#define RK3368_CLKSEL_CON(x) ((x) * 0x4 + 0x100)
#define RK3368_CLKGATE_CON(x) ((x) * 0x4 + 0x200)
@@ -130,6 +152,7 @@
enum rockchip_pll_type {
pll_rk3036,
pll_rk3066,
+ pll_rk3328,
pll_rk3399,
};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 2/4] dt-bindings: add bindings for rk3328 clock controller
From: Elaine Zhang @ 2016-12-26 3:45 UTC (permalink / raw)
To: heiko, mturquette, sboyd, xf
Cc: robh+dt, mark.rutland, linux-clk, huangtao, xxx, cl,
linux-rockchip, linux-kernel, devicetree, linux-arm-kernel,
Elaine Zhang
In-Reply-To: <1482723930-5876-1-git-send-email-zhangqing@rock-chips.com>
Add devicetree bindings for Rockchip cru which found on
Rockchip SoCs.
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
.../bindings/clock/rockchip,rk3328-cru.txt | 57 ++++++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
new file mode 100644
index 000000000000..20053494d49f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
@@ -0,0 +1,57 @@
+* Rockchip RK3328 Clock and Reset Unit
+
+The RK3328 clock controller generates and supplies clock to various
+controllers within the SoC and also implements a reset controller for SoC
+peripherals.
+
+Required Properties:
+
+- compatible: should be "rockchip,rk3328-cru"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Optional Properties:
+
+- rockchip,grf: phandle to the syscon managing the "general register files"
+ If missing pll rates are not changeable, due to the missing pll lock status.
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume. All available clocks are defined as
+preprocessor macros in the dt-bindings/clock/rk3328-cru.h headers and can be
+used in device tree sources. Similar macros exist for the reset sources in
+these files.
+
+External clocks:
+
+There are several clocks that are generated outside the SoC. It is expected
+that they are defined using standard clock bindings with following
+clock-output-names:
+ - "xin24m" - crystal input - required,
+ - "clkin_i2s" - external I2S clock - optional,
+ - "gmac_clkin" - external GMAC clock - optional
+ - "phy_50m_out" - output clock of the pll in the mac phy
+
+Example: Clock controller node:
+
+ cru: clock-controller@ff440000 {
+ compatible = "rockchip,rk3328-cru", "rockchip,cru", "syscon";
+ reg = <0x0 0xff440000 0x0 0x1000>;
+ rockchip,grf = <&grf>;
+
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+Example: UART controller node that consumes the clock generated by the clock
+ controller:
+
+ uart0: serial@ff120000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xff120000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&cru SCLK_UART0>;
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v3 1/4] clk: rockchip: add dt-binding header for rk3328
From: Elaine Zhang @ 2016-12-26 3:45 UTC (permalink / raw)
To: heiko, mturquette, sboyd, xf
Cc: robh+dt, mark.rutland, linux-clk, huangtao, xxx, cl,
linux-rockchip, linux-kernel, devicetree, linux-arm-kernel,
Elaine Zhang
In-Reply-To: <1482723930-5876-1-git-send-email-zhangqing@rock-chips.com>
Add the dt-bindings header for the rk3328, that gets shared between
the clock controller and the clock references in the dts.
Add softreset ID for rk3328.
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
include/dt-bindings/clock/rk3328-cru.h | 403 +++++++++++++++++++++++++++++++++
1 file changed, 403 insertions(+)
create mode 100644 include/dt-bindings/clock/rk3328-cru.h
diff --git a/include/dt-bindings/clock/rk3328-cru.h b/include/dt-bindings/clock/rk3328-cru.h
new file mode 100644
index 000000000000..545ed7541316
--- /dev/null
+++ b/include/dt-bindings/clock/rk3328-cru.h
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Elaine <zhangqing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3328_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3328_H
+
+/* core clocks */
+#define PLL_APLL 1
+#define PLL_DPLL 2
+#define PLL_CPLL 3
+#define PLL_GPLL 4
+#define PLL_NPLL 5
+#define ARMCLK 6
+
+/* sclk gates (special clocks) */
+#define SCLK_RTC32K 30
+#define SCLK_SDMMC_EXT 31
+#define SCLK_SPI 32
+#define SCLK_SDMMC 33
+#define SCLK_SDIO 34
+#define SCLK_EMMC 35
+#define SCLK_TSADC 36
+#define SCLK_SARADC 37
+#define SCLK_UART0 38
+#define SCLK_UART1 39
+#define SCLK_UART2 40
+#define SCLK_I2S0 41
+#define SCLK_I2S1 42
+#define SCLK_I2S2 43
+#define SCLK_I2S1_OUT 44
+#define SCLK_I2S2_OUT 45
+#define SCLK_SPDIF 46
+#define SCLK_TIMER0 47
+#define SCLK_TIMER1 48
+#define SCLK_TIMER2 49
+#define SCLK_TIMER3 50
+#define SCLK_TIMER4 51
+#define SCLK_TIMER5 52
+#define SCLK_WIFI 53
+#define SCLK_CIF_OUT 54
+#define SCLK_I2C0 55
+#define SCLK_I2C1 56
+#define SCLK_I2C2 57
+#define SCLK_I2C3 58
+#define SCLK_CRYPTO 59
+#define SCLK_PWM 60
+#define SCLK_PDM 61
+#define SCLK_EFUSE 62
+#define SCLK_OTP 63
+#define SCLK_DDRCLK 64
+#define SCLK_VDEC_CABAC 65
+#define SCLK_VDEC_CORE 66
+#define SCLK_VENC_DSP 67
+#define SCLK_VENC_CORE 68
+#define SCLK_RGA 69
+#define SCLK_HDMI_SFC 70
+#define SCLK_HDMI_CEC 71
+#define SCLK_USB3_REF 72
+#define SCLK_USB3_SUSPEND 73
+#define SCLK_SDMMC_DRV 74
+#define SCLK_SDIO_DRV 75
+#define SCLK_EMMC_DRV 76
+#define SCLK_SDMMC_EXT_DRV 77
+#define SCLK_SDMMC_SAMPLE 78
+#define SCLK_SDIO_SAMPLE 79
+#define SCLK_EMMC_SAMPLE 80
+#define SCLK_SDMMC_EXT_SAMPLE 81
+#define SCLK_VOP 82
+#define SCLK_MAC2PHY_RXTX 83
+#define SCLK_MAC2PHY_SRC 84
+#define SCLK_MAC2PHY_REF 85
+#define SCLK_MAC2PHY_OUT 86
+#define SCLK_MAC2IO_RX 87
+#define SCLK_MAC2IO_TX 88
+#define SCLK_MAC2IO_REFOUT 89
+#define SCLK_MAC2IO_REF 90
+#define SCLK_MAC2IO_OUT 91
+#define SCLK_TSP 92
+#define SCLK_HSADC_TSP 93
+#define SCLK_USB3PHY_REF 94
+#define SCLK_REF_USB3OTG 95
+#define SCLK_USB3OTG_REF 96
+#define SCLK_USB3OTG_SUSPEND 97
+#define SCLK_REF_USB3OTG_SRC 98
+#define SCLK_MAC2IO_SRC 99
+
+/* dclk gates */
+#define DCLK_LCDC 180
+#define DCLK_HDMIPHY 181
+#define HDMIPHY 182
+#define USB480M 183
+#define DCLK_LCDC_SRC 184
+
+/* aclk gates */
+#define ACLK_AXISRAM 190
+#define ACLK_VOP_PRE 191
+#define ACLK_USB3OTG 192
+#define ACLK_RGA_PRE 193
+#define ACLK_DMAC 194
+#define ACLK_GPU 195
+#define ACLK_BUS_PRE 196
+#define ACLK_PERI_PRE 197
+#define ACLK_RKVDEC_PRE 198
+#define ACLK_RKVDEC 199
+#define ACLK_RKVENC 200
+#define ACLK_VPU_PRE 201
+#define ACLK_VIO_PRE 202
+#define ACLK_VPU 203
+#define ACLK_VIO 204
+#define ACLK_VOP 205
+#define ACLK_GMAC 206
+#define ACLK_H265 207
+#define ACLK_H264 208
+#define ACLK_MAC2PHY 209
+#define ACLK_MAC2IO 210
+#define ACLK_DCF 211
+#define ACLK_TSP 212
+#define ACLK_PERI 213
+#define ACLK_RGA 214
+#define ACLK_IEP 215
+#define ACLK_CIF 216
+#define ACLK_HDCP 217
+
+/* pclk gates */
+#define PCLK_GPIO0 300
+#define PCLK_GPIO1 301
+#define PCLK_GPIO2 302
+#define PCLK_GPIO3 303
+#define PCLK_GRF 304
+#define PCLK_I2C0 305
+#define PCLK_I2C1 306
+#define PCLK_I2C2 307
+#define PCLK_I2C3 308
+#define PCLK_SPI 309
+#define PCLK_UART0 310
+#define PCLK_UART1 311
+#define PCLK_UART2 312
+#define PCLK_TSADC 313
+#define PCLK_PWM 314
+#define PCLK_TIMER 315
+#define PCLK_BUS_PRE 316
+#define PCLK_PERI_PRE 317
+#define PCLK_HDMI_CTRL 318
+#define PCLK_HDMI_PHY 319
+#define PCLK_GMAC 320
+#define PCLK_H265 321
+#define PCLK_MAC2PHY 322
+#define PCLK_MAC2IO 323
+#define PCLK_USB3PHY_OTG 324
+#define PCLK_USB3PHY_PIPE 325
+#define PCLK_USB3_GRF 326
+#define PCLK_USB2_GRF 327
+#define PCLK_HDMIPHY 328
+#define PCLK_DDR 329
+#define PCLK_PERI 330
+#define PCLK_HDMI 331
+#define PCLK_HDCP 332
+#define PCLK_DCF 333
+#define PCLK_SARADC 334
+
+/* hclk gates */
+#define HCLK_PERI 408
+#define HCLK_TSP 409
+#define HCLK_GMAC 410
+#define HCLK_I2S0_8CH 411
+#define HCLK_I2S1_8CH 413
+#define HCLK_I2S2_2CH 413
+#define HCLK_SPDIF_8CH 414
+#define HCLK_VOP 415
+#define HCLK_NANDC 416
+#define HCLK_SDMMC 417
+#define HCLK_SDIO 418
+#define HCLK_EMMC 419
+#define HCLK_SDMMC_EXT 420
+#define HCLK_RKVDEC_PRE 421
+#define HCLK_RKVDEC 422
+#define HCLK_RKVENC 423
+#define HCLK_VPU_PRE 424
+#define HCLK_VIO_PRE 425
+#define HCLK_VPU 426
+#define HCLK_VIO 427
+#define HCLK_BUS_PRE 428
+#define HCLK_PERI_PRE 429
+#define HCLK_H264 430
+#define HCLK_CIF 431
+#define HCLK_OTG_PMU 432
+#define HCLK_OTG 433
+#define HCLK_HOST0 434
+#define HCLK_HOST0_ARB 435
+#define HCLK_CRYPTO_MST 436
+#define HCLK_CRYPTO_SLV 437
+#define HCLK_PDM 438
+#define HCLK_IEP 439
+#define HCLK_RGA 440
+#define HCLK_HDCP 441
+
+#define CLK_NR_CLKS (HCLK_HDCP + 1)
+
+#define SCLK_MAC2IO 0
+#define SCLK_MAC2PHY 1
+
+#define CLKGRF_NR_CLKS (SCLK_MAC2PHY + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0_PO 0
+#define SRST_CORE1_PO 1
+#define SRST_CORE2_PO 2
+#define SRST_CORE3_PO 3
+#define SRST_CORE0 4
+#define SRST_CORE1 5
+#define SRST_CORE2 6
+#define SRST_CORE3 7
+#define SRST_CORE0_DBG 8
+#define SRST_CORE1_DBG 9
+#define SRST_CORE2_DBG 10
+#define SRST_CORE3_DBG 11
+#define SRST_TOPDBG 12
+#define SRST_CORE_NIU 13
+#define SRST_STRC_A 14
+#define SRST_L2C 15
+
+#define SRST_A53_GIC 18
+#define SRST_DAP 19
+#define SRST_PMU_P 21
+#define SRST_EFUSE 22
+#define SRST_BUSSYS_H 23
+#define SRST_BUSSYS_P 24
+#define SRST_SPDIF 25
+#define SRST_INTMEM 26
+#define SRST_ROM 27
+#define SRST_GPIO0 28
+#define SRST_GPIO1 29
+#define SRST_GPIO2 30
+#define SRST_GPIO3 31
+
+#define SRST_I2S0 32
+#define SRST_I2S1 33
+#define SRST_I2S2 34
+#define SRST_I2S0_H 35
+#define SRST_I2S1_H 36
+#define SRST_I2S2_H 37
+#define SRST_UART0 38
+#define SRST_UART1 39
+#define SRST_UART2 40
+#define SRST_UART0_P 41
+#define SRST_UART1_P 42
+#define SRST_UART2_P 43
+#define SRST_I2C0 44
+#define SRST_I2C1 45
+#define SRST_I2C2 46
+#define SRST_I2C3 47
+
+#define SRST_I2C0_P 48
+#define SRST_I2C1_P 49
+#define SRST_I2C2_P 50
+#define SRST_I2C3_P 51
+#define SRST_EFUSE_SE_P 52
+#define SRST_EFUSE_NS_P 53
+#define SRST_PWM0 54
+#define SRST_PWM0_P 55
+#define SRST_DMA 56
+#define SRST_TSP_A 57
+#define SRST_TSP_H 58
+#define SRST_TSP 59
+#define SRST_TSP_HSADC 60
+#define SRST_DCF_A 61
+#define SRST_DCF_P 62
+
+#define SRST_SCR 64
+#define SRST_SPI 65
+#define SRST_TSADC 66
+#define SRST_TSADC_P 67
+#define SRST_CRYPTO 68
+#define SRST_SGRF 69
+#define SRST_GRF 70
+#define SRST_USB_GRF 71
+#define SRST_TIMER_6CH_P 72
+#define SRST_TIMER0 73
+#define SRST_TIMER1 74
+#define SRST_TIMER2 75
+#define SRST_TIMER3 76
+#define SRST_TIMER4 77
+#define SRST_TIMER5 78
+#define SRST_USB3GRF 79
+
+#define SRST_PHYNIU 80
+#define SRST_HDMIPHY 81
+#define SRST_VDAC 82
+#define SRST_ACODEC_p 83
+#define SRST_SARADC 85
+#define SRST_SARADC_P 86
+#define SRST_GRF_DDR 87
+#define SRST_DFIMON 88
+#define SRST_MSCH 89
+#define SRST_DDRMSCH 91
+#define SRST_DDRCTRL 92
+#define SRST_DDRCTRL_P 93
+#define SRST_DDRPHY 94
+#define SRST_DDRPHY_P 95
+
+#define SRST_GMAC_NIU_A 96
+#define SRST_GMAC_NIU_P 97
+#define SRST_GMAC2PHY_A 98
+#define SRST_GMAC2IO_A 99
+#define SRST_MACPHY 100
+#define SRST_OTP_PHY 101
+#define SRST_GPU_A 102
+#define SRST_GPU_NIU_A 103
+#define SRST_SDMMCEXT 104
+#define SRST_PERIPH_NIU_A 105
+#define SRST_PERIHP_NIU_H 106
+#define SRST_PERIHP_P 107
+#define SRST_PERIPHSYS_H 108
+#define SRST_MMC0 109
+#define SRST_SDIO 110
+#define SRST_EMMC 111
+
+#define SRST_USB2OTG_H 112
+#define SRST_USB2OTG 113
+#define SRST_USB2OTG_ADP 114
+#define SRST_USB2HOST_H 115
+#define SRST_USB2HOST_ARB 116
+#define SRST_USB2HOST_AUX 117
+#define SRST_USB2HOST_EHCIPHY 118
+#define SRST_USB2HOST_UTMI 119
+#define SRST_USB3OTG 120
+#define SRST_USBPOR 121
+#define SRST_USB2OTG_UTMI 122
+#define SRST_USB2HOST_PHY_UTMI 123
+#define SRST_USB3OTG_UTMI 124
+#define SRST_USB3PHY_U2 125
+#define SRST_USB3PHY_U3 126
+#define SRST_USB3PHY_PIPE 127
+
+#define SRST_VIO_A 128
+#define SRST_VIO_BUS_H 129
+#define SRST_VIO_H2P_H 130
+#define SRST_VIO_ARBI_H 131
+#define SRST_VOP_NIU_A 132
+#define SRST_VOP_A 133
+#define SRST_VOP_H 134
+#define SRST_VOP_D 135
+#define SRST_RGA 136
+#define SRST_RGA_NIU_A 137
+#define SRST_RGA_A 138
+#define SRST_RGA_H 139
+#define SRST_IEP_A 140
+#define SRST_IEP_H 141
+#define SRST_HDMI 142
+#define SRST_HDMI_P 143
+
+#define SRST_HDCP_A 144
+#define SRST_HDCP 145
+#define SRST_HDCP_H 146
+#define SRST_CIF_A 147
+#define SRST_CIF_H 148
+#define SRST_CIF_P 149
+#define SRST_OTP_P 150
+#define SRST_OTP_SBPI 151
+#define SRST_OTP_USER 152
+#define SRST_DDRCTRL_A 153
+#define SRST_DDRSTDY_P 154
+#define SRST_DDRSTDY 155
+#define SRST_PDM_H 156
+#define SRST_PDM 157
+#define SRST_USB3PHY_OTG_P 158
+#define SRST_USB3PHY_PIPE_P 159
+
+#define SRST_VCODEC_A 160
+#define SRST_VCODEC_NIU_A 161
+#define SRST_VCODEC_H 162
+#define SRST_VCODEC_NIU_H 163
+#define SRST_VDEC_A 164
+#define SRST_VDEC_NIU_A 165
+#define SRST_VDEC_H 166
+#define SRST_VDEC_NIU_H 167
+#define SRST_VDEC_CORE 168
+#define SRST_VDEC_CABAC 169
+#define SRST_DDRPHYDIV 175
+
+#define SRST_RKVENC_NIU_A 176
+#define SRST_RKVENC_NIU_H 177
+#define SRST_RKVENC_H265_A 178
+#define SRST_RKVENC_H265_P 179
+#define SRST_RKVENC_H265_CORE 180
+#define SRST_RKVENC_H265_DSP 181
+#define SRST_RKVENC_H264_A 182
+#define SRST_RKVENC_H264_H 183
+#define SRST_RKVENC_INTMEM 184
+
+#endif
--
1.9.1
^ permalink raw reply related
* [PATCH v3 0/4] clk: rockchip: support clk controller for rk3328 SoC
From: Elaine Zhang @ 2016-12-26 3:45 UTC (permalink / raw)
To: heiko, mturquette, sboyd, xf
Cc: robh+dt, mark.rutland, linux-clk, huangtao, xxx, cl,
linux-rockchip, linux-kernel, devicetree, linux-arm-kernel,
Elaine Zhang
Changes in v3:
fix up the pll type pll_rk3328 description and use.
Changes in v2:
add bindings for rk3328 clock controller
Elaine Zhang (4):
clk: rockchip: add dt-binding header for rk3328
dt-bindings: add bindings for rk3328 clock controller
clk: rockchip: add clock controller for rk3328
clk: rockchip: add new pll-type for rk3328
.../bindings/clock/rockchip,rk3328-cru.txt | 57 ++
drivers/clk/rockchip/Makefile | 1 +
drivers/clk/rockchip/clk-pll.c | 16 +-
drivers/clk/rockchip/clk-rk3328.c | 1068 ++++++++++++++++++++
drivers/clk/rockchip/clk.h | 23 +
include/dt-bindings/clock/rk3328-cru.h | 403 ++++++++
6 files changed, 1565 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
create mode 100644 drivers/clk/rockchip/clk-rk3328.c
create mode 100644 include/dt-bindings/clock/rk3328-cru.h
--
1.9.1
^ permalink raw reply
* Re: [PATCH v8 0/5] Add intial support to DW MMC host on ZTE SoC
From: Jun Nie @ 2016-12-26 2:24 UTC (permalink / raw)
To: jh80.chung, shawn.guo, xie.baoyou, devicetree
Cc: ulf.hansson, jason.liu, chen.chaokai, lai.binz, linux-mmc,
robh+dt, mark.rutland
In-Reply-To: <1482382657-16681-1-git-send-email-jun.nie@linaro.org>
On 2016年12月22日 12:57, Jun Nie wrote:
> Add intial support to DW MMC host on ZTE SoC. It include platform
> specific wrapper driver and workarounds for fifo quirk.
>
> Changes vs version 7:
> - Re-order patches sequence so that new dts property is introduced before usage.
> - Remove unecessary property in zx mmc dts.
>
> Changes vs version 6:
> - Resolve confilict when rebase to latest dw-mmc.git for-ulf branch.
> - Add Shawn Lin's review tag.
>
> Changes vs version 5:
> - Add clock delay lock status check to save CPU cycle in timing tuning CMD.
>
> Changes vs version 4:
> - Fix missing empty dts compatible element in the end of compatible array.
>
> Changes vs version 3:
> - Fix brace error in document.
>
> Changes vs version 2:
> - Change dt property fifo-addr to data-addr and fifo-watermark-quirk to
> fifo-watermark-aligned.
> - Polish ZX MMC driver on minor coding style issues.
>
> Changes vs version 1:
> - Change fifo-addr-override to fifo-addr and remove its workaround tag in comments.
> - Remove ZX DW MMC driver reset cap in driver, which can be added in dt nodes.
>
>
> Jun Nie (5):
> Documentation: synopsys-dw-mshc: add binding for fifo quirks
> mmc: dw: Add fifo address property
> mmc: dw: Add fifo watermark alignment property
> mmc: dt-bindings: add ZTE ZX296718 MMC bindings
> mmc: zx: Initial support for ZX mmc controller
>
> .../devicetree/bindings/mmc/synopsys-dw-mshc.txt | 13 ++
> .../devicetree/bindings/mmc/zx-dw-mshc.txt | 33 +++
> drivers/mmc/host/Kconfig | 9 +
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/dw_mmc-zx.c | 242 +++++++++++++++++++++
> drivers/mmc/host/dw_mmc-zx.h | 31 +++
> drivers/mmc/host/dw_mmc.c | 17 +-
> include/linux/mmc/dw_mmc.h | 5 +
> 8 files changed, 348 insertions(+), 3 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt
> create mode 100644 drivers/mmc/host/dw_mmc-zx.c
> create mode 100644 drivers/mmc/host/dw_mmc-zx.h
>
Jaehoon,
Could you help add this patch set to your branch that for next merge
window? Thank you very much!
Jun
^ permalink raw reply
* Re: [PATCH v6 4/4] of/fdt: mark hotpluggable memory
From: Heinrich Schuchardt @ 2016-12-25 9:02 UTC (permalink / raw)
To: Reza Arbab
Cc: Balbir Singh, Aneesh Kumar K . V, H . Peter Anvin,
Alistair Popple, Benjamin Herrenschmidt, Bharata B Rao,
Frank Rowand, Ingo Molnar, Michael Ellerman, Nathan Fontenot,
Paul Mackerras, Rob Herring, Stewart Smith, Thomas Gleixner,
Andrew Morton, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg, Heinrich Schuchardt
In-Reply-To: <1478562276-25539-5-git-send-email-arbab-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
The patch adds a new property "linux,hotpluggable" to memory nodes of the
device tree.
memory@0 {
reg = <0x0 0x01000000 0x0 0x7f000000>;
linux,hotpluggable;
}
Memory areas marked by this property can later be disabled using the hotplugging
API. Especially for virtual machines this is a very useful capability.
Unfortunately the notation chosen does not fit well with the concept of
devicetree overlays which allow to change the devicetree during runtime.
I suggest to use the following notation
memory@0 {
compatible = "linux,hotpluggable-memory";
reg = <0x0 0x01000000 0x0 0x7f000000>;
status = "disabled";
}
This will allow us to write a device driver that can react to changes of the
devicetree made via devicetree overlays.
This driver could react to the change of the status between "okay" and
"disabled" and update the memory status accordingly.
Further we could use devicetree overlays to provide additional hotpluggable
memory.
The referenced patch has already been pulled for 4.10. But I hope it is not
too late for this design change.
Best regards
Heinrich Schuchardt
--
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 v3 3/3] nfc: trf7970a: Prevent repeated polling from crashing the kernel
From: Mark Greer @ 2016-12-24 17:24 UTC (permalink / raw)
To: Geoff Lansberry
Cc: linux-wireless, Lauro Ramos Venancio, Aloisio Almeida Jr,
Samuel Ortiz, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Justin Bronder, Jaret Cantu
In-Reply-To: <CAO7Z3W+n85jbr8cmj3HJV1c+eL=oRh-XRy+O=iZ+mD=ov2WABA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Sat, Dec 24, 2016 at 11:17:18AM -0500, Geoff Lansberry wrote:
> Mark - I'm sorry, but I did not write this code, and therefore was not
> able to accurately describe it. It is fixing a different issue, not
> the neard segfault that we are still chasing. Last week Jaret Cantu
> sent a separate email explaining the purpose of the code, which had
> you copied, did you see that?
Hm, no, I didn't. I received an email from Justin Bronder but not from
Jaret Cantu. Justin's email did help but is still pretty high-level.
We need a clear understanding as to what is happening in the digital
layer and the driver to know how execution is getting into a block of
error handling code that should never be executed. Once we understand
that we can start thinking about what the best fix is.
> Does it explain why it was done to
> your satisfaction? I've asked him to join in on the effort to push
> the change upstream, however he will not be available until the new
> year.
I expect that it would help if he joins. After the holidays is fine -
I think many people are taking it easy for the next week or so, anyway.
> I know you did suggest that we split off that change from the others,
> and if now is the time to do that, let me know. If you don't have
> the email from Jaret, also please let me know and I will forward it to
> you.
I think it would help you if you split it off because the first two patches
have a good chance of being accepted but this one doesn't (yet). If you
separate the them, it will make it easier for Samuel to take the first two
(or he may take the first two anyway but its always good to make it as
easy maintainers as you can).
Mark
--
--
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 v3 3/3] nfc: trf7970a: Prevent repeated polling from crashing the kernel
From: Geoff Lansberry @ 2016-12-24 16:17 UTC (permalink / raw)
To: Mark Greer
Cc: linux-wireless, Lauro Ramos Venancio, Aloisio Almeida Jr,
Samuel Ortiz, robh+dt, mark.rutland, netdev, devicetree,
linux-kernel, Justin Bronder, Jaret Cantu
In-Reply-To: <20161224060141.GA9069@animalcreek.com>
Mark - I'm sorry, but I did not write this code, and therefore was not
able to accurately describe it. It is fixing a different issue, not
the neard segfault that we are still chasing. Last week Jaret Cantu
sent a separate email explaining the purpose of the code, which had
you copied, did you see that? Does it explain why it was done to
your satisfaction? I've asked him to join in on the effort to push
the change upstream, however he will not be available until the new
year.
I know you did suggest that we split off that change from the others,
and if now is the time to do that, let me know. If you don't have
the email from Jaret, also please let me know and I will forward it to
you.
Geoff
Geoff Lansberry
Engineering Guy
Kuvée, Inc
125 Kingston St., 3rd Floor
Boston, MA 02111
1-617-290-1118 (m)
geoff.lansberry (skype)
http://www.kuvee.com
On Sat, Dec 24, 2016 at 1:01 AM, Mark Greer <mgreer@animalcreek.com> wrote:
> On Wed, Dec 21, 2016 at 11:18:34PM -0500, Geoff Lansberry wrote:
>> From: Jaret Cantu <jaret.cantu@timesys.com>
>>
>> Repeated polling attempts cause a NULL dereference error to occur.
>> This is because the state of the trf7970a is currently reading but
>> another request has been made to send a command before it has finished.
>>
>> The solution is to properly kill the waiting reading (workqueue)
>> before failing on the send.
>>
>> Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
>> ---
>
> You've still provided virtually no information on the actual problem(s)
> nor justified why you think this is the best solution. You're adding
> code to a section of code that should _never_ be executed so the only
> reasonable things I can infer is that there are, at least, two problems:
>
> 1) There is a bug causing execution to get into this block of code.
>
> 2) Once in this block of code, there is another bug.
>
> You seem to be attempting to fix 2) and completely ignoring 1).
> 1) is the first bug that needs to be root-caused and fixed.
>
> Also, what exactly is the "NULL dereference error" you mention?
> Is this the neard crash you talked about in another thread or is
> this a kernel crash? If it is the kernel crash, please post the
> relevant information. If this is the neard crash - which seems
> unlikely - then how can changing a section of kernel code that
> shouldn't be executed in the first place fix that?
>
> Mark
> --
^ permalink raw reply
* [PATCH] of: drop duplicate headers
From: Geliang Tang @ 2016-12-24 15:45 UTC (permalink / raw)
To: Pantelis Antoniou, Rob Herring, Frank Rowand
Cc: Geliang Tang, devicetree, linux-kernel
Drop duplicate headers string.h and of_platform.h.
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
drivers/of/overlay.c | 1 -
drivers/of/resolver.c | 1 -
drivers/of/unittest.c | 1 -
3 files changed, 3 deletions(-)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 0d4cda7..d4e337e 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -18,7 +18,6 @@
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/errno.h>
-#include <linux/string.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/idr.h>
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index 8bf12e9..7ae9863 100644
--- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c
@@ -18,7 +18,6 @@
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/errno.h>
-#include <linux/string.h>
#include <linux/slab.h>
/* illegal phandle value (set when unresolved) */
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 53c83d6..b4e8236 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -17,7 +17,6 @@
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
-#include <linux/of_platform.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
--
2.9.3
^ permalink raw reply related
* Re: [PATCH] ARM: dts: imx: remove obsoleted property fsl,spi-num-chipselects
From: Fabio Estevam @ 2016-12-24 12:47 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Shawn Guo, Fabio Estevam, Sascha Hauer, Alexander Shiyan,
Rob Herring,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20161224054354.28289-1-vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
On Sat, Dec 24, 2016 at 3:43 AM, Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org> wrote:
> Since commit b36581df7e78 ("spi: imx: Using existing properties for
> chipselects") the device tree property 'fsl,spi-num-chipselects' is
> unused and it is already marked as obsolete in device tree binding
> documentation. Remove the property from the existing DTS files to
> avoid its reoccurence on copying.
>
> Signed-off-by: Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
Reviewed-by: Fabio Estevam <fabio.estevam-3arQi8VN3Tc@public.gmane.org>
--
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] adc: add adc driver for Hisilicon BVT SOCs
From: Jonathan Cameron @ 2016-12-24 11:46 UTC (permalink / raw)
To: Allen Liu, jic23-DgEjT+Ai2ygdnm+yROfE0A, knaack.h-Mmb7MZpHnFY,
lars-Qo5EllUWu/uELgA04lAiVw, pmeerw-jW+XmwGofnusTnJN9+BGXg,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
Cc: akinobu.mita-Re5JQEeQqe8AvxtiuMwx3w,
ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w,
krzk-DgEjT+Ai2ygdnm+yROfE0A, vilhelm.gray-Re5JQEeQqe8AvxtiuMwx3w,
ksenija.stanojevic-Re5JQEeQqe8AvxtiuMwx3w,
zhiyong.tao-NuS5LvNUpcJWk0Htik3J/w,
daniel.baluta-ral2JQCrhuEAvxtiuMwx3w,
leonard.crestez-ral2JQCrhuEAvxtiuMwx3w,
ray.jui-dY08KVG/lbpWk0Htik3J/w,
raveendra.padasalagi-dY08KVG/lbpWk0Htik3J/w,
mranostay-Re5JQEeQqe8AvxtiuMwx3w,
amsfield22-Re5JQEeQqe8AvxtiuMwx3w,
linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
xuejiancheng-C8/M+/jPZTeaMJb+Lgu22Q,
kevin.lixu-C8/M+/jPZTeaMJb+Lgu22Q
In-Reply-To: <1482544497-136656-1-git-send-email-liurenzhong-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
On 24 December 2016 01:54:57 GMT+00:00, Allen Liu <liurenzhong-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org> wrote:
>Add ADC driver for the ADC controller found on HiSilicon BVT SOCs, like
>Hi3516CV300, etc.
>The ADC controller is primarily in charge of detecting voltage.
>
>Reviewed-by: Jiancheng Xue <xuejiancheng-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
>Signed-off-by: Allen Liu <liurenzhong-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
Reading on phone so may not be that thorough!
Looks pretty good. The device abstraction makes it slightly more complicated than it needs
to be. If you aren't going to follow up quickly with other device support please drop the
abstraction. It can be easily readded when needed.
Various little things inline.
Thanks
Jonathan
>---
> .../devicetree/bindings/iio/adc/hibvt-lsadc.txt | 26 ++
> drivers/iio/adc/Kconfig | 10 +
> drivers/iio/adc/Makefile | 1 +
>drivers/iio/adc/hibvt_lsadc.c | 344
>+++++++++++++++++++++
> 4 files changed, 381 insertions(+)
>create mode 100644
>Documentation/devicetree/bindings/iio/adc/hibvt-lsadc.txt
> create mode 100644 drivers/iio/adc/hibvt_lsadc.c
>
>diff --git a/Documentation/devicetree/bindings/iio/adc/hibvt-lsadc.txt
>b/Documentation/devicetree/bindings/iio/adc/hibvt-lsadc.txt
>new file mode 100644
>index 0000000..63de46e
>--- /dev/null
>+++ b/Documentation/devicetree/bindings/iio/adc/hibvt-lsadc.txt
>@@ -0,0 +1,26 @@
>+Hisilicon BVT Low Speed (LS) A/D Converter bindings
>+
>+Required properties:
>+- compatible: should be "hisilicon,<name>-lsadc"
>+ - "hisilicon,hibvt-lsadc": for hi3516cv300
>+
>+- reg: physical base address of the controller and length of memory
>mapped
>+ region.
>+- interrupts: The interrupt number to the cpu. The interrupt specifier
>format
>+ depends on the interrupt controller.
A cross reference to the interrupt bindings doc always good to add.
>+- #io-channel-cells: Should be 1, see ../iio-bindings.txt
>+
>+Optional properties:
>+- resets: Must contain an entry for each entry in reset-names if need
>support
>+ this option. See ../reset/reset.txt for details.
>+- reset-names: Must include the name "saradc-apb".
>+
>+Example:
>+ lsadc: hibvt-lsadc@120e0000 {
>+ compatible = "hisilicon,hibvt-lsadc";
>+ reg = <0x120e0000 0x1000>;
>+ interrupts = <19>;
>+ resets = <&crg 0x7c 3>;
>+ reset-names = "lsadc-crg";
Doesn't contain saradc-apb which docs say it must...
>+ status = "disabled";
Not documented...
>+ };
>diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
>index 99c0514..0443f51 100644
>--- a/drivers/iio/adc/Kconfig
>+++ b/drivers/iio/adc/Kconfig
>@@ -225,6 +225,16 @@ config HI8435
> This driver can also be built as a module. If so, the module will be
> called hi8435.
>
>+config HIBVT_LSADC
>+ tristate "HIBVT LSADC driver"
>+ depends on ARCH_HISI || COMPILE_TEST
>+ help
>+ Say yes here to build support for the LSADC found in SoCs from
>+ hisilicon BVT chip.
>+
>+ To compile this driver as a module, choose M here: the
>+ module will be called hibvt_lsadc.
>+
> config INA2XX_ADC
> tristate "Texas Instruments INA2xx Power Monitors IIO driver"
> depends on I2C && !SENSORS_INA2XX
>diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
>index 7a40c04..6554d92 100644
>--- a/drivers/iio/adc/Makefile
>+++ b/drivers/iio/adc/Makefile
>@@ -23,6 +23,7 @@ obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o
> obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
> obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
> obj-$(CONFIG_HI8435) += hi8435.o
>+obj-$(CONFIG_HIBVT_LSADC) += hibvt_lsadc.o
> obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
> obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
> obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
>diff --git a/drivers/iio/adc/hibvt_lsadc.c
>b/drivers/iio/adc/hibvt_lsadc.c
>new file mode 100644
>index 0000000..a20afe8
>--- /dev/null
>+++ b/drivers/iio/adc/hibvt_lsadc.c
>@@ -0,0 +1,344 @@
>+/*
>+ * Hisilicon BVT Low Speed (LS) A/D Converter
>+ * Copyright (C) 2016 HiSilicon Technologies Co., Ltd.
>+ *
>+ * This program is free software; you can redistribute it and/or
>modify
>+ * it under the terms of the GNU General Public License as published
>by
>+ * the Free Software Foundation; either version 2 of the License, or
>+ * (at your option) any later version.
>+ *
>+ * This program is distributed in the hope that it will be useful,
>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>+ * GNU General Public License for more details.
>+ */
>+
>+#include <linux/module.h>
>+#include <linux/platform_device.h>
>+#include <linux/interrupt.h>
>+#include <linux/io.h>
>+#include <linux/of.h>
>+#include <linux/of_device.h>
>+#include <linux/clk.h>
>+#include <linux/completion.h>
>+#include <linux/delay.h>
>+#include <linux/reset.h>
>+#include <linux/regulator/consumer.h>
>+#include <linux/iio/iio.h>
>+
>+/* hisilicon bvt adc registers definitions */
>+#define LSADC_CONFIG 0x00
>+#define CONFIG_DEGLITCH BIT(17)
Please add a driver specific prefix to all defines to keep them in their own namespace.
>+#define CONFIG_RESET BIT(15)
>+#define CONFIG_POWERDOWN BIT(14)
>+#define CONFIG_MODE BIT(13)
>+#define CONFIG_CHC_VALID BIT(10)
>+#define CONFIG_CHB_VALID BIT(9)
>+#define CONFIG_CHA_VALID BIT(8)
>+
>+#define LSADC_TIMESCAN 0x08
Lsadc is perhaps to generic a prefix. Clash chances are a bit high
>+#define LSADC_INTEN 0x10
>+#define LSADC_INTSTATUS 0x14
>+#define LSADC_INTCLR 0x18
>+#define LSADC_START 0x1C
>+#define LSADC_STOP 0x20
>+#define LSADC_ACTBIT 0x24
>+#define LSADC_CHNDATA 0x2C
>+
>+#define ADC_CON_EN (1u << 0)
>+#define ADC_CON_DEN (0u << 0)
>+
>+#define ADC_NUM_BITS 10
>+
>+/* fix clk:3000000, default tscan set 10ms */
>+#define DEF_ADC_TSCAN_MS (10*3000)
>+
>+#define LSADC_CHN_MASK 0x7
>+
>+#define LSADC_TIMEOUT msecs_to_jiffies(100)
>+
>+/* default voltage scale for every channel <mv> */
>+static int g_voltage[] = {
>+ 3300, 3300, 3300
>+};
Prefix these as well.
>+
>+struct hibvt_lsadc {
>+ void __iomem *regs;
>+ struct completion completion;
>+ struct reset_control *reset;
>+ const struct hibvt_lsadc_data *data;
>+ unsigned int cur_chn;
>+ unsigned int value;
>+};
>+
>+struct hibvt_lsadc_data {
>+ int num_bits;
>+ const struct iio_chan_spec *channels;
>+ int num_channels;
>+
>+ void (*clear_irq)(struct hibvt_lsadc *info, int mask);
>+ void (*start_conv)(struct hibvt_lsadc *info);
>+ void (*stop_conv)(struct hibvt_lsadc *info);
>+};
>+
>+static int hibvt_lsadc_read_raw(struct iio_dev *indio_dev,
>+ struct iio_chan_spec const *chan,
>+ int *val, int *val2, long mask)
>+{
>+ struct hibvt_lsadc *info = iio_priv(indio_dev);
>+
>+ switch (mask) {
>+ case IIO_CHAN_INFO_RAW:
>+ mutex_lock(&indio_dev->mlock);
>+
>+ reinit_completion(&info->completion);
>+
>+ /* Select the channel to be used */
>+ info->cur_chn = chan->channel;
>+
>+ if (info->data->start_conv)
>+ info->data->start_conv(info);
>+
>+ if (!wait_for_completion_timeout(&info->completion,
>+ LSADC_TIMEOUT)) {
>+ if (info->data->stop_conv)
>+ info->data->stop_conv(info);
>+ mutex_unlock(&indio_dev->mlock);
>+ return -ETIMEDOUT;
>+ }
>+
>+ *val = info->value;
>+ mutex_unlock(&indio_dev->mlock);
>+ return IIO_VAL_INT;
>+ case IIO_CHAN_INFO_SCALE:
>+ *val = g_voltage[chan->channel];
>+ *val2 = info->data->num_bits;
>+ return IIO_VAL_FRACTIONAL_LOG2;
>+ default:
>+ return -EINVAL;
>+ }
>+}
>+
>+static irqreturn_t hibvt_lsadc_isr(int irq, void *dev_id)
>+{
>+ struct hibvt_lsadc *info = (struct hibvt_lsadc *)dev_id;
>+ int mask;
>+
>+ mask = readl(info->regs + LSADC_INTSTATUS);
>+ mask &= LSADC_CHN_MASK;
>+
>+ /* Clear irq */
>+ if (info->data->clear_irq)
>+ info->data->clear_irq(info, mask);
>+
>+ /* Read value */
>+ info->value = readl(info->regs + LSADC_CHNDATA + (info->cur_chn <<
>2));
>+ info->value &= GENMASK(info->data->num_bits - 1, 0);
>+
>+ /* stop adc */
>+ if (info->data->stop_conv)
>+ info->data->stop_conv(info);
>+
>+ complete(&info->completion);
>+
>+ return IRQ_HANDLED;
>+}
>+
>+static const struct iio_info hibvt_lsadc_iio_info = {
>+ .read_raw = hibvt_lsadc_read_raw,
>+ .driver_module = THIS_MODULE,
>+};
>+
>+#define ADC_CHANNEL(_index, _id) { \
Prefix this define.
>+ .type = IIO_VOLTAGE, \
>+ .indexed = 1, \
>+ .channel = _index, \
>+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
>+ BIT(IIO_CHAN_INFO_SCALE), \
>+ .datasheet_name = _id, \
>+}
>+
>+static const struct iio_chan_spec hibvt_lsadc_iio_channels[] = {
>+ ADC_CHANNEL(0, "adc0"),
>+ ADC_CHANNEL(1, "adc1"),
>+ ADC_CHANNEL(2, "adc2"),
>+};
>+
>+static void hibvt_lsadc_clear_irq(struct hibvt_lsadc *info, int mask)
>+{
>+ writel(mask, info->regs + LSADC_INTCLR);
>+}
>+
>+static void hibvt_lsadc_start_conv(struct hibvt_lsadc *info)
>+{
>+ unsigned int con;
>+
>+ /* set number bit */
>+ con = GENMASK(info->data->num_bits - 1, 0);
>+ writel(con, (info->regs + LSADC_ACTBIT));
>+
>+ /* config */
>+ con = readl(info->regs + LSADC_CONFIG);
>+ con &= ~CONFIG_RESET;
>+ con |= (CONFIG_POWERDOWN | CONFIG_DEGLITCH | CONFIG_MODE);
>+ con &= ~(CONFIG_CHA_VALID | CONFIG_CHB_VALID | CONFIG_CHC_VALID);
>+ con |= (CONFIG_CHA_VALID << info->cur_chn);
>+ writel(con, (info->regs + LSADC_CONFIG));
>+
>+ /* set timescan */
>+ writel(DEF_ADC_TSCAN_MS, (info->regs + LSADC_TIMESCAN));
>+
>+ /* clear interrupt */
>+ writel(LSADC_CHN_MASK, info->regs + LSADC_INTCLR);
>+
>+ /* enable interrupt */
>+ writel(ADC_CON_EN, (info->regs + LSADC_INTEN));
>+
>+ /* start scan */
>+ writel(ADC_CON_EN, (info->regs + LSADC_START));
>+}
>+
>+static void hibvt_lsadc_stop_conv(struct hibvt_lsadc *info)
>+{
>+ /* reset the timescan */
>+ writel(ADC_CON_DEN, (info->regs + LSADC_TIMESCAN));
>+
>+ /* disable interrupt */
>+ writel(ADC_CON_DEN, (info->regs + LSADC_INTEN));
>+
>+ /* stop scan */
>+ writel(ADC_CON_EN, (info->regs + LSADC_STOP));
>+}
>+
>+static const struct hibvt_lsadc_data lsadc_data = {
>+ .num_bits = ADC_NUM_BITS,
>+ .channels = hibvt_lsadc_iio_channels,
>+ .num_channels = ARRAY_SIZE(hibvt_lsadc_iio_channels),
>+
>+ .clear_irq = hibvt_lsadc_clear_irq,
>+ .start_conv = hibvt_lsadc_start_conv,
>+ .stop_conv = hibvt_lsadc_stop_conv,
>+};
Usual convention is to only introduce a device type specific structure when more than one device is supported. If you are going to follow up
shortly with more device support then leave it but add a note to the patch description. If not please drop this abstraction.
>+
>+static const struct of_device_id hibvt_lsadc_match[] = {
>+ {
>+ .compatible = "hisilicon,hibvt-lsadc",
>+ .data = &lsadc_data,
>+ },
>+ {},
>+};
>+MODULE_DEVICE_TABLE(of, hibvt_lsadc_match);
>+
>+/**
>+ * Reset LSADC Controller.
Single line comment syntax please.
>+ */
>+static void hibvt_lsadc_reset_controller(struct reset_control *reset)
>+{
>+ reset_control_assert(reset);
>+ usleep_range(10, 20);
>+ reset_control_deassert(reset);
>+}
>+
>+static int hibvt_lsadc_probe(struct platform_device *pdev)
>+{
>+ struct hibvt_lsadc *info = NULL;
>+ struct device_node *np = pdev->dev.of_node;
>+ struct iio_dev *indio_dev = NULL;
>+ struct resource *mem;
>+ const struct of_device_id *match;
>+ int ret;
>+ int irq;
>+
>+ if (!np)
>+ return -ENODEV;
>+
>+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
>+ if (!indio_dev) {
>+ dev_err(&pdev->dev, "failed allocating iio device\n");
>+ return -ENOMEM;
>+ }
>+ info = iio_priv(indio_dev);
>+
>+ match = of_match_device(hibvt_lsadc_match, &pdev->dev);
>+ info->data = match->data;
>+
>+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>+ info->regs = devm_ioremap_resource(&pdev->dev, mem);
>+ if (IS_ERR(info->regs))
>+ return PTR_ERR(info->regs);
>+
>+ /*
>+ * The reset should be an optional property, as it should work
>+ * with old devicetrees as well
>+ */
>+ info->reset = devm_reset_control_get(&pdev->dev, "lsadc-crg");
>+ if (IS_ERR(info->reset)) {
>+ ret = PTR_ERR(info->reset);
>+ if (ret != -ENOENT)
>+ return ret;
>+
>+ dev_dbg(&pdev->dev, "no reset control found\n");
>+ info->reset = NULL;
>+ }
>+
>+ init_completion(&info->completion);
>+
>+ irq = platform_get_irq(pdev, 0);
>+ if (irq < 0) {
>+ dev_err(&pdev->dev, "no irq resource?\n");
>+ return irq;
>+ }
>+
>+ ret = devm_request_irq(&pdev->dev, irq, hibvt_lsadc_isr,
>+ 0, dev_name(&pdev->dev), info);
>+ if (ret < 0) {
>+ dev_err(&pdev->dev, "failed requesting irq %d\n", irq);
>+ return ret;
>+ }
>+
>+ if (info->reset)
>+ hibvt_lsadc_reset_controller(info->reset);
>+
>+ platform_set_drvdata(pdev, indio_dev);
>+
>+ indio_dev->name = dev_name(&pdev->dev);
>+ indio_dev->dev.parent = &pdev->dev;
>+ indio_dev->dev.of_node = pdev->dev.of_node;
>+ indio_dev->info = &hibvt_lsadc_iio_info;
>+ indio_dev->modes = INDIO_DIRECT_MODE;
>+
>+ indio_dev->channels = info->data->channels;
>+ indio_dev->num_channels = info->data->num_channels;
>+
>+ ret = iio_device_register(indio_dev);
>+ if (ret < 0) {
>+ dev_err(&pdev->dev, "failed register iio device\n");
>+ return ret;
>+ }
>+
>+ return 0;
>+}
>+
>+static int hibvt_lsadc_remove(struct platform_device *pdev)
>+{
>+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>+
>+ iio_device_unregister(indio_dev);
As nothing else here can use devm version of register and drop remove entirely.
>+
>+ return 0;
>+}
>+
>+static struct platform_driver hibvt_lsadc_driver = {
>+ .probe = hibvt_lsadc_probe,
>+ .remove = hibvt_lsadc_remove,
>+ .driver = {
>+ .name = "hibvt-lsadc",
>+ .of_match_table = hibvt_lsadc_match,
>+ },
>+};
>+
>+module_platform_driver(hibvt_lsadc_driver);
>+
>+MODULE_AUTHOR("Allen Liu <liurenzhong-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>");
>+MODULE_DESCRIPTION("hisilicon BVT LSADC driver");
>+MODULE_LICENSE("GPL v2");
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
^ permalink raw reply
* Re: [PATCH] iio: misc: add a generic regulator driver
From: Jonathan Cameron @ 2016-12-24 10:43 UTC (permalink / raw)
To: Geert Uytterhoeven, Lars-Peter Clausen
Cc: Bartosz Golaszewski, Jonathan Cameron, Hartmut Knaack,
Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
linux-iio-u79uwXL29TY76Z2rM5mHXA, linux-devicetree, LKML,
Kevin Hilman, Patrick Titiano, Neil Armstrong, Liam Girdwood,
Mark Brown, linus.walleij-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <CAMuHMdXnzDUYcr8qiUTwE2peBdjwuVWPRUkms2J8AHFaQ=SHHQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 23 December 2016 12:56:11 GMT+00:00, Geert Uytterhoeven <geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org> wrote:
>Hi Lars,
>
>On Fri, Dec 23, 2016 at 12:35 PM, Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
>wrote:
>> On 12/23/2016 11:00 AM, Geert Uytterhoeven wrote:
>>> On Mon, Dec 12, 2016 at 6:15 PM, Lars-Peter Clausen
><lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> wrote:
>>>> On 12/06/2016 12:12 PM, Bartosz Golaszewski wrote:
>>>>> We're already using libiio to read the measured data from the
>power
>>>>> monitor, that's why we'd like to use the iio framework for
>>>>> power-cycling the devices as well. My question is: would bridging
>the
>>>>> regulator framework be the right solution? Should we look for
>>>>> something else? Bridge the GPIO framework instead?
>>>>
>>>> I wouldn't necessaries create bridge, but instead just use the GPIO
>>>> framework directly.
>>>>
>>>> We now have the GPIO chardev interface which meant to be used to
>support
>>>> application specific logic that control the GPIOs, but where you
>don't want
>>>> to write a kernel driver.
>>>>
>>>> My idea was to add GPIOs and GPIO chips as high level object inside
>libiio
>>>> that can be accessed through the same context as the IIO devices.
>Similar to
>>>> the current IIO API you have a API for gpios that allows to
>enumerate the
>>>> GPIO devices and their pins as well as modify the pin state.
>>>
>>> That would mean libiio has access to all GPIOs, allowing a remote
>person
>>> to not only control through iiod the GPIOs for industrial control,
>but also the
>>> GPIOs not intended for export, right?
>>
>> Well, it is a policy question. Who gets access to what. Right now it
>is all
>> or nothing, a privileged application gets access to all
>devices/GPIOs, a
>> unprivileged application gets access to nothing. Same for GPIOs as
>well as
>> IIO devices.
>>
>> iiod at the moment does not have any access control at all, which in
>itself
>> is a problem. We need to add support for that at some point. I don't
>see an
>> issue with implementing a finer grained access scheme when we do so.
>E.g.
>> unprivileged applications only get access to certain pins.
>
>OK, so that's WIP.
>
>>> Having a separate GPIO switch driver avoids that, as DT (or some
>other means)
>>> can be used to specify and label the GPIOs for IIO use.
>>
>> Sure, functionally this would be equivalent, but we have to ask
>whether this
>> is the right way to use the DT. Is access policy specification part
>of the
>> hardware description? In my opinion the answer is no. At the hardware
>> description level there is no operating system, there is no userspace
>or
>> kernelspace, there is are no access levels. Putting the distinction
>between
>> a switch/regulator that can be controlled from userspace or can only
>be
>> controlled from kernel space into the DT would be a layering
>violation. It
>> is analogous to why we don't have spidev DT bindings. This is an
>issue that
>> needs to be solved at a higher level. In my opinion this level is a
>> cooperation between kernel- and userspace. Kernelspace offering an
>interface
>> to export a device for userspace access and userspace making use of
>that
>> interface to request access to a device. In a similar way to how vfio
>is
>> structured.
>
>I'm not advocating using DT for policy, only for hardware description.
>
>We have means (bindings) to describe GPIOs connected to LEDs and
>switches
>(incl. their labels), while you can control LEDs through plain GPIO
>sysfs
>export or chardev, too. It's just more error prone to use the latter.
>
>We do not have bindings to describe GPIOs connected to e.g. relays.
We should.
>
>Switching external devices (the internals of those devices not
>described
>itself in DT, like in an industrial context), sounds more like
>something to
>be handled by IIO, doesn't it?
Certainly, if there is known hardware to describe, we should endeavour to describe it.
Userspace interfaces are needed wherever we hit the boundary of what we can describe,
whether because we are measuring things not in our control (e.g. what key is pressed on a
keyboard) or because the next bit of hardware is interchangeable (e.g. your relay example, or
this power switch).
The challenge is to structure the device model for the interchangeable edge case to be the
same, more or less, as it would be if we knew what was hanging off the switch.
Hence, we either cut out early (gpio) or we attempt to put an appropriate consumer in place
for the gpio (or possibly the power switch if we describe that). No problem at all in doing that
last chunk with IIO or GPIO userspace as appropriate...
The challenge is that we are representing the fact the hardware is unknown in device tree.
Perhaps we need a way to make that explicit? Is there one already? Things like extcon do similar
things I guess.
Same is true for regulators, when they are at the edge of the device...
On the binary channel types in IIO we have discussed this a fair bit in the past. There
Is a non trivial amount of work needed to do triggered input (demuxing to multiple consumers
In particular).
Sysfs stuff would be simple but then it would really be gpio interface wrapped up a bit.
What IIO would bring to the mix ultimately is synchronized triggering of input and output.
(Speaking of which, Lars any progress on output buffers? Perhaps if we post that someone else might pick it up and run with it?)
One could argue the relay case is more of a mux than anything else so perhaps the ongoing
generic mux subsystem discussion would be a good place to talk about that?
Interesting discussion, sorry it took me until my Christmas train journey to join in).
Linus, if you get a chance, you have probably thought more about gpio IIO interactions than I have!
Jonathan
>
>Gr{oetje,eeting}s,
>
> Geert
>
>--
>Geert Uytterhoeven -- There's lots of Linux beyond ia32 --
>geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org
>
>In personal conversations with technical people, I call myself a
>hacker. But
>when I'm talking to journalists I just say "programmer" or something
>like that.
> -- Linus Torvalds
>--
>To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
--
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 v5 6/6] arm64: arch_timer: acpi: add hisi timer errata data
From: Kefeng Wang @ 2016-12-24 7:11 UTC (permalink / raw)
To: Ding Tianhong, catalin.marinas-5wv7dgnIgG8,
will.deacon-5wv7dgnIgG8, marc.zyngier-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, oss-fOR+EgIDQEHk1uMJSBkQmQ,
devicetree-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A, stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxarm-hv44wF8Li93QT0dZR+AlfA
Cc: Hanjun Guo
In-Reply-To: <1482476669-15596-7-git-send-email-dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
On 2016/12/23 15:04, Ding Tianhong wrote:
> From: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>
> Add hisi timer specific erratum fixes.
>
> v3: add hisilicon erratum 161601 for ACPI mode.
>
> v4: update some data structures.
>
> Signed-off-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Ding Tianhong <dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> ---
> drivers/clocksource/arm_arch_timer.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 212bfa5..7b15d2a 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -1089,10 +1089,28 @@ struct gtdt_arch_timer_fixup {
> void *context;
> };
>
> +#ifdef CONFIG_HISILICON_ERRATUM_161601
> +static void __init erratum_workaround_enable(void *context)
> +{
> + u64 erratum = (u64) context;
> +
> + if (erratum & HISILICON_161601) {
> + timer_unstable_counter_workaround = &arch_timer_hisi_161601;
> + static_branch_enable(&arch_timer_read_ool_enabled);
> + pr_info("Enabling workaround for HISILICON ERRATUM 161601\n");
> + }
Use arch_timer_hisi_161601 for context instead of HISILICON_161601 directly,
we can make erratum_workaround_enable more general.
> +}
> +#endif
> +
> /* note: this needs to be updated according to the doc of OEM ID
> * and TABLE ID for different board.
> */
> struct gtdt_arch_timer_fixup arch_timer_quirks[] __initdata = {
> +#ifdef CONFIG_HISILICON_ERRATUM_161601
> + {"HISI", "hip05", 0, &erratum_workaround_enable, (void *) HISILICON_161601},
> + {"HISI", "hip06", 0, &erratum_workaround_enable, (void *) HISILICON_161601},
> + {"HISI", "hip07", 0, &erratum_workaround_enable, (void *) HISILICON_161601},
> +#endif
> };
>
> void __init arch_timer_acpi_quirks_handler(char *oem_id,
>
--
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 v5 3/6] arm64: arch_timer: Work around Erratum Hisilicon-161601
From: Kefeng Wang @ 2016-12-24 6:07 UTC (permalink / raw)
To: Ding Tianhong, catalin.marinas-5wv7dgnIgG8,
will.deacon-5wv7dgnIgG8, marc.zyngier-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, oss-fOR+EgIDQEHk1uMJSBkQmQ,
devicetree-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A, stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxarm-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <1482476669-15596-4-git-send-email-dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
On 2016/12/23 15:04, Ding Tianhong wrote:
> Erratum Hisilicon-161601 says that the ARM generic timer counter "has the
> potential to contain an erroneous value when the timer value changes".
> Accesses to TVAL (both read and write) are also affected due to the implicit counter
> read. Accesses to CVAL are not affected.
>
> The workaround is to reread the system count registers until the value of the second
> read is larger than the first one by less than 32, the system counter can be guaranteed
> not to return wrong value twice by back-to-back read and the error value is always larger
> than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.
>
> The workaround is enabled if the hisilicon,erratum-161601 property is found in
> the timer node in the device tree. This can be overridden with the
> clocksource.arm_arch_timer.hisilicon-161601 boot parameter, which allows KVM
> users to enable the workaround until a mechanism is implemented to
> automatically communicate this information.
>
> Fix some description for fsl erratum a008585.
>
> v2: Significant rework based on feedback, including seperate the fsl erratum a008585
> to another patch, update the erratum name and remove unwanted code.
>
> v3: Significant rework based on feedback, including fix some alignment problem, make the
> #define __hisi_161601_read_reg to be private to the .c file instead of being globally
> visible, add more accurate annotation and modify a bit of logical format to enable
> arch_timer_read_ool_enabled, remove the kernel commandline parameter
> clocksource.arm_arch_timer.hisilicon-161601.
>
> v5: Theoretically the erratum should not occur more than twice in succession when reading
> the system counter, but it is possible that some interrupts may lead to more than twice
> read errors, triggering the warning, so setting the number of retries to 50 which is far
> beyond the number of iterations the loop has been observed to take.
>
> Signed-off-by: Ding Tianhong <dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> ---
> Documentation/arm64/silicon-errata.txt | 1 +
> arch/arm64/include/asm/arch_timer.h | 2 +-
> drivers/clocksource/Kconfig | 9 +++++
> drivers/clocksource/arm_arch_timer.c | 70 +++++++++++++++++++++++++++++++---
> 4 files changed, 76 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
> index 405da11..1c1a95f 100644
> --- a/Documentation/arm64/silicon-errata.txt
> +++ b/Documentation/arm64/silicon-errata.txt
> @@ -63,3 +63,4 @@ stable kernels.
> | Cavium | ThunderX SMMUv2 | #27704 | N/A |
> | | | | |
> | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
> +| Hisilicon | Hip0{5,6,7} | #161601 | HISILICON_ERRATUM_161601|
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index f882c7c..ebf4cde 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -29,7 +29,7 @@
>
> #include <clocksource/arm_arch_timer.h>
>
> -#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
> extern struct static_key_false arch_timer_read_ool_enabled;
> #define needs_unstable_timer_counter_workaround() \
> static_branch_unlikely(&arch_timer_read_ool_enabled)
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 4866f7a..162d820 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -335,6 +335,15 @@ config FSL_ERRATUM_A008585
> value"). The workaround will only be active if the
> fsl,erratum-a008585 property is found in the timer node.
>
> +config HISILICON_ERRATUM_161601
> + bool "Workaround for Hisilicon Erratum 161601"
> + default y
> + depends on ARM_ARCH_TIMER && ARM64
> + help
> + This option enables a workaround for Hisilicon Erratum
> + 161601. The workaround will be active if the hisilicon,erratum-161601
> + property is found in the timer node.
> +
> config ARM_GLOBAL_TIMER
> bool "Support for the ARM global timer" if COMPILE_TEST
> select CLKSRC_OF if OF
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index e7406ad..9a82496 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -95,15 +95,18 @@ static int __init early_evtstrm_cfg(char *buf)
> * Architected system timer support.
> */
>
> -#ifdef CONFIG_FSL_ERRATUM_A008585
> +#if CONFIG_FSL_ERRATUM_A008585 || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
> struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
> EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
>
> #define FSL_A008585 0x0001
> +#define HISILICON_161601 0x0002
It looks like the DEFINE is useless,
> +
> +static struct arch_timer_erratum_workaround arch_timer_hisi_161601 = {
> + .erratum = HISILICON_161601,
Just a errata description, eg.
.desc = "HISILICON ERRATUM 161601"
then....
> + .read_cntp_tval_el0 = hisi_161601_read_cntp_tval_el0,
> + .read_cntv_tval_el0 = hisi_161601_read_cntv_tval_el0,
> + .read_cntvct_el0 = hisi_161601_read_cntvct_el0,
> +};
> +#endif /* CONFIG_HISILICON_ERRATUM_161601 */
[..]
> -#ifdef CONFIG_FSL_ERRATUM_A008585
> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
> /*
> * Don't use the vdso fastpath if errata require using
> * the out-of-line counter accessor.
> @@ -909,10 +960,19 @@ static int __init arch_timer_of_init(struct device_node *np)
> #ifdef CONFIG_FSL_ERRATUM_A008585
> if (!timer_unstable_counter_workaround && of_property_read_bool(np, "fsl,erratum-a008585"))
> timer_unstable_counter_workaround = &arch_timer_fsl_a008585;
> +#endif
> +
> +#ifdef CONFIG_HISILICON_ERRATUM_161601
> + if (!timer_unstable_counter_workaround && of_property_read_bool(np, "hisilicon,erratum-161601"))
> + timer_unstable_counter_workaround = &arch_timer_hisi_161601;
> +#endif
>
> +#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
> if (timer_unstable_counter_workaround) {
> static_branch_enable(&arch_timer_read_ool_enabled);
> - pr_info("Enabling workaround for FSL erratum A-008585\n");
> + pr_info("Enabling workaround for %s\n",
> + timer_unstable_counter_workaround->erratum == FSL_A008585 ?
> + "FSL ERRATUM A-008585" : "HISILICON ERRATUM 161601");
......> pr_info("Enabling workaround for %s\n", timer_unstable_counter_workaround->desc)
> }
> #endif
>
>
--
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