Import first batch of sunxi64 patches
This commit is contained in:
parent
d8332dbe22
commit
dd47a94472
@ -2442,6 +2442,7 @@ CONFIG_THERMAL_EMULATION=y
|
||||
#
|
||||
# ACPI INT340X thermal drivers
|
||||
#
|
||||
CONFIG_SUN8I_THS=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
# CONFIG_WATCHDOG_NOWAYOUT is not set
|
||||
@ -2623,6 +2624,7 @@ CONFIG_REGULATOR_QCOM_SPMI=y
|
||||
# CONFIG_REGULATOR_S2MPA01 is not set
|
||||
CONFIG_REGULATOR_S2MPS11=y
|
||||
# CONFIG_REGULATOR_S5M8767 is not set
|
||||
CONFIG_REGULATOR_SY8106A=y
|
||||
# CONFIG_REGULATOR_TPS51632 is not set
|
||||
# CONFIG_REGULATOR_TPS62360 is not set
|
||||
# CONFIG_REGULATOR_TPS65023 is not set
|
||||
@ -3608,13 +3610,7 @@ CONFIG_SUNXI_CCU_NKMP=y
|
||||
CONFIG_SUNXI_CCU_NM=y
|
||||
CONFIG_SUNXI_CCU_MP=y
|
||||
CONFIG_SUN50I_A64_CCU=y
|
||||
# CONFIG_SUN5I_CCU is not set
|
||||
# CONFIG_SUN6I_A31_CCU is not set
|
||||
# CONFIG_SUN8I_A23_CCU is not set
|
||||
# CONFIG_SUN8I_A33_CCU is not set
|
||||
CONFIG_SUN8I_H3_CCU=y
|
||||
# CONFIG_SUN8I_V3S_CCU is not set
|
||||
# CONFIG_SUN9I_A80_CCU is not set
|
||||
CONFIG_SUN8I_R_CCU=y
|
||||
|
||||
#
|
||||
|
||||
340
patch/kernel/sun50i-dev/add-h3-h5-THS.patch
Normal file
340
patch/kernel/sun50i-dev/add-h3-h5-THS.patch
Normal file
@ -0,0 +1,340 @@
|
||||
From d622c59b1a71f9e5e20663fae693b268fcb2d39b Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 25 Jun 2016 21:51:05 +0200
|
||||
Subject: [PATCH] thermal: sun8i_ths: Add support for the thermal sensor on
|
||||
Allwinner H3
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch adds support for the sun8i thermal sensor on
|
||||
Allwinner H3 SoC.
|
||||
|
||||
Signed-off-by: Ondřej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/thermal/Kconfig | 7 ++
|
||||
drivers/thermal/Makefile | 1 +
|
||||
drivers/thermal/sun8i_ths.c | 239 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 247 insertions(+)
|
||||
create mode 100644 drivers/thermal/sun8i_ths.c
|
||||
|
||||
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
|
||||
index 776b3439..d46d97b 100644
|
||||
--- a/drivers/thermal/Kconfig
|
||||
+++ b/drivers/thermal/Kconfig
|
||||
@@ -392,6 +392,13 @@ config MTK_THERMAL
|
||||
Enable this option if you want to have support for thermal management
|
||||
controller present in Mediatek SoCs
|
||||
|
||||
+config SUN8I_THS
|
||||
+ tristate "Thermal sensor driver for Allwinner H3"
|
||||
+ depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI)
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ Enable this to support thermal reporting on some newer Allwinner SoCs.
|
||||
+
|
||||
menu "Texas Instruments thermal drivers"
|
||||
depends on ARCH_HAS_BANDGAP || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
|
||||
index 7adae20..2480dc5 100644
|
||||
--- a/drivers/thermal/Makefile
|
||||
+++ b/drivers/thermal/Makefile
|
||||
@@ -58,3 +58,4 @@ obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
|
||||
obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
|
||||
obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
|
||||
obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
|
||||
+obj-$(CONFIG_SUN8I_THS) += sun8i_ths.o
|
||||
diff --git a/drivers/thermal/sun8i_ths.c b/drivers/thermal/sun8i_ths.c
|
||||
new file mode 100644
|
||||
index 0000000..cfe7d10
|
||||
--- /dev/null
|
||||
+++ b/drivers/thermal/sun8i_ths.c
|
||||
@@ -0,0 +1,239 @@
|
||||
+/*
|
||||
+ * Thermal sensor driver for Allwinner H3 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Ondřej Jirman
|
||||
+ * Based on the work of Josef Gajdusek <atx@atx.name>
|
||||
+ *
|
||||
+ * This software is licensed under the terms of the GNU General Public
|
||||
+ * License version 2, as published by the Free Software Foundation, and
|
||||
+ * may be copied, distributed, and modified under those terms.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/thermal.h>
|
||||
+#include <linux/printk.h>
|
||||
+
|
||||
+#define THS_H3_CTRL0 0x00
|
||||
+#define THS_H3_CTRL2 0x40
|
||||
+#define THS_H3_INT_CTRL 0x44
|
||||
+#define THS_H3_STAT 0x48
|
||||
+#define THS_H3_FILTER 0x70
|
||||
+#define THS_H3_CDATA 0x74
|
||||
+#define THS_H3_DATA 0x80
|
||||
+
|
||||
+#define THS_H3_CTRL0_SENSOR_ACQ0(x) (x)
|
||||
+#define THS_H3_CTRL2_SENSE_EN BIT(0)
|
||||
+#define THS_H3_CTRL2_SENSOR_ACQ1(x) ((x) << 16)
|
||||
+#define THS_H3_INT_CTRL_DATA_IRQ_EN BIT(8)
|
||||
+#define THS_H3_INT_CTRL_THERMAL_PER(x) ((x) << 12)
|
||||
+#define THS_H3_STAT_DATA_IRQ_STS BIT(8)
|
||||
+#define THS_H3_FILTER_TYPE(x) ((x) << 0)
|
||||
+#define THS_H3_FILTER_EN BIT(2)
|
||||
+
|
||||
+#define THS_H3_CLK_IN 40000000 /* Hz */
|
||||
+#define THS_H3_DATA_PERIOD 330 /* ms */
|
||||
+
|
||||
+#define THS_H3_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */
|
||||
+#define THS_H3_FILTER_DIV (1 << (THS_H3_FILTER_TYPE_VALUE + 1))
|
||||
+#define THS_H3_INT_CTRL_THERMAL_PER_VALUE \
|
||||
+ (THS_H3_DATA_PERIOD * (THS_H3_CLK_IN / 1000) / THS_H3_FILTER_DIV / 4096 - 1)
|
||||
+#define THS_H3_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */
|
||||
+#define THS_H3_CTRL2_SENSOR_ACQ1_VALUE 0x3f
|
||||
+
|
||||
+struct sun8i_ths_data {
|
||||
+ struct reset_control *reset;
|
||||
+ struct clk *clk;
|
||||
+ struct clk *busclk;
|
||||
+ void __iomem *regs;
|
||||
+ struct thermal_zone_device *tzd;
|
||||
+ u32 temp;
|
||||
+};
|
||||
+
|
||||
+static int sun8i_ths_get_temp(void *_data, int *out)
|
||||
+{
|
||||
+ struct sun8i_ths_data *data = _data;
|
||||
+
|
||||
+ if (data->temp == 0)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ /* Formula and parameters from the Allwinner 3.4 kernel */
|
||||
+ *out = 217000 - (int)((data->temp * 1000000) / 8253);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t sun8i_ths_irq_thread(int irq, void *_data)
|
||||
+{
|
||||
+ struct sun8i_ths_data *data = _data;
|
||||
+
|
||||
+ writel(THS_H3_STAT_DATA_IRQ_STS, data->regs + THS_H3_STAT);
|
||||
+
|
||||
+ data->temp = readl(data->regs + THS_H3_DATA);
|
||||
+ if (data->temp)
|
||||
+ thermal_zone_device_update(data->tzd, THERMAL_EVENT_TEMP_SAMPLE);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void sun8i_ths_h3_init(struct sun8i_ths_data *data)
|
||||
+{
|
||||
+ writel(THS_H3_CTRL0_SENSOR_ACQ0(THS_H3_CTRL0_SENSOR_ACQ0_VALUE),
|
||||
+ data->regs + THS_H3_CTRL0);
|
||||
+ writel(THS_H3_FILTER_EN | THS_H3_FILTER_TYPE(THS_H3_FILTER_TYPE_VALUE),
|
||||
+ data->regs + THS_H3_FILTER);
|
||||
+ writel(THS_H3_CTRL2_SENSOR_ACQ1(THS_H3_CTRL2_SENSOR_ACQ1_VALUE) |
|
||||
+ THS_H3_CTRL2_SENSE_EN,
|
||||
+ data->regs + THS_H3_CTRL2);
|
||||
+ writel(THS_H3_INT_CTRL_THERMAL_PER(THS_H3_INT_CTRL_THERMAL_PER_VALUE) |
|
||||
+ THS_H3_INT_CTRL_DATA_IRQ_EN,
|
||||
+ data->regs + THS_H3_INT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = {
|
||||
+ .get_temp = sun8i_ths_get_temp,
|
||||
+};
|
||||
+
|
||||
+static int sun8i_ths_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sun8i_ths_data *data;
|
||||
+ struct resource *res;
|
||||
+ int ret;
|
||||
+ int irq;
|
||||
+
|
||||
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "no memory resources defined\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ data->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(data->regs)) {
|
||||
+ ret = PTR_ERR(data->regs);
|
||||
+ dev_err(&pdev->dev, "failed to ioremap THS registers: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq);
|
||||
+ return irq;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||
+ sun8i_ths_irq_thread, IRQF_ONESHOT,
|
||||
+ dev_name(&pdev->dev), data);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ data->busclk = devm_clk_get(&pdev->dev, "ahb");
|
||||
+ if (IS_ERR(data->busclk)) {
|
||||
+ ret = PTR_ERR(data->busclk);
|
||||
+ dev_err(&pdev->dev, "failed to get ahb clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ data->clk = devm_clk_get(&pdev->dev, "ths");
|
||||
+ if (IS_ERR(data->clk)) {
|
||||
+ ret = PTR_ERR(data->clk);
|
||||
+ dev_err(&pdev->dev, "failed to get ths clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ data->reset = devm_reset_control_get(&pdev->dev, "ahb");
|
||||
+ if (IS_ERR(data->reset)) {
|
||||
+ ret = PTR_ERR(data->reset);
|
||||
+ dev_err(&pdev->dev, "failed to get reset: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_deassert(data->reset);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "reset deassert failed: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(data->busclk);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to enable bus clk: %d\n", ret);
|
||||
+ goto err_assert_reset;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(data->clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to enable ths clk: %d\n", ret);
|
||||
+ goto err_disable_bus;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_set_rate(data->clk, THS_H3_CLK_IN);
|
||||
+ if (ret)
|
||||
+ goto err_disable_ths;
|
||||
+
|
||||
+ data->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, data,
|
||||
+ &sun8i_ths_thermal_ops);
|
||||
+ if (IS_ERR(data->tzd)) {
|
||||
+ ret = PTR_ERR(data->tzd);
|
||||
+ dev_err(&pdev->dev, "failed to register thermal zone: %d\n",
|
||||
+ ret);
|
||||
+ goto err_disable_ths;
|
||||
+ }
|
||||
+
|
||||
+ sun8i_ths_h3_init(data);
|
||||
+
|
||||
+ platform_set_drvdata(pdev, data);
|
||||
+ return 0;
|
||||
+
|
||||
+err_disable_ths:
|
||||
+ clk_disable_unprepare(data->clk);
|
||||
+err_disable_bus:
|
||||
+ clk_disable_unprepare(data->busclk);
|
||||
+err_assert_reset:
|
||||
+ reset_control_assert(data->reset);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int sun8i_ths_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sun8i_ths_data *data = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ reset_control_assert(data->reset);
|
||||
+ clk_disable_unprepare(data->clk);
|
||||
+ clk_disable_unprepare(data->busclk);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id sun8i_ths_id_table[] = {
|
||||
+ { .compatible = "allwinner,sun8i-h3-ths", },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sun8i_ths_id_table);
|
||||
+
|
||||
+static struct platform_driver sun8i_ths_driver = {
|
||||
+ .probe = sun8i_ths_probe,
|
||||
+ .remove = sun8i_ths_remove,
|
||||
+ .driver = {
|
||||
+ .name = "sun8i_ths",
|
||||
+ .of_match_table = sun8i_ths_id_table,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(sun8i_ths_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Ondřej Jirman <megous@megous.com>");
|
||||
+MODULE_DESCRIPTION("Thermal sensor driver for Allwinner H3 SoC");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
From 71010833320fd2ffded4e7d6ee5e49902f6827c7 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 25 Jun 2016 00:02:04 +0200
|
||||
Subject: [PATCH] dt-bindings: document sun8i_ths - H3 thermal sensor driver
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch adds the binding documentation for the
|
||||
sun8i_ths driver. This is a driver for thermal sensor
|
||||
found in Allwinner H3 SoC.
|
||||
|
||||
Signed-off-by: Ondřej Jirman <megous@megous.com>
|
||||
---
|
||||
.../devicetree/bindings/thermal/sun8i-ths.txt | 24 ++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/thermal/sun8i-ths.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/thermal/sun8i-ths.txt b/Documentation/devicetree/bindings/thermal/sun8i-ths.txt
|
||||
new file mode 100644
|
||||
index 0000000..ba12881
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/thermal/sun8i-ths.txt
|
||||
@@ -0,0 +1,24 @@
|
||||
+* Thermal sensor driver for Allwinner H3 SoC
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible : "allwinner,sun8i-h3-ths"
|
||||
+- reg : Address range of the thermal sensor registers
|
||||
+- resets : Must contain phandles to reset controls matching the entries
|
||||
+ of the names
|
||||
+- reset-names : Must include the name "ahb"
|
||||
+- clocks : Must contain phandles to clock controls matching the entries
|
||||
+ of the names
|
||||
+- clock-names : Must contain "ahb" for the bus gate and "ths" for the THS
|
||||
+ clock
|
||||
+
|
||||
+Example:
|
||||
+ths: ths@01c25000 {
|
||||
+ #thermal-sensor-cells = <0>;
|
||||
+ compatible = "allwinner,sun8i-h3-ths";
|
||||
+ reg = <0x01c25000 0x400>;
|
||||
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ resets = <&bus_rst 136>;
|
||||
+ reset-names = "ahb";
|
||||
+ clocks = <&bus_gates 72>, <&ths_clk>;
|
||||
+ clock-names = "ahb", "ths";
|
||||
+};
|
||||
@ -97,7 +97,17 @@ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
|
||||
index 0a07f901..5ccd3490 100644
|
||||
--- a/scripts/Makefile.lib
|
||||
+++ b/scripts/Makefile.lib
|
||||
@@ -312,6 +312,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
|
||||
@@ -278,6 +278,9 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
|
||||
# ---------------------------------------------------------------------------
|
||||
DTC ?= $(objtree)/scripts/dtc/dtc
|
||||
|
||||
+# Overlay support
|
||||
+DTC_FLAGS += -@ -Wno-unit_address_format
|
||||
+
|
||||
# Disable noisy checks by default
|
||||
ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),)
|
||||
DTC_FLAGS += -Wno-unit_address_vs_reg
|
||||
@@ -312,6 +315,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
|
||||
$(obj)/%.dtb: $(src)/%.dts FORCE
|
||||
$(call if_changed_dep,dtc)
|
||||
|
||||
|
||||
271
patch/kernel/sun50i-dev/add-sy8106a-driver.patch
Normal file
271
patch/kernel/sun50i-dev/add-sy8106a-driver.patch
Normal file
@ -0,0 +1,271 @@
|
||||
From 5bcc6066f1dfbbef937ca8584a0fba44bb1468f0 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 25 Jun 2016 02:13:50 +0200
|
||||
Subject: [PATCH] regulator: SY8106A regulator driver
|
||||
|
||||
SY8106A is I2C attached single output voltage regulator
|
||||
made by Silergy.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/regulator/Kconfig | 8 +-
|
||||
drivers/regulator/Makefile | 2 +-
|
||||
drivers/regulator/sy8106a-regulator.c | 167 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 175 insertions(+), 2 deletions(-)
|
||||
create mode 100644 drivers/regulator/sy8106a-regulator.c
|
||||
|
||||
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
|
||||
index be06eb2..9c4b51e 100644
|
||||
--- a/drivers/regulator/Kconfig
|
||||
+++ b/drivers/regulator/Kconfig
|
||||
@@ -727,6 +727,13 @@ config REGULATOR_STW481X_VMMC
|
||||
This driver supports the internal VMMC regulator in the STw481x
|
||||
PMIC chips.
|
||||
|
||||
+config REGULATOR_SY8106A
|
||||
+ tristate "Silergy SY8106A"
|
||||
+ depends on I2C && (OF || COMPILE_TEST)
|
||||
+ select REGMAP_I2C
|
||||
+ help
|
||||
+ This driver provides support for SY8106A voltage regulator.
|
||||
+
|
||||
config REGULATOR_TPS51632
|
||||
tristate "TI TPS51632 Power Regulator"
|
||||
depends on I2C
|
||||
@@ -886,4 +893,3 @@ config REGULATOR_WM8994
|
||||
WM8994 CODEC.
|
||||
|
||||
endif
|
||||
-
|
||||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
|
||||
index ef7725e..a829718 100644
|
||||
--- a/drivers/regulator/Makefile
|
||||
+++ b/drivers/regulator/Makefile
|
||||
@@ -91,6 +91,7 @@ obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
|
||||
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
|
||||
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
|
||||
+obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
|
||||
@@ -114,5 +115,4 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
|
||||
|
||||
-
|
||||
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
|
||||
diff --git a/drivers/regulator/sy8106a-regulator.c b/drivers/regulator/sy8106a-regulator.c
|
||||
new file mode 100644
|
||||
index 0000000..7274965
|
||||
--- /dev/null
|
||||
+++ b/drivers/regulator/sy8106a-regulator.c
|
||||
@@ -0,0 +1,167 @@
|
||||
+/*
|
||||
+ * sy8106a-regulator.c - Regulator device driver for SY8106A
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Ondřej Jirman <megous@megous.com>
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Library General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library 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
|
||||
+ * Library General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Library General Public
|
||||
+ * License along with this library; if not, write to the
|
||||
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
+ * Boston, MA 02110-1301, USA.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/regulator/driver.h>
|
||||
+#include <linux/regulator/of_regulator.h>
|
||||
+
|
||||
+#define SY8106A_REG_VOUT1_SEL 0x01
|
||||
+#define SY8106A_REG_VOUT_COM 0x02
|
||||
+#define SY8106A_REG_VOUT1_SEL_MASK 0x7f
|
||||
+#define SY8106A_DISABLE_REG BIT(0)
|
||||
+#define SY8106A_GO_BIT BIT(7)
|
||||
+
|
||||
+struct sy8106a {
|
||||
+ struct regulator_dev *rdev;
|
||||
+ struct regmap *regmap;
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_config sy8106a_regmap_config = {
|
||||
+ .reg_bits = 8,
|
||||
+ .val_bits = 8,
|
||||
+};
|
||||
+
|
||||
+static int sy8106a_set_voltage_sel(struct regulator_dev *rdev, unsigned sel)
|
||||
+{
|
||||
+ /* We use our set_voltage_sel in order to avoid unnecessary I2C chatter,
|
||||
+ * because the regulator_get_voltage_sel_regmap using apply_bit
|
||||
+ * would perform 4 unnecessary transfers instead of one, increasing the
|
||||
+ * chance of error.
|
||||
+ */
|
||||
+ return regmap_write(rdev->regmap, rdev->desc->vsel_reg,
|
||||
+ sel | SY8106A_GO_BIT);
|
||||
+}
|
||||
+
|
||||
+static const struct regulator_ops sy8106a_ops = {
|
||||
+ .is_enabled = regulator_is_enabled_regmap,
|
||||
+ .set_voltage_sel = sy8106a_set_voltage_sel,
|
||||
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
+ .list_voltage = regulator_list_voltage_linear,
|
||||
+};
|
||||
+
|
||||
+/* Default limits measured in millivolts and milliamps */
|
||||
+#define SY8106A_MIN_MV 680
|
||||
+#define SY8106A_MAX_MV 1950
|
||||
+#define SY8106A_STEP_MV 10
|
||||
+
|
||||
+static const struct regulator_desc sy8106a_reg = {
|
||||
+ .name = "SY8106A",
|
||||
+ .id = 0,
|
||||
+ .ops = &sy8106a_ops,
|
||||
+ .type = REGULATOR_VOLTAGE,
|
||||
+ .n_voltages = ((SY8106A_MAX_MV - SY8106A_MIN_MV) / SY8106A_STEP_MV) + 1,
|
||||
+ .min_uV = (SY8106A_MIN_MV * 1000),
|
||||
+ .uV_step = (SY8106A_STEP_MV * 1000),
|
||||
+ .vsel_reg = SY8106A_REG_VOUT1_SEL,
|
||||
+ .vsel_mask = SY8106A_REG_VOUT1_SEL_MASK,
|
||||
+ .enable_reg = SY8106A_REG_VOUT_COM,
|
||||
+ .enable_mask = SY8106A_DISABLE_REG,
|
||||
+ .disable_val = SY8106A_DISABLE_REG,
|
||||
+ .enable_is_inverted = 1,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * I2C driver interface functions
|
||||
+ */
|
||||
+static int sy8106a_i2c_probe(struct i2c_client *i2c,
|
||||
+ const struct i2c_device_id *id)
|
||||
+{
|
||||
+ struct sy8106a *chip;
|
||||
+ struct device *dev = &i2c->dev;
|
||||
+ struct regulator_dev *rdev = NULL;
|
||||
+ struct regulator_config config = { };
|
||||
+ unsigned int selector;
|
||||
+ int error;
|
||||
+
|
||||
+ chip = devm_kzalloc(&i2c->dev, sizeof(struct sy8106a), GFP_KERNEL);
|
||||
+ if (!chip)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ chip->regmap = devm_regmap_init_i2c(i2c, &sy8106a_regmap_config);
|
||||
+ if (IS_ERR(chip->regmap)) {
|
||||
+ error = PTR_ERR(chip->regmap);
|
||||
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
|
||||
+ error);
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ config.dev = &i2c->dev;
|
||||
+ config.regmap = chip->regmap;
|
||||
+ config.driver_data = chip;
|
||||
+
|
||||
+ config.of_node = dev->of_node;
|
||||
+ config.init_data = of_get_regulator_init_data(dev, dev->of_node, &sy8106a_reg);
|
||||
+ if (!config.init_data) {
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ /* Probe regulator */
|
||||
+ error = regmap_read(chip->regmap, SY8106A_REG_VOUT1_SEL, &selector);
|
||||
+ if (error) {
|
||||
+ dev_err(&i2c->dev, "Failed to read voltage at probe time: %d\n", error);
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ rdev = devm_regulator_register(&i2c->dev, &sy8106a_reg, &config);
|
||||
+ if (IS_ERR(rdev)) {
|
||||
+ error = PTR_ERR(rdev);
|
||||
+ dev_err(&i2c->dev, "Failed to register SY8106A regulator: %d\n", error);
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ chip->rdev = rdev;
|
||||
+
|
||||
+ i2c_set_clientdata(i2c, chip);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id sy8106a_i2c_of_match[] = {
|
||||
+ { .compatible = "silergy,sy8106a" },
|
||||
+ { },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sy8106a_i2c_of_match);
|
||||
+
|
||||
+static const struct i2c_device_id sy8106a_i2c_id[] = {
|
||||
+ { "sy8106a", 0 },
|
||||
+ { },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(i2c, sy8106a_i2c_id);
|
||||
+
|
||||
+static struct i2c_driver sy8106a_regulator_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "sy8106a",
|
||||
+ .of_match_table = of_match_ptr(sy8106a_i2c_of_match),
|
||||
+ },
|
||||
+ .probe = sy8106a_i2c_probe,
|
||||
+ .id_table = sy8106a_i2c_id,
|
||||
+};
|
||||
+
|
||||
+module_i2c_driver(sy8106a_regulator_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Ondřej Jirman <megous@megous.com>");
|
||||
+MODULE_DESCRIPTION("Regulator device driver for Silergy SY8106A");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
From cbbe21d790a5a47e69238ed64d53acd36752d7ae Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 25 Jun 2016 02:20:08 +0200
|
||||
Subject: [PATCH] dt-bindings: document SY8106A regulator driver
|
||||
|
||||
This patch adds the binding documentation for the
|
||||
sy8106a regulator driver.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
.../bindings/regulator/sy8106a-regulator.txt | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/regulator/sy8106a-regulator.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/regulator/sy8106a-regulator.txt b/Documentation/devicetree/bindings/regulator/sy8106a-regulator.txt
|
||||
new file mode 100644
|
||||
index 0000000..1e623a34
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/regulator/sy8106a-regulator.txt
|
||||
@@ -0,0 +1,21 @@
|
||||
+SY8106A Voltage regulator
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: Must be "silergy,sy8106a"
|
||||
+- reg: I2C slave address - must be <0x65>
|
||||
+
|
||||
+Any property defined as part of the core regulator binding, defined in
|
||||
+regulator.txt, can also be used.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ sy8106a {
|
||||
+ compatible = "silergy,sy8106a";
|
||||
+ reg = <0x65>;
|
||||
+ regulator-name = "sy8106a-vdd";
|
||||
+ regulator-min-microvolt = <1000000>;
|
||||
+ regulator-max-microvolt = <1400000>;
|
||||
+ regulator-ramp-delay = <200>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
346
patch/kernel/sun50i-dev/clk-ng-fixes.patch
Normal file
346
patch/kernel/sun50i-dev/clk-ng-fixes.patch
Normal file
@ -0,0 +1,346 @@
|
||||
From 8ef4d5e976df3c15453b827e5fdcb4c3fb3598dd Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@csie.org>
|
||||
Date: Fri, 24 Mar 2017 16:33:05 +0800
|
||||
Subject: [PATCH] clk: sunxi-ng: use 1 as fallback for minimum multiplier
|
||||
|
||||
A zero multiplier does not make sense for clocks.
|
||||
|
||||
Use 1 as the minimum when a multiplier minimum isn't specified.
|
||||
|
||||
Fixes: 2beaa601c849 ("clk: sunxi-ng: Implement minimum for multipliers")
|
||||
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu_nk.c | 8 ++++----
|
||||
drivers/clk/sunxi-ng/ccu_nkm.c | 8 ++++----
|
||||
drivers/clk/sunxi-ng/ccu_nkmp.c | 4 ++--
|
||||
drivers/clk/sunxi-ng/ccu_nm.c | 2 +-
|
||||
4 files changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c
|
||||
index b9e9b8a..2485bda 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nk.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nk.c
|
||||
@@ -102,9 +102,9 @@ static long ccu_nk_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate *= nk->fixed_post_div;
|
||||
|
||||
- _nk.min_n = nk->n.min;
|
||||
+ _nk.min_n = nk->n.min ?: 1;
|
||||
_nk.max_n = nk->n.max ?: 1 << nk->n.width;
|
||||
- _nk.min_k = nk->k.min;
|
||||
+ _nk.min_k = nk->k.min ?: 1;
|
||||
_nk.max_k = nk->k.max ?: 1 << nk->k.width;
|
||||
|
||||
ccu_nk_find_best(*parent_rate, rate, &_nk);
|
||||
@@ -127,9 +127,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate = rate * nk->fixed_post_div;
|
||||
|
||||
- _nk.min_n = nk->n.min;
|
||||
+ _nk.min_n = nk->n.min ?: 1;
|
||||
_nk.max_n = nk->n.max ?: 1 << nk->n.width;
|
||||
- _nk.min_k = nk->k.min;
|
||||
+ _nk.min_k = nk->k.min ?: 1;
|
||||
_nk.max_k = nk->k.max ?: 1 << nk->k.width;
|
||||
|
||||
ccu_nk_find_best(parent_rate, rate, &_nk);
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
|
||||
index 71f81e9..cba84af 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
|
||||
@@ -109,9 +109,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
|
||||
struct ccu_nkm *nkm = data;
|
||||
struct _ccu_nkm _nkm;
|
||||
|
||||
- _nkm.min_n = nkm->n.min;
|
||||
+ _nkm.min_n = nkm->n.min ?: 1;
|
||||
_nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
|
||||
- _nkm.min_k = nkm->k.min;
|
||||
+ _nkm.min_k = nkm->k.min ?: 1;
|
||||
_nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
|
||||
_nkm.min_m = 1;
|
||||
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
|
||||
@@ -138,9 +138,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
- _nkm.min_n = nkm->n.min;
|
||||
+ _nkm.min_n = nkm->n.min ?: 1;
|
||||
_nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
|
||||
- _nkm.min_k = nkm->k.min;
|
||||
+ _nkm.min_k = nkm->k.min ?: 1;
|
||||
_nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
|
||||
_nkm.min_m = 1;
|
||||
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
index 488055e..162ff26 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
@@ -116,9 +116,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
|
||||
struct _ccu_nkmp _nkmp;
|
||||
|
||||
- _nkmp.min_n = nkmp->n.min;
|
||||
+ _nkmp.min_n = nkmp->n.min ?: 1;
|
||||
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
|
||||
- _nkmp.min_k = nkmp->k.min;
|
||||
+ _nkmp.min_k = nkmp->k.min ?: 1;
|
||||
_nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
|
||||
_nkmp.min_m = 1;
|
||||
_nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
|
||||
index af71b19..f312c92 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nm.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
|
||||
@@ -99,7 +99,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
struct ccu_nm *nm = hw_to_ccu_nm(hw);
|
||||
struct _ccu_nm _nm;
|
||||
|
||||
- _nm.min_n = nm->n.min;
|
||||
+ _nm.min_n = nm->n.min ?: 1;
|
||||
_nm.max_n = nm->n.max ?: 1 << nm->n.width;
|
||||
_nm.min_m = 1;
|
||||
_nm.max_m = nm->m.max ?: 1 << nm->m.width;
|
||||
From bafee6723b1c425dee1c415463b7386ea923d2cd Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@csie.org>
|
||||
Date: Fri, 24 Mar 2017 16:33:06 +0800
|
||||
Subject: [PATCH] clk: sunxi-ng: Fix round_rate/set_rate multiplier minimum
|
||||
mismatch
|
||||
|
||||
In commit 2beaa601c849 ("clk: sunxi-ng: Implement minimum for
|
||||
multipliers"), the multiplier minimums in the set_rate callback
|
||||
for NM and NKMP style clocks were not updated.
|
||||
|
||||
This patch fixes them to match their round_rate callbacks.
|
||||
|
||||
Fixes: 2beaa601c849 ("clk: sunxi-ng: Implement minimum for multipliers")
|
||||
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu_nkmp.c | 4 ++--
|
||||
drivers/clk/sunxi-ng/ccu_nm.c | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
index 162ff26..e58c9578 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
@@ -138,9 +138,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
- _nkmp.min_n = 1;
|
||||
+ _nkmp.min_n = nkmp->n.min ?: 1;
|
||||
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
|
||||
- _nkmp.min_k = 1;
|
||||
+ _nkmp.min_k = nkmp->k.min ?: 1;
|
||||
_nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
|
||||
_nkmp.min_m = 1;
|
||||
_nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
|
||||
index f312c92..5e5e90a 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nm.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
|
||||
@@ -122,7 +122,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
else
|
||||
ccu_frac_helper_disable(&nm->common, &nm->frac);
|
||||
|
||||
- _nm.min_n = 1;
|
||||
+ _nm.min_n = nm->n.min ?: 1;
|
||||
_nm.max_n = nm->n.max ?: 1 << nm->n.width;
|
||||
_nm.min_m = 1;
|
||||
_nm.max_m = nm->m.max ?: 1 << nm->m.width;
|
||||
From 43b883c1d002fa910e88e5776a0c42c733bb151f Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@csie.org>
|
||||
Date: Fri, 24 Mar 2017 16:33:07 +0800
|
||||
Subject: [PATCH] clk: sunxi-ng: a80: Fix audio PLL comment not matching actual
|
||||
code
|
||||
|
||||
We ignore the d1 and d2 dividers in the audio PLL, and force them to
|
||||
1 (register value 0) at probe time. However the comment preceding the
|
||||
audio PLL definition says we enforce the default value, which is not
|
||||
the same.
|
||||
|
||||
Fix the preceding comment to match what we do in code.
|
||||
|
||||
Fixes: b8eb71dcdd08 ("clk: sunxi-ng: Add A80 CCU")
|
||||
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu-sun9i-a80.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
|
||||
index e13e313..a031bee 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
|
||||
@@ -70,8 +70,7 @@ static struct ccu_nm pll_c1cpux_clk = {
|
||||
/*
|
||||
* The Audio PLL has d1, d2 dividers in addition to the usual N, M
|
||||
* factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz
|
||||
- * and 24.576 MHz, ignore them for now. Enforce the default for them,
|
||||
- * which is d1 = 0, d2 = 1.
|
||||
+ * and 24.576 MHz, ignore them for now. Enforce d1 = 0 and d2 = 0.
|
||||
*/
|
||||
#define SUN9I_A80_PLL_AUDIO_REG 0x008
|
||||
|
||||
From 9594d638564896ac0f40cfd316e87a55c8d30570 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@csie.org>
|
||||
Date: Tue, 14 Feb 2017 11:35:23 +0800
|
||||
Subject: [PATCH] clk: sunxi-ng: gate: Support common pre-dividers
|
||||
|
||||
Some clock gates have a pre-divider between the source input and the
|
||||
gate itself. A notable example is the HSIC 12 MHz clock found on the
|
||||
A83T, which has the 24 MHz main oscillator as its input, and a /2
|
||||
pre-divider.
|
||||
|
||||
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
|
||||
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu_gate.c | 47 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 47 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_gate.c b/drivers/clk/sunxi-ng/ccu_gate.c
|
||||
index 8a81f9d..cd069d5 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_gate.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_gate.c
|
||||
@@ -75,8 +75,55 @@ static int ccu_gate_is_enabled(struct clk_hw *hw)
|
||||
return ccu_gate_helper_is_enabled(&cg->common, cg->enable);
|
||||
}
|
||||
|
||||
+static unsigned long ccu_gate_recalc_rate(struct clk_hw *hw,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct ccu_gate *cg = hw_to_ccu_gate(hw);
|
||||
+ unsigned long rate = parent_rate;
|
||||
+
|
||||
+ if (cg->common.features & CCU_FEATURE_ALL_PREDIV)
|
||||
+ rate /= cg->common.prediv;
|
||||
+
|
||||
+ return rate;
|
||||
+}
|
||||
+
|
||||
+static long ccu_gate_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long *prate)
|
||||
+{
|
||||
+ struct ccu_gate *cg = hw_to_ccu_gate(hw);
|
||||
+ int div = 1;
|
||||
+
|
||||
+ if (cg->common.features & CCU_FEATURE_ALL_PREDIV)
|
||||
+ div = cg->common.prediv;
|
||||
+
|
||||
+ if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
|
||||
+ unsigned long best_parent = rate;
|
||||
+
|
||||
+ if (cg->common.features & CCU_FEATURE_ALL_PREDIV)
|
||||
+ best_parent *= div;
|
||||
+ *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
|
||||
+ }
|
||||
+
|
||||
+ return *prate / div;
|
||||
+}
|
||||
+
|
||||
+static int ccu_gate_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ /*
|
||||
+ * We must report success but we can do so unconditionally because
|
||||
+ * clk_factor_round_rate returns values that ensure this call is a
|
||||
+ * nop.
|
||||
+ */
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
const struct clk_ops ccu_gate_ops = {
|
||||
.disable = ccu_gate_disable,
|
||||
.enable = ccu_gate_enable,
|
||||
.is_enabled = ccu_gate_is_enabled,
|
||||
+ .round_rate = ccu_gate_round_rate,
|
||||
+ .set_rate = ccu_gate_set_rate,
|
||||
+ .recalc_rate = ccu_gate_recalc_rate,
|
||||
};
|
||||
From 272bce4ab673fca0e42add73189e559acbf8e0ca Mon Sep 17 00:00:00 2001
|
||||
From: Peter Robinson <pbrobinson@gmail.com>
|
||||
Date: Thu, 2 Mar 2017 17:43:57 +0000
|
||||
Subject: [PATCH] clk: sunxi-ng: tighten SoC deps on explicit AllWinner SoCs
|
||||
|
||||
Tighten the depends on the various AllWinn SoCs so we don't
|
||||
inadvertantly get clock drivers when we're not wanting them
|
||||
like 32 bit SoC clocks for 64 bit configs. Ensure there's
|
||||
still test coverage though.
|
||||
|
||||
Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
|
||||
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
---
|
||||
drivers/clk/sunxi-ng/Kconfig | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
|
||||
index 6b347d4..cf8dc27 100644
|
||||
--- a/drivers/clk/sunxi-ng/Kconfig
|
||||
+++ b/drivers/clk/sunxi-ng/Kconfig
|
||||
@@ -64,6 +64,7 @@ config SUN50I_A64_CCU
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default ARM64 && ARCH_SUNXI
|
||||
+ depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN5I_CCU
|
||||
bool "Support for the Allwinner sun5i family CCM"
|
||||
@@ -75,6 +76,7 @@ config SUN5I_CCU
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default MACH_SUN5I
|
||||
+ depends on MACH_SUN5I || COMPILE_TEST
|
||||
|
||||
config SUN6I_A31_CCU
|
||||
bool "Support for the Allwinner A31/A31s CCU"
|
||||
@@ -86,6 +88,7 @@ config SUN6I_A31_CCU
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default MACH_SUN6I
|
||||
+ depends on MACH_SUN6I || COMPILE_TEST
|
||||
|
||||
config SUN8I_A23_CCU
|
||||
bool "Support for the Allwinner A23 CCU"
|
||||
@@ -98,6 +101,7 @@ config SUN8I_A23_CCU
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default MACH_SUN8I
|
||||
+ depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_A33_CCU
|
||||
bool "Support for the Allwinner A33 CCU"
|
||||
@@ -110,6 +114,7 @@ config SUN8I_A33_CCU
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default MACH_SUN8I
|
||||
+ depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_H3_CCU
|
||||
bool "Support for the Allwinner H3 CCU"
|
||||
@@ -121,6 +126,7 @@ config SUN8I_H3_CCU
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
|
||||
+ depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN8I_V3S_CCU
|
||||
bool "Support for the Allwinner V3s CCU"
|
||||
@@ -132,6 +138,7 @@ config SUN8I_V3S_CCU
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default MACH_SUN8I
|
||||
+ depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN9I_A80_CCU
|
||||
bool "Support for the Allwinner A80 CCU"
|
||||
@@ -143,5 +150,6 @@ config SUN9I_A80_CCU
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default MACH_SUN9I
|
||||
+ depends on MACH_SUN9I || COMPILE_TEST
|
||||
|
||||
endif
|
||||
@ -1,54 +0,0 @@
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
index 495edf5f..c0edd5c2 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
@@ -45,6 +45,22 @@
|
||||
/ {
|
||||
interrupt-parent = <&gic>;
|
||||
|
||||
+ chosen {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges;
|
||||
+
|
||||
+ simplefb_hdmi: framebuffer@0 {
|
||||
+ compatible = "allwinner,simple-framebuffer",
|
||||
+ "simple-framebuffer";
|
||||
+ allwinner,pipeline = "de0-lcd0-hdmi";
|
||||
+ clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_BUS_DE>,
|
||||
+ <&ccu CLK_BUS_HDMI>, <&ccu CLK_DE>,
|
||||
+ <&ccu CLK_TCON0>, <&ccu CLK_HDMI>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
index 100e9b49..e208e005 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -52,6 +52,22 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
+ chosen {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges;
|
||||
+
|
||||
+ simplefb_hdmi: framebuffer@0 {
|
||||
+ compatible = "allwinner,simple-framebuffer",
|
||||
+ "simple-framebuffer";
|
||||
+ allwinner,pipeline = "de0-lcd0-hdmi";
|
||||
+ clocks = <&ccu CLK_BUS_TCON1>, <&ccu CLK_BUS_DE>,
|
||||
+ <&ccu CLK_BUS_HDMI>, <&ccu CLK_DE>,
|
||||
+ <&ccu CLK_TCON1>, <&ccu CLK_HDMI>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
Loading…
Reference in New Issue
Block a user