remove out of date, unused patches
This commit is contained in:
parent
d9632f677f
commit
9df3a682e5
@ -1,38 +0,0 @@
|
||||
From bca0f6d98bb3003178d962f83ba795d524460346 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
Date: Fri, 5 Sep 2014 15:43:56 -0600
|
||||
Subject: [PATCH 04/14] fix mvsdio eMMC timing
|
||||
|
||||
These changes from Globalscale change the MMC timing to allow the eMMC versions
|
||||
of the Mirabox and SMILE Plug to work.
|
||||
|
||||
Signed-off-by: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
---
|
||||
drivers/mmc/host/mvsdio.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
|
||||
index e22bbff89c8d..6b30c850ce07 100644
|
||||
--- a/drivers/mmc/host/mvsdio.c
|
||||
+++ b/drivers/mmc/host/mvsdio.c
|
||||
@@ -93,7 +93,7 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
|
||||
tmout_index = fls(tmout - 1) - 12;
|
||||
if (tmout_index < 0)
|
||||
tmout_index = 0;
|
||||
- if (tmout_index > MVSD_HOST_CTRL_TMOUT_MAX)
|
||||
+// if (tmout_index > MVSD_HOST_CTRL_TMOUT_MAX) //by steven, try to setup the timeout to maximum value
|
||||
tmout_index = MVSD_HOST_CTRL_TMOUT_MAX;
|
||||
|
||||
dev_dbg(host->dev, "data %s at 0x%08x: blocks=%d blksz=%d tmout=%u (%d)\n",
|
||||
@@ -616,6 +616,8 @@ static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
u32 m = DIV_ROUND_UP(host->base_clock, ios->clock) - 1;
|
||||
if (m > MVSD_BASE_DIV_MAX)
|
||||
m = MVSD_BASE_DIV_MAX;
|
||||
+ if(ios->clock==50000000 ) //by steven
|
||||
+ m=1;
|
||||
mvsd_write(MVSD_CLK_DIV, m);
|
||||
host->clock = ios->clock;
|
||||
host->ns_per_clk = 1000000000 / (host->base_clock / (m+1));
|
||||
--
|
||||
2.18.0
|
||||
|
@ -1,790 +0,0 @@
|
||||
From 4ddcbb9ed40c97371724245d0b8d01d471bb6570 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Chen <peter.chen@nxp.com>
|
||||
Date: Wed, 21 Jun 2017 14:42:03 +0800
|
||||
Subject: [PATCH 09/14] power: add power sequence library
|
||||
|
||||
We have an well-known problem that the device needs to do some power
|
||||
sequence before it can be recognized by related host, the typical
|
||||
example like hard-wired mmc devices and usb devices.
|
||||
|
||||
This power sequence is hard to be described at device tree and handled by
|
||||
related host driver, so we have created a common power sequence
|
||||
library to cover this requirement. The core code has supplied
|
||||
some common helpers for host driver, and individual power sequence
|
||||
libraries handle kinds of power sequence for devices. The pwrseq
|
||||
librares always need to allocate extra instance for compatible
|
||||
string match.
|
||||
|
||||
pwrseq_generic is intended for general purpose of power sequence, which
|
||||
handles gpios and clocks currently, and can cover other controls in
|
||||
future. The host driver just needs to call of_pwrseq_on/of_pwrseq_off
|
||||
if only one power sequence is needed, else call of_pwrseq_on_list
|
||||
/of_pwrseq_off_list instead (eg, USB hub driver).
|
||||
|
||||
For new power sequence library, it needs to add its compatible string
|
||||
and allocation function at pwrseq_match_table_list, then the pwrseq
|
||||
core will match it with DT's, and choose this library at runtime.
|
||||
|
||||
Signed-off-by: Peter Chen <peter.chen@nxp.com>
|
||||
Tested-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
Tested-by Joshua Clayton <stillcompiling@gmail.com>
|
||||
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
|
||||
Tested-by: Matthias Kaehlcke <mka@chromium.org>
|
||||
---
|
||||
Documentation/power/power-sequence/design.rst | 54 ++++
|
||||
MAINTAINERS | 9 +
|
||||
drivers/power/Kconfig | 1 +
|
||||
drivers/power/Makefile | 1 +
|
||||
drivers/power/pwrseq/Kconfig | 20 ++
|
||||
drivers/power/pwrseq/Makefile | 2 +
|
||||
drivers/power/pwrseq/core.c | 293 ++++++++++++++++++
|
||||
drivers/power/pwrseq/pwrseq_generic.c | 210 +++++++++++++
|
||||
include/linux/power/pwrseq.h | 84 +++++
|
||||
9 files changed, 674 insertions(+)
|
||||
create mode 100644 Documentation/power/power-sequence/design.rst
|
||||
create mode 100644 drivers/power/pwrseq/Kconfig
|
||||
create mode 100644 drivers/power/pwrseq/Makefile
|
||||
create mode 100644 drivers/power/pwrseq/core.c
|
||||
create mode 100644 drivers/power/pwrseq/pwrseq_generic.c
|
||||
create mode 100644 include/linux/power/pwrseq.h
|
||||
|
||||
diff --git a/Documentation/power/power-sequence/design.rst b/Documentation/power/power-sequence/design.rst
|
||||
new file mode 100644
|
||||
index 000000000000..554608e5f3b6
|
||||
--- /dev/null
|
||||
+++ b/Documentation/power/power-sequence/design.rst
|
||||
@@ -0,0 +1,54 @@
|
||||
+====================================
|
||||
+Power Sequence Library
|
||||
+====================================
|
||||
+
|
||||
+:Date: Feb, 2017
|
||||
+:Author: Peter Chen <peter.chen@nxp.com>
|
||||
+
|
||||
+
|
||||
+Introduction
|
||||
+============
|
||||
+
|
||||
+We have an well-known problem that the device needs to do a power
|
||||
+sequence before it can be recognized by related host, the typical
|
||||
+examples are hard-wired mmc devices and usb devices. The host controller
|
||||
+can't know what kinds of this device is in its bus if the power
|
||||
+sequence has not done, since the related devices driver's probe calling
|
||||
+is determined by runtime according to eunumeration results. Besides,
|
||||
+the devices may have custom power sequence, so the power sequence library
|
||||
+which is independent with the devices is needed.
|
||||
+
|
||||
+Design
|
||||
+============
|
||||
+
|
||||
+The power sequence library includes the core file and customer power
|
||||
+sequence library. The core file exports interfaces are called by
|
||||
+host controller driver for power sequence and customer power sequence
|
||||
+library files to register its power sequence instance to global
|
||||
+power sequence list. The custom power sequence library creates power
|
||||
+sequence instance and implement custom power sequence.
|
||||
+
|
||||
+Since the power sequence describes hardware design, the description is
|
||||
+located at board description file, eg, device tree dts file. And
|
||||
+a specific power sequence belongs to device, so its description
|
||||
+is under the device node, please refer to:
|
||||
+Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
|
||||
+
|
||||
+Custom power sequence library allocates one power sequence instance at
|
||||
+bootup periods using postcore_initcall, this static allocated instance is
|
||||
+used to compare with device-tree (DT) node to see if this library can be
|
||||
+used for the node or not. When the result is matched, the core API will
|
||||
+try to get resourses (->get, implemented at each library) for power
|
||||
+sequence, if all resources are got, it will try to allocate another
|
||||
+instance for next possible request from host driver.
|
||||
+
|
||||
+Then, the host controller driver can carry out power sequence on for this
|
||||
+DT node, the library will do corresponding operations, like open clocks,
|
||||
+toggle gpio, etc. The power sequence off routine will close and free the
|
||||
+resources, and is called when the parent is removed. And the power
|
||||
+sequence suspend and resume routine can be called at host driver's
|
||||
+suspend and resume routine if needed.
|
||||
+
|
||||
+The exported interfaces
|
||||
+.. kernel-doc:: drivers/power/pwrseq/core.c
|
||||
+ :export:
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 96e98e206b0d..99339375209c 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -11398,6 +11398,15 @@ F: drivers/firmware/psci*.c
|
||||
F: include/linux/psci.h
|
||||
F: include/uapi/linux/psci.h
|
||||
|
||||
+POWER SEQUENCE LIBRARY
|
||||
+M: Peter Chen <Peter.Chen@nxp.com>
|
||||
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git
|
||||
+L: linux-pm@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: Documentation/devicetree/bindings/power/pwrseq/
|
||||
+F: drivers/power/pwrseq/
|
||||
+F: include/linux/power/pwrseq.h
|
||||
+
|
||||
POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
|
||||
M: Sebastian Reichel <sre@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
|
||||
index 63454b5cac27..c1bb0465f956 100644
|
||||
--- a/drivers/power/Kconfig
|
||||
+++ b/drivers/power/Kconfig
|
||||
@@ -1,3 +1,4 @@
|
||||
source "drivers/power/avs/Kconfig"
|
||||
source "drivers/power/reset/Kconfig"
|
||||
source "drivers/power/supply/Kconfig"
|
||||
+source "drivers/power/pwrseq/Kconfig"
|
||||
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
|
||||
index ff35c712d824..7db80354b691 100644
|
||||
--- a/drivers/power/Makefile
|
||||
+++ b/drivers/power/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_POWER_AVS) += avs/
|
||||
obj-$(CONFIG_POWER_RESET) += reset/
|
||||
obj-$(CONFIG_POWER_SUPPLY) += supply/
|
||||
+obj-$(CONFIG_POWER_SEQUENCE) += pwrseq/
|
||||
diff --git a/drivers/power/pwrseq/Kconfig b/drivers/power/pwrseq/Kconfig
|
||||
new file mode 100644
|
||||
index 000000000000..c6b356926cca
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/pwrseq/Kconfig
|
||||
@@ -0,0 +1,20 @@
|
||||
+#
|
||||
+# Power Sequence library
|
||||
+#
|
||||
+
|
||||
+menuconfig POWER_SEQUENCE
|
||||
+ bool "Power sequence control"
|
||||
+ help
|
||||
+ It is used for drivers which needs to do power sequence
|
||||
+ (eg, turn on clock, toggle reset gpio) before the related
|
||||
+ devices can be found by hardware, eg, USB bus.
|
||||
+
|
||||
+if POWER_SEQUENCE
|
||||
+
|
||||
+config PWRSEQ_GENERIC
|
||||
+ bool "Generic power sequence control"
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ This is the generic power sequence control library, and is
|
||||
+ supposed to support common power sequence usage.
|
||||
+endif
|
||||
diff --git a/drivers/power/pwrseq/Makefile b/drivers/power/pwrseq/Makefile
|
||||
new file mode 100644
|
||||
index 000000000000..ad82389028c2
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/pwrseq/Makefile
|
||||
@@ -0,0 +1,2 @@
|
||||
+obj-$(CONFIG_POWER_SEQUENCE) += core.o
|
||||
+obj-$(CONFIG_PWRSEQ_GENERIC) += pwrseq_generic.o
|
||||
diff --git a/drivers/power/pwrseq/core.c b/drivers/power/pwrseq/core.c
|
||||
new file mode 100644
|
||||
index 000000000000..6b78a6691683
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/pwrseq/core.c
|
||||
@@ -0,0 +1,293 @@
|
||||
+/*
|
||||
+ * core.c power sequence core file
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
+ * Author: Peter Chen <peter.chen@nxp.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 of
|
||||
+ * the License as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/power/pwrseq.h>
|
||||
+
|
||||
+/*
|
||||
+ * Static power sequence match table
|
||||
+ * - Add compatible (the same with dts node) and related allocation function.
|
||||
+ * - Update related binding doc.
|
||||
+ */
|
||||
+static const struct of_device_id pwrseq_match_table_list[] = {
|
||||
+ { .compatible = "usb424,2513", .data = &pwrseq_generic_alloc_instance},
|
||||
+ { .compatible = "usb424,2514", .data = &pwrseq_generic_alloc_instance},
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+static int pwrseq_get(struct device_node *np, struct pwrseq *p)
|
||||
+{
|
||||
+ if (p && p->get)
|
||||
+ return p->get(np, p);
|
||||
+
|
||||
+ return -ENOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static int pwrseq_on(struct pwrseq *p)
|
||||
+{
|
||||
+ if (p && p->on)
|
||||
+ return p->on(p);
|
||||
+
|
||||
+ return -ENOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static void pwrseq_off(struct pwrseq *p)
|
||||
+{
|
||||
+ if (p && p->off)
|
||||
+ p->off(p);
|
||||
+}
|
||||
+
|
||||
+static void pwrseq_put(struct pwrseq *p)
|
||||
+{
|
||||
+ if (p && p->put)
|
||||
+ p->put(p);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * of_pwrseq_on - Carry out power sequence on for device node
|
||||
+ *
|
||||
+ * @np: the device node would like to power on
|
||||
+ *
|
||||
+ * Carry out a single device power on. If multiple devices
|
||||
+ * need to be handled, use of_pwrseq_on_list() instead.
|
||||
+ *
|
||||
+ * Return a pointer to the power sequence instance on success, or NULL if
|
||||
+ * not exist, or an error code on failure.
|
||||
+ */
|
||||
+struct pwrseq *of_pwrseq_on(struct device_node *np)
|
||||
+{
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ int ret;
|
||||
+ const struct of_device_id *of_id;
|
||||
+ struct pwrseq *(*alloc_instance)(void);
|
||||
+
|
||||
+ of_id = of_match_node(pwrseq_match_table_list, np);
|
||||
+ if (!of_id)
|
||||
+ return NULL;
|
||||
+
|
||||
+ alloc_instance = of_id->data;
|
||||
+ /* Allocate pwrseq instance */
|
||||
+ pwrseq = alloc_instance();
|
||||
+ if (IS_ERR(pwrseq))
|
||||
+ return pwrseq;
|
||||
+
|
||||
+ ret = pwrseq_get(np, pwrseq);
|
||||
+ if (ret)
|
||||
+ goto pwr_put;
|
||||
+
|
||||
+ ret = pwrseq_on(pwrseq);
|
||||
+ if (ret)
|
||||
+ goto pwr_put;
|
||||
+
|
||||
+ return pwrseq;
|
||||
+
|
||||
+pwr_put:
|
||||
+ pwrseq_put(pwrseq);
|
||||
+ return ERR_PTR(ret);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(of_pwrseq_on);
|
||||
+
|
||||
+/**
|
||||
+ * of_pwrseq_off - Carry out power sequence off for this pwrseq instance
|
||||
+ *
|
||||
+ * @pwrseq: the pwrseq instance which related device would like to be off
|
||||
+ *
|
||||
+ * This API is used to power off single device, it is the opposite
|
||||
+ * operation for of_pwrseq_on.
|
||||
+ */
|
||||
+void of_pwrseq_off(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ pwrseq_off(pwrseq);
|
||||
+ pwrseq_put(pwrseq);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(of_pwrseq_off);
|
||||
+
|
||||
+/**
|
||||
+ * of_pwrseq_on_list - Carry out power sequence on for list
|
||||
+ *
|
||||
+ * @np: the device node would like to power on
|
||||
+ * @head: the list head for pwrseq list on this bus
|
||||
+ *
|
||||
+ * This API is used to power on multiple devices at single bus.
|
||||
+ * If there are several devices on bus (eg, USB bus), uses this
|
||||
+ * this API. Otherwise, use of_pwrseq_on instead. After the device
|
||||
+ * is powered on successfully, it will be added to pwrseq list for
|
||||
+ * this bus. The caller needs to use mutex_lock for concurrent.
|
||||
+ *
|
||||
+ * Return 0 on success, or -ENOENT if not exist, or an error value on failure.
|
||||
+ */
|
||||
+int of_pwrseq_on_list(struct device_node *np, struct list_head *head)
|
||||
+{
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ struct pwrseq_list_per_dev *pwrseq_list_node;
|
||||
+
|
||||
+ pwrseq_list_node = kzalloc(sizeof(*pwrseq_list_node), GFP_KERNEL);
|
||||
+ if (!pwrseq_list_node)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pwrseq = of_pwrseq_on(np);
|
||||
+ if (!pwrseq)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ if (IS_ERR(pwrseq)) {
|
||||
+ kfree(pwrseq_list_node);
|
||||
+ return PTR_ERR(pwrseq);
|
||||
+ }
|
||||
+
|
||||
+ pwrseq_list_node->pwrseq = pwrseq;
|
||||
+ list_add(&pwrseq_list_node->list, head);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(of_pwrseq_on_list);
|
||||
+
|
||||
+/**
|
||||
+ * of_pwrseq_off_list - Carry out power sequence off for the list
|
||||
+ *
|
||||
+ * @head: the list head for pwrseq instance list on this bus
|
||||
+ *
|
||||
+ * This API is used to power off all devices on this bus, it is
|
||||
+ * the opposite operation for of_pwrseq_on_list.
|
||||
+ * The caller needs to use mutex_lock for concurrent.
|
||||
+ */
|
||||
+void of_pwrseq_off_list(struct list_head *head)
|
||||
+{
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ struct pwrseq_list_per_dev *pwrseq_list_node, *tmp_node;
|
||||
+
|
||||
+ list_for_each_entry_safe(pwrseq_list_node, tmp_node, head, list) {
|
||||
+ pwrseq = pwrseq_list_node->pwrseq;
|
||||
+ of_pwrseq_off(pwrseq);
|
||||
+ list_del(&pwrseq_list_node->list);
|
||||
+ kfree(pwrseq_list_node);
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(of_pwrseq_off_list);
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_suspend - Carry out power sequence suspend for this pwrseq instance
|
||||
+ *
|
||||
+ * @pwrseq: the pwrseq instance
|
||||
+ *
|
||||
+ * This API is used to do suspend operation on pwrseq instance.
|
||||
+ *
|
||||
+ * Return 0 on success, or an error value otherwise.
|
||||
+ */
|
||||
+int pwrseq_suspend(struct pwrseq *p)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (p && p->suspend)
|
||||
+ ret = p->suspend(p);
|
||||
+ else
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!ret)
|
||||
+ p->suspended = true;
|
||||
+ else
|
||||
+ pr_err("%s failed\n", __func__);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(pwrseq_suspend);
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_resume - Carry out power sequence resume for this pwrseq instance
|
||||
+ *
|
||||
+ * @pwrseq: the pwrseq instance
|
||||
+ *
|
||||
+ * This API is used to do resume operation on pwrseq instance.
|
||||
+ *
|
||||
+ * Return 0 on success, or an error value otherwise.
|
||||
+ */
|
||||
+int pwrseq_resume(struct pwrseq *p)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (p && p->resume)
|
||||
+ ret = p->resume(p);
|
||||
+ else
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!ret)
|
||||
+ p->suspended = false;
|
||||
+ else
|
||||
+ pr_err("%s failed\n", __func__);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(pwrseq_resume);
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_suspend_list - Carry out power sequence suspend for list
|
||||
+ *
|
||||
+ * @head: the list head for pwrseq instance list on this bus
|
||||
+ *
|
||||
+ * This API is used to do suspend on all power sequence instances on this bus.
|
||||
+ * The caller needs to use mutex_lock for concurrent.
|
||||
+ */
|
||||
+int pwrseq_suspend_list(struct list_head *head)
|
||||
+{
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ struct pwrseq_list_per_dev *pwrseq_list_node;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ list_for_each_entry(pwrseq_list_node, head, list) {
|
||||
+ ret = pwrseq_suspend(pwrseq_list_node->pwrseq);
|
||||
+ if (ret)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (ret) {
|
||||
+ list_for_each_entry(pwrseq_list_node, head, list) {
|
||||
+ pwrseq = pwrseq_list_node->pwrseq;
|
||||
+ if (pwrseq->suspended)
|
||||
+ pwrseq_resume(pwrseq);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(pwrseq_suspend_list);
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_resume_list - Carry out power sequence resume for the list
|
||||
+ *
|
||||
+ * @head: the list head for pwrseq instance list on this bus
|
||||
+ *
|
||||
+ * This API is used to do resume on all power sequence instances on this bus.
|
||||
+ * The caller needs to use mutex_lock for concurrent.
|
||||
+ */
|
||||
+int pwrseq_resume_list(struct list_head *head)
|
||||
+{
|
||||
+ struct pwrseq_list_per_dev *pwrseq_list_node;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ list_for_each_entry(pwrseq_list_node, head, list) {
|
||||
+ ret = pwrseq_resume(pwrseq_list_node->pwrseq);
|
||||
+ if (ret)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(pwrseq_resume_list);
|
||||
diff --git a/drivers/power/pwrseq/pwrseq_generic.c b/drivers/power/pwrseq/pwrseq_generic.c
|
||||
new file mode 100644
|
||||
index 000000000000..b7bbd6c5b47d
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/pwrseq/pwrseq_generic.c
|
||||
@@ -0,0 +1,210 @@
|
||||
+/*
|
||||
+ * pwrseq_generic.c Generic power sequence handling
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
+ * Author: Peter Chen <peter.chen@nxp.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 of
|
||||
+ * the License as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/gpio/consumer.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_gpio.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include <linux/power/pwrseq.h>
|
||||
+
|
||||
+struct pwrseq_generic {
|
||||
+ struct pwrseq pwrseq;
|
||||
+ struct gpio_desc *gpiod_reset;
|
||||
+ struct clk *clks[PWRSEQ_MAX_CLKS];
|
||||
+ u32 duration_us;
|
||||
+ bool suspended;
|
||||
+};
|
||||
+
|
||||
+#define to_generic_pwrseq(p) container_of(p, struct pwrseq_generic, pwrseq)
|
||||
+
|
||||
+static int pwrseq_generic_suspend(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk;
|
||||
+
|
||||
+ for (clk = PWRSEQ_MAX_CLKS - 1; clk >= 0; clk--)
|
||||
+ clk_disable_unprepare(pwrseq_gen->clks[clk]);
|
||||
+
|
||||
+ pwrseq_gen->suspended = true;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int pwrseq_generic_resume(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk, ret = 0;
|
||||
+
|
||||
+ for (clk = 0; clk < PWRSEQ_MAX_CLKS && pwrseq_gen->clks[clk]; clk++) {
|
||||
+ ret = clk_prepare_enable(pwrseq_gen->clks[clk]);
|
||||
+ if (ret) {
|
||||
+ pr_err("Can't enable clock, ret=%d\n", ret);
|
||||
+ goto err_disable_clks;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pwrseq_gen->suspended = false;
|
||||
+ return ret;
|
||||
+
|
||||
+err_disable_clks:
|
||||
+ while (--clk >= 0)
|
||||
+ clk_disable_unprepare(pwrseq_gen->clks[clk]);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void pwrseq_generic_put(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk;
|
||||
+
|
||||
+ if (pwrseq_gen->gpiod_reset)
|
||||
+ gpiod_put(pwrseq_gen->gpiod_reset);
|
||||
+
|
||||
+ for (clk = 0; clk < PWRSEQ_MAX_CLKS; clk++)
|
||||
+ clk_put(pwrseq_gen->clks[clk]);
|
||||
+
|
||||
+ kfree(pwrseq_gen);
|
||||
+}
|
||||
+
|
||||
+static void pwrseq_generic_off(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk;
|
||||
+
|
||||
+ if (pwrseq_gen->suspended)
|
||||
+ return;
|
||||
+
|
||||
+ for (clk = PWRSEQ_MAX_CLKS - 1; clk >= 0; clk--)
|
||||
+ clk_disable_unprepare(pwrseq_gen->clks[clk]);
|
||||
+}
|
||||
+
|
||||
+static int pwrseq_generic_on(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk, ret = 0;
|
||||
+ struct gpio_desc *gpiod_reset = pwrseq_gen->gpiod_reset;
|
||||
+
|
||||
+ for (clk = 0; clk < PWRSEQ_MAX_CLKS && pwrseq_gen->clks[clk]; clk++) {
|
||||
+ ret = clk_prepare_enable(pwrseq_gen->clks[clk]);
|
||||
+ if (ret) {
|
||||
+ pr_err("Can't enable clock, ret=%d\n", ret);
|
||||
+ goto err_disable_clks;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (gpiod_reset) {
|
||||
+ u32 duration_us = pwrseq_gen->duration_us;
|
||||
+
|
||||
+ if (duration_us <= 10)
|
||||
+ udelay(10);
|
||||
+ else
|
||||
+ usleep_range(duration_us, duration_us + 100);
|
||||
+ gpiod_set_value(gpiod_reset, 0);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+err_disable_clks:
|
||||
+ while (--clk >= 0)
|
||||
+ clk_disable_unprepare(pwrseq_gen->clks[clk]);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int pwrseq_generic_get(struct device_node *np, struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ enum of_gpio_flags flags;
|
||||
+ int reset_gpio, clk, ret = 0;
|
||||
+
|
||||
+ for (clk = 0; clk < PWRSEQ_MAX_CLKS; clk++) {
|
||||
+ pwrseq_gen->clks[clk] = of_clk_get(np, clk);
|
||||
+ if (IS_ERR(pwrseq_gen->clks[clk])) {
|
||||
+ ret = PTR_ERR(pwrseq_gen->clks[clk]);
|
||||
+ if (ret != -ENOENT)
|
||||
+ goto err_put_clks;
|
||||
+ pwrseq_gen->clks[clk] = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
|
||||
+ if (gpio_is_valid(reset_gpio)) {
|
||||
+ unsigned long gpio_flags;
|
||||
+
|
||||
+ if (flags & OF_GPIO_ACTIVE_LOW)
|
||||
+ gpio_flags = GPIOF_ACTIVE_LOW | GPIOF_OUT_INIT_LOW;
|
||||
+ else
|
||||
+ gpio_flags = GPIOF_OUT_INIT_HIGH;
|
||||
+
|
||||
+ ret = gpio_request_one(reset_gpio, gpio_flags,
|
||||
+ "pwrseq-reset-gpios");
|
||||
+ if (ret)
|
||||
+ goto err_put_clks;
|
||||
+
|
||||
+ pwrseq_gen->gpiod_reset = gpio_to_desc(reset_gpio);
|
||||
+ of_property_read_u32(np, "reset-duration-us",
|
||||
+ &pwrseq_gen->duration_us);
|
||||
+ } else if (reset_gpio == -ENOENT) {
|
||||
+ ; /* no such gpio */
|
||||
+ } else {
|
||||
+ ret = reset_gpio;
|
||||
+ pr_err("Failed to get reset gpio on %s, err = %d\n",
|
||||
+ np->full_name, reset_gpio);
|
||||
+ goto err_put_clks;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_put_clks:
|
||||
+ while (--clk >= 0)
|
||||
+ clk_put(pwrseq_gen->clks[clk]);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_generic_alloc_instance - power sequence instance allocation
|
||||
+ *
|
||||
+ * This function is used to allocate one generic power sequence instance,
|
||||
+ * it is called when the system boots up and after one power sequence
|
||||
+ * instance is got successfully.
|
||||
+ *
|
||||
+ * Return zero on success or an error code otherwise.
|
||||
+ */
|
||||
+struct pwrseq *pwrseq_generic_alloc_instance(void)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen;
|
||||
+
|
||||
+ pwrseq_gen = kzalloc(sizeof(*pwrseq_gen), GFP_KERNEL);
|
||||
+ if (!pwrseq_gen)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ pwrseq_gen->pwrseq.get = pwrseq_generic_get;
|
||||
+ pwrseq_gen->pwrseq.on = pwrseq_generic_on;
|
||||
+ pwrseq_gen->pwrseq.off = pwrseq_generic_off;
|
||||
+ pwrseq_gen->pwrseq.put = pwrseq_generic_put;
|
||||
+ pwrseq_gen->pwrseq.suspend = pwrseq_generic_suspend;
|
||||
+ pwrseq_gen->pwrseq.resume = pwrseq_generic_resume;
|
||||
+
|
||||
+ return &pwrseq_gen->pwrseq;
|
||||
+}
|
||||
diff --git a/include/linux/power/pwrseq.h b/include/linux/power/pwrseq.h
|
||||
new file mode 100644
|
||||
index 000000000000..c5b278f5f2ae
|
||||
--- /dev/null
|
||||
+++ b/include/linux/power/pwrseq.h
|
||||
@@ -0,0 +1,84 @@
|
||||
+#ifndef __LINUX_PWRSEQ_H
|
||||
+#define __LINUX_PWRSEQ_H
|
||||
+
|
||||
+#include <linux/of.h>
|
||||
+
|
||||
+#define PWRSEQ_MAX_CLKS 3
|
||||
+
|
||||
+/**
|
||||
+ * struct pwrseq - the power sequence structure
|
||||
+ * @pwrseq_of_match_table: the OF device id table this pwrseq library supports
|
||||
+ * @node: the list pointer to be added to pwrseq list
|
||||
+ * @get: the API is used to get pwrseq instance from the device node
|
||||
+ * @on: do power on for this pwrseq instance
|
||||
+ * @off: do power off for this pwrseq instance
|
||||
+ * @put: release the resources on this pwrseq instance
|
||||
+ * @suspend: do suspend operation on this pwrseq instance
|
||||
+ * @resume: do resume operation on this pwrseq instance
|
||||
+ */
|
||||
+struct pwrseq {
|
||||
+ const struct of_device_id *pwrseq_of_match_table;
|
||||
+ struct list_head node;
|
||||
+ int (*get)(struct device_node *np, struct pwrseq *p);
|
||||
+ int (*on)(struct pwrseq *p);
|
||||
+ void (*off)(struct pwrseq *p);
|
||||
+ void (*put)(struct pwrseq *p);
|
||||
+ int (*suspend)(struct pwrseq *p);
|
||||
+ int (*resume)(struct pwrseq *p);
|
||||
+ bool suspended;
|
||||
+};
|
||||
+
|
||||
+/* used for power sequence instance list in one driver */
|
||||
+struct pwrseq_list_per_dev {
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_POWER_SEQUENCE)
|
||||
+struct pwrseq *of_pwrseq_on(struct device_node *np);
|
||||
+void of_pwrseq_off(struct pwrseq *pwrseq);
|
||||
+int of_pwrseq_on_list(struct device_node *np, struct list_head *head);
|
||||
+void of_pwrseq_off_list(struct list_head *head);
|
||||
+int pwrseq_suspend(struct pwrseq *p);
|
||||
+int pwrseq_resume(struct pwrseq *p);
|
||||
+int pwrseq_suspend_list(struct list_head *head);
|
||||
+int pwrseq_resume_list(struct list_head *head);
|
||||
+#else
|
||||
+static inline struct pwrseq *of_pwrseq_on(struct device_node *np)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+static void of_pwrseq_off(struct pwrseq *pwrseq) {}
|
||||
+static int of_pwrseq_on_list(struct device_node *np, struct list_head *head)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static void of_pwrseq_off_list(struct list_head *head) {}
|
||||
+static int pwrseq_suspend(struct pwrseq *p)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static int pwrseq_resume(struct pwrseq *p)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static int pwrseq_suspend_list(struct list_head *head)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static int pwrseq_resume_list(struct list_head *head)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* CONFIG_POWER_SEQUENCE */
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_PWRSEQ_GENERIC)
|
||||
+extern struct pwrseq *pwrseq_generic_alloc_instance(void);
|
||||
+#else
|
||||
+static inline struct pwrseq *pwrseq_generic_alloc_instance(void)
|
||||
+{
|
||||
+ return ERR_PTR(-ENOTSUPP);
|
||||
+}
|
||||
+#endif /* CONFIG_PWRSEQ_GENERIC */
|
||||
+
|
||||
+#endif /* __LINUX_PWRSEQ_H */
|
||||
--
|
||||
2.18.0
|
||||
|
@ -1,733 +0,0 @@
|
||||
From aeb42ff3a2d04e19ff87b1e537e0d84d63132c11 Mon Sep 17 00:00:00 2001
|
||||
From: Urja Rannikko <urjaman@gmail.com>
|
||||
Date: Wed, 22 Aug 2018 18:36:05 +0000
|
||||
Subject: [PATCH] RK3288 HDMI clock hacks combined
|
||||
|
||||
This is only for my patching convenience, contains these:
|
||||
|
||||
clk: rockchip: improve rk3288 pll rates for better hdmi output
|
||||
dt-bindings: clock: rk3288-cru: Add property to dedicate NPLL for VOPx
|
||||
drivers: clk-rk3288: support for dedicating NPLL to a VOP
|
||||
dt-bindings: display/rockchip: dw_hdmi: Add property for HDMI frequency list
|
||||
drm: dw_hdmi-rockchip: better clock selection logic and dts-based rate list
|
||||
dts: rk3288: support for dedicating npll to a vop
|
||||
dts: rk3288-veyron-chromebook: dedicate npll to VOP0/HDMI + HDMI rates
|
||||
|
||||
Signed-off-by: Urja Rannikko <urjaman@gmail.com>
|
||||
---
|
||||
.../bindings/clock/rockchip,rk3288-cru.txt | 3 +
|
||||
.../display/rockchip/dw_hdmi-rockchip.txt | 1 +
|
||||
.../boot/dts/rk3288-veyron-chromebook.dtsi | 67 +++++
|
||||
arch/arm/boot/dts/rk3288.dtsi | 6 +-
|
||||
drivers/clk/rockchip/clk-rk3288.c | 98 +++++--
|
||||
drivers/clk/rockchip/clk.h | 3 +
|
||||
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 269 ++++++++++++------
|
||||
7 files changed, 335 insertions(+), 112 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
|
||||
index 8cb47c39ba53..20724584e0a4 100644
|
||||
--- a/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
|
||||
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
|
||||
@@ -16,6 +16,9 @@ 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.
|
||||
+- rockchip,npll-for-vop: u32 0 or 1, dedicates NPLL to a VOP output unit for
|
||||
+ more frequency flexibility for the selected VOP output at a cost of
|
||||
+ flexibility for other devices. Disabled if not present or -1.
|
||||
|
||||
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
|
||||
diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
|
||||
index adc94fc3c9f8..edeacbbc4f26 100644
|
||||
--- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
|
||||
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
|
||||
@@ -34,6 +34,7 @@ Optional properties
|
||||
- clock-names: May contain "cec" as defined in dw_hdmi.txt.
|
||||
- clock-names: May contain "grf", power for grf io.
|
||||
- clock-names: May contain "vpll", external clock for some hdmi phy.
|
||||
+- rockchip,hdmi-rates-hz: List of allowed HDMI frequencies in Hz.
|
||||
|
||||
Example:
|
||||
|
||||
diff --git a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
|
||||
index b16d570ff029..70ed0b2a9549 100644
|
||||
--- a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
|
||||
+++ b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
|
||||
@@ -163,6 +163,25 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&cru {
|
||||
+ /* Dedicate NPLL for VOP0 / VOP_BIG for HDMI. */
|
||||
+ rockchip,npll-for-vop = <0>;
|
||||
+ /* The first assigned clocks are DCLK_VOP0 and DCLK_VOP1 */
|
||||
+ assigned-clock-parents = <&cru PLL_NPLL>, <&cru PLL_GPLL>;
|
||||
+};
|
||||
+
|
||||
+/* Delete the nodes that allow non-desirable VOP - connector links. That
|
||||
+ * is the eDP cannot use vopb and HDMI cannot use vopl. */
|
||||
+
|
||||
+/delete-node/ &edp_in_vopb;
|
||||
+/delete-node/ &vopb_out_edp;
|
||||
+/delete-node/ &hdmi_in_vopl;
|
||||
+/delete-node/ &vopl_out_hdmi;
|
||||
+
|
||||
+/* Delete the 500 Mhz GPU opp since that cannot be easily made
|
||||
+ * without NPLL. */
|
||||
+/delete-node/ &{/gpu-opp-table/opp@500000000};
|
||||
+
|
||||
&edp {
|
||||
status = "okay";
|
||||
|
||||
@@ -186,6 +205,54 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&hdmi {
|
||||
+ /* These depend on NPLL being dedicated to HDMI use. */
|
||||
+ rockchip,hdmi-rates-hz = <
|
||||
+ 25176471 /* for 25.175 MHz, 0.006% off */
|
||||
+ 25200000
|
||||
+ 27000000
|
||||
+ 28320000
|
||||
+ 30240000
|
||||
+ 31500000
|
||||
+ 32000000
|
||||
+ 33750000
|
||||
+ 36000000
|
||||
+ 40000000
|
||||
+ 49500000
|
||||
+ 50000000
|
||||
+ 54000000
|
||||
+ 57290323 /* for 57.284 MHz, .011 % off */
|
||||
+ 65000000
|
||||
+ 68250000
|
||||
+ 71000000
|
||||
+ 72000000
|
||||
+ 73250000
|
||||
+ 74250000
|
||||
+ 74437500 /* for 74.44 MHz, .003% off */
|
||||
+ 75000000
|
||||
+ 78750000
|
||||
+ 78800000
|
||||
+ 79500000
|
||||
+ 83500000
|
||||
+ 85500000
|
||||
+ 88750000
|
||||
+ 97750000
|
||||
+ 101000000
|
||||
+ 106500000
|
||||
+ 108000000
|
||||
+ 115500000
|
||||
+ 118666667 /* for 118.68 MHz, .011% off */
|
||||
+ 119000000
|
||||
+ 121714286 /* for 121.75 MHz, .029% off */
|
||||
+ 135000000
|
||||
+ 136800000 /* for 136.75 MHz, .037% off */
|
||||
+ 146250000
|
||||
+ 148500000
|
||||
+ 154000000
|
||||
+ 162000000 >;
|
||||
+};
|
||||
+
|
||||
+
|
||||
&gpio_keys {
|
||||
pinctrl-0 = <&pwr_key_l &ap_lid_int_l>;
|
||||
lid {
|
||||
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
|
||||
index d7e49d29ace5..2106ddfdaf06 100644
|
||||
--- a/arch/arm/boot/dts/rk3288.dtsi
|
||||
+++ b/arch/arm/boot/dts/rk3288.dtsi
|
||||
@@ -840,12 +840,14 @@
|
||||
rockchip,grf = <&grf>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
- assigned-clocks = <&cru PLL_GPLL>, <&cru PLL_CPLL>,
|
||||
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>,
|
||||
+ <&cru PLL_GPLL>, <&cru PLL_CPLL>,
|
||||
<&cru PLL_NPLL>, <&cru ACLK_CPU>,
|
||||
<&cru HCLK_CPU>, <&cru PCLK_CPU>,
|
||||
<&cru ACLK_PERI>, <&cru HCLK_PERI>,
|
||||
<&cru PCLK_PERI>;
|
||||
- assigned-clock-rates = <594000000>, <400000000>,
|
||||
+ assigned-clock-rates = <0>, <0>,
|
||||
+ <594000000>, <400000000>,
|
||||
<500000000>, <300000000>,
|
||||
<150000000>, <75000000>,
|
||||
<300000000>, <150000000>,
|
||||
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
|
||||
index 450de24a1b42..7adf85e43078 100644
|
||||
--- a/drivers/clk/rockchip/clk-rk3288.c
|
||||
+++ b/drivers/clk/rockchip/clk-rk3288.c
|
||||
@@ -83,22 +83,43 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = {
|
||||
RK3066_PLL_RATE( 768000000, 1, 64, 2),
|
||||
RK3066_PLL_RATE( 742500000, 8, 495, 2),
|
||||
RK3066_PLL_RATE( 696000000, 1, 58, 2),
|
||||
+ RK3066_PLL_RATE_NB(621000000, 1, 207, 8, 1),
|
||||
RK3066_PLL_RATE( 600000000, 1, 50, 2),
|
||||
RK3066_PLL_RATE_NB(594000000, 1, 198, 8, 1),
|
||||
RK3066_PLL_RATE( 552000000, 1, 46, 2),
|
||||
RK3066_PLL_RATE( 504000000, 1, 84, 4),
|
||||
RK3066_PLL_RATE( 500000000, 3, 125, 2),
|
||||
RK3066_PLL_RATE( 456000000, 1, 76, 4),
|
||||
+ RK3066_PLL_RATE( 428000000, 1, 107, 6),
|
||||
RK3066_PLL_RATE( 408000000, 1, 68, 4),
|
||||
RK3066_PLL_RATE( 400000000, 3, 100, 2),
|
||||
+ RK3066_PLL_RATE_NB( 394000000, 1, 197, 12, 1),
|
||||
RK3066_PLL_RATE( 384000000, 2, 128, 4),
|
||||
RK3066_PLL_RATE( 360000000, 1, 60, 4),
|
||||
+ RK3066_PLL_RATE_NB( 356000000, 1, 178, 12, 1),
|
||||
+ RK3066_PLL_RATE_NB( 324000000, 1, 189, 14, 1),
|
||||
RK3066_PLL_RATE( 312000000, 1, 52, 4),
|
||||
- RK3066_PLL_RATE( 300000000, 1, 50, 4),
|
||||
- RK3066_PLL_RATE( 297000000, 2, 198, 8),
|
||||
+ RK3066_PLL_RATE_NB( 308000000, 1, 154, 12, 1),
|
||||
+ RK3066_PLL_RATE_NB( 303000000, 1, 202, 16, 1),
|
||||
+ RK3066_PLL_RATE( 300000000, 1, 75, 6),
|
||||
+ RK3066_PLL_RATE_NB( 297750000, 2, 397, 16, 1),
|
||||
+ RK3066_PLL_RATE_NB( 293250000, 2, 391, 16, 1),
|
||||
+ RK3066_PLL_RATE_NB( 292500000, 1, 195, 16, 1),
|
||||
+ RK3066_PLL_RATE( 273600000, 1, 114, 10),
|
||||
+ RK3066_PLL_RATE_NB( 273000000, 1, 182, 16, 1),
|
||||
+ RK3066_PLL_RATE_NB( 270000000, 1, 180, 16, 1),
|
||||
+ RK3066_PLL_RATE_NB( 266250000, 2, 355, 16, 1),
|
||||
+ RK3066_PLL_RATE_NB( 256500000, 1, 171, 16, 1),
|
||||
RK3066_PLL_RATE( 252000000, 1, 84, 8),
|
||||
- RK3066_PLL_RATE( 216000000, 1, 72, 8),
|
||||
- RK3066_PLL_RATE( 148500000, 2, 99, 8),
|
||||
+ RK3066_PLL_RATE_NB( 250500000, 1, 167, 16, 1),
|
||||
+ RK3066_PLL_RATE_NB( 243428571, 1, 142, 14, 1),
|
||||
+ RK3066_PLL_RATE( 238000000, 1, 119, 12),
|
||||
+ RK3066_PLL_RATE_NB( 219750000, 2, 293, 16, 1),
|
||||
+ RK3066_PLL_RATE_NB( 216000000, 1, 144, 16, 1),
|
||||
+ RK3066_PLL_RATE_NB( 213000000, 1, 142, 16, 1),
|
||||
+ RK3066_PLL_RATE( 195428571, 1, 114, 14),
|
||||
+ RK3066_PLL_RATE( 160000000, 1, 80, 12),
|
||||
+ RK3066_PLL_RATE( 157500000, 1, 105, 16),
|
||||
RK3066_PLL_RATE( 126000000, 1, 84, 16),
|
||||
RK3066_PLL_RATE( 48000000, 1, 64, 32),
|
||||
{ /* sentinel */ },
|
||||
@@ -177,10 +198,14 @@ PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" };
|
||||
PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
|
||||
|
||||
PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
|
||||
-PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
|
||||
-PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" };
|
||||
+PNAME_ED(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
|
||||
+
|
||||
+PNAME_ED(mux_pll_src_cgn_pll_nonvop_p) = { "cpll", "gpll", "npll" };
|
||||
+PNAME_ED(mux_pll_src_cgn_pll_vop0_p) = { "cpll", "gpll", "npll" };
|
||||
+PNAME_ED(mux_pll_src_cgn_pll_vop1_p) = { "cpll", "gpll", "npll" };
|
||||
+
|
||||
PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" };
|
||||
-PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" };
|
||||
+PNAME_ED(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" };
|
||||
|
||||
PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" };
|
||||
PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
|
||||
@@ -426,24 +451,24 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
RK3288_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 4, GFLAGS),
|
||||
|
||||
- COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cgn_pll_vop0_p, 0,
|
||||
RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 1, GFLAGS),
|
||||
- COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cgn_pll_vop1_p, 0,
|
||||
RK3288_CLKSEL_CON(29), 6, 2, MFLAGS, 8, 8, DFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 3, GFLAGS),
|
||||
|
||||
COMPOSITE_NODIV(SCLK_EDP_24M, "sclk_edp_24m", mux_edp_24m_p, 0,
|
||||
RK3288_CLKSEL_CON(28), 15, 1, MFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 12, GFLAGS),
|
||||
- COMPOSITE(SCLK_EDP, "sclk_edp", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(SCLK_EDP, "sclk_edp", mux_pll_src_cgn_pll_nonvop_p, 0,
|
||||
RK3288_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 6, DFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 13, GFLAGS),
|
||||
|
||||
- COMPOSITE(SCLK_ISP, "sclk_isp", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(SCLK_ISP, "sclk_isp", mux_pll_src_cgn_pll_nonvop_p, 0,
|
||||
RK3288_CLKSEL_CON(6), 6, 2, MFLAGS, 0, 6, DFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 14, GFLAGS),
|
||||
- COMPOSITE(SCLK_ISP_JPE, "sclk_isp_jpe", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(SCLK_ISP_JPE, "sclk_isp_jpe", mux_pll_src_cgn_pll_nonvop_p, 0,
|
||||
RK3288_CLKSEL_CON(6), 14, 2, MFLAGS, 8, 6, DFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 15, GFLAGS),
|
||||
|
||||
@@ -452,16 +477,16 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
GATE(SCLK_HDMI_CEC, "sclk_hdmi_cec", "xin32k", 0,
|
||||
RK3288_CLKGATE_CON(5), 11, GFLAGS),
|
||||
|
||||
- COMPOSITE(ACLK_HEVC, "aclk_hevc", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(ACLK_HEVC, "aclk_hevc", mux_pll_src_cgn_pll_nonvop_p, 0,
|
||||
RK3288_CLKSEL_CON(39), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3288_CLKGATE_CON(13), 13, GFLAGS),
|
||||
DIV(HCLK_HEVC, "hclk_hevc", "aclk_hevc", 0,
|
||||
RK3288_CLKSEL_CON(40), 12, 2, DFLAGS),
|
||||
|
||||
- COMPOSITE(SCLK_HEVC_CABAC, "sclk_hevc_cabac", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(SCLK_HEVC_CABAC, "sclk_hevc_cabac", mux_pll_src_cgn_pll_nonvop_p, 0,
|
||||
RK3288_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3288_CLKGATE_CON(13), 14, GFLAGS),
|
||||
- COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_cgn_pll_nonvop_p, 0,
|
||||
RK3288_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3288_CLKGATE_CON(13), 15, GFLAGS),
|
||||
|
||||
@@ -535,7 +560,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
COMPOSITE(0, "sclk_tspout", mux_tspout_p, 0,
|
||||
RK3288_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3288_CLKGATE_CON(4), 11, GFLAGS),
|
||||
- COMPOSITE(0, "sclk_tsp", mux_pll_src_cpll_gpll_npll_p, 0,
|
||||
+ COMPOSITE(0, "sclk_tsp", mux_pll_src_cgn_pll_nonvop_p, 0,
|
||||
RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3288_CLKGATE_CON(4), 10, GFLAGS),
|
||||
|
||||
@@ -895,6 +920,7 @@ static void __init rk3288_clk_init(struct device_node *np)
|
||||
{
|
||||
struct rockchip_clk_provider *ctx;
|
||||
struct clk *clk;
|
||||
+ s32 npll_vop = -1;
|
||||
|
||||
rk3288_cru_base = of_iomap(np, 0);
|
||||
if (!rk3288_cru_base) {
|
||||
@@ -902,6 +928,46 @@ static void __init rk3288_clk_init(struct device_node *np)
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (!of_property_read_s32(np, "rockchip,npll-for-vop", &npll_vop)) {
|
||||
+ if ((npll_vop < -1) || (npll_vop > 1)) {
|
||||
+ pr_warn("%s: invalid VOP to dedicate NPLL to: %d\n",
|
||||
+ __func__, npll_vop);
|
||||
+ } else if (npll_vop >= 0) {
|
||||
+ unsigned int vop_clk_id;
|
||||
+ const char ** npll_names;
|
||||
+ const char ** non_npll_names;
|
||||
+ int i;
|
||||
+
|
||||
+ /* Firstly, not-VOP needs to not use npll */
|
||||
+ mux_pll_src_npll_cpll_gpll_p[0] = "dummy_npll";
|
||||
+ mux_pll_src_cgn_pll_nonvop_p[2] = "dummy_npll";
|
||||
+ mux_pll_src_cpll_gll_usb_npll_p[3] = "dummy_npll";
|
||||
+
|
||||
+ /* Then the npll VOP needs to only use npll, and the other one not use npll. */
|
||||
+ if (npll_vop) {
|
||||
+ vop_clk_id = DCLK_VOP1;
|
||||
+ npll_names = mux_pll_src_cgn_pll_vop1_p;
|
||||
+ non_npll_names = mux_pll_src_cgn_pll_vop0_p;
|
||||
+ } else {
|
||||
+ vop_clk_id = DCLK_VOP0;
|
||||
+ npll_names = mux_pll_src_cgn_pll_vop0_p;
|
||||
+ non_npll_names = mux_pll_src_cgn_pll_vop1_p;
|
||||
+ }
|
||||
+ npll_names[0] = "dummy_cpll";
|
||||
+ npll_names[1] = "dummy_gpll";
|
||||
+ non_npll_names[2] = "dummy_npll";
|
||||
+
|
||||
+ /* Lastly the npll-dedicated-VOP needs to be able to control npll. */
|
||||
+ for (i = 0; i < ARRAY_SIZE(rk3288_clk_branches); i++) {
|
||||
+ if (rk3288_clk_branches[i].id == vop_clk_id) {
|
||||
+ rk3288_clk_branches[i].flags |= CLK_SET_RATE_PARENT;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ pr_debug("%s: npll dedicated for VOP %d\n", __func__, npll_vop);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ctx = rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS);
|
||||
if (IS_ERR(ctx)) {
|
||||
pr_err("%s: rockchip clk init failed\n", __func__);
|
||||
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
|
||||
index ef601dded32c..8e2f70d62f03 100644
|
||||
--- a/drivers/clk/rockchip/clk.h
|
||||
+++ b/drivers/clk/rockchip/clk.h
|
||||
@@ -343,6 +343,9 @@ struct clk *rockchip_clk_register_muxgrf(const char *name,
|
||||
|
||||
#define PNAME(x) static const char *const x[] __initconst
|
||||
|
||||
+/* For when you want to be able to modify the pointers. */
|
||||
+#define PNAME_ED(x) static const char * x[] __initdata
|
||||
+
|
||||
enum rockchip_clk_branch_type {
|
||||
branch_composite,
|
||||
branch_mux,
|
||||
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
||||
index 11309a2a4e43..740b0aeea796 100644
|
||||
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
||||
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
||||
@@ -49,122 +49,141 @@ struct rockchip_hdmi {
|
||||
struct clk *vpll_clk;
|
||||
struct clk *grf_clk;
|
||||
struct dw_hdmi *hdmi;
|
||||
+ u32* rates;
|
||||
+ u32 rates_cnt;
|
||||
};
|
||||
|
||||
+#define CLK_SLOP(clk) ((clk) / 1000)
|
||||
+#define CLK_PLUS_SLOP(clk) ((clk) + CLK_SLOP(clk))
|
||||
+
|
||||
#define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x)
|
||||
|
||||
+/* These were the rates allowed by the driver before rates list in device tree,
|
||||
+ * so keep them around as a fallback */
|
||||
+static const u32 dw_hdmi_fallback_rates[] = {
|
||||
+ 27000000,
|
||||
+ 36000000,
|
||||
+ 40000000,
|
||||
+ 54000000,
|
||||
+ 65000000,
|
||||
+ 66000000,
|
||||
+ 74250000,
|
||||
+ 83500000,
|
||||
+ 106500000,
|
||||
+ 108000000,
|
||||
+ 146250000,
|
||||
+ 148500000
|
||||
+};
|
||||
+
|
||||
static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
|
||||
{
|
||||
- 27000000, {
|
||||
- { 0x00b3, 0x0000},
|
||||
- { 0x2153, 0x0000},
|
||||
- { 0x40f3, 0x0000}
|
||||
+ 30666000, {
|
||||
+ { 0x00b3, 0x0000 },
|
||||
+ { 0x2153, 0x0000 },
|
||||
+ { 0x40f3, 0x0000 },
|
||||
+ },
|
||||
+ }, {
|
||||
+ 36800000, {
|
||||
+ { 0x00b3, 0x0000 },
|
||||
+ { 0x2153, 0x0000 },
|
||||
+ { 0x40a2, 0x0001 },
|
||||
},
|
||||
- }, {
|
||||
- 36000000, {
|
||||
- { 0x00b3, 0x0000},
|
||||
- { 0x2153, 0x0000},
|
||||
- { 0x40f3, 0x0000}
|
||||
+ }, {
|
||||
+ 46000000, {
|
||||
+ { 0x00b3, 0x0000 },
|
||||
+ { 0x2142, 0x0001 },
|
||||
+ { 0x40a2, 0x0001 },
|
||||
},
|
||||
- }, {
|
||||
- 40000000, {
|
||||
- { 0x00b3, 0x0000},
|
||||
- { 0x2153, 0x0000},
|
||||
- { 0x40f3, 0x0000}
|
||||
+ }, {
|
||||
+ 61333000, {
|
||||
+ { 0x0072, 0x0001 },
|
||||
+ { 0x2142, 0x0001 },
|
||||
+ { 0x40a2, 0x0001 },
|
||||
},
|
||||
- }, {
|
||||
- 54000000, {
|
||||
- { 0x0072, 0x0001},
|
||||
- { 0x2142, 0x0001},
|
||||
- { 0x40a2, 0x0001},
|
||||
+ }, {
|
||||
+ 73600000, {
|
||||
+ { 0x0072, 0x0001 },
|
||||
+ { 0x2142, 0x0001 },
|
||||
+ { 0x4061, 0x0002 },
|
||||
},
|
||||
- }, {
|
||||
- 65000000, {
|
||||
- { 0x0072, 0x0001},
|
||||
- { 0x2142, 0x0001},
|
||||
- { 0x40a2, 0x0001},
|
||||
+ }, {
|
||||
+ 92000000, {
|
||||
+ { 0x0072, 0x0001 },
|
||||
+ { 0x2145, 0x0002 },
|
||||
+ { 0x4061, 0x0002 },
|
||||
},
|
||||
- }, {
|
||||
- 66000000, {
|
||||
- { 0x013e, 0x0003},
|
||||
- { 0x217e, 0x0002},
|
||||
- { 0x4061, 0x0002}
|
||||
+ }, {
|
||||
+ 122666000, {
|
||||
+ { 0x0051, 0x0002 },
|
||||
+ { 0x2145, 0x0002 },
|
||||
+ { 0x4061, 0x0002 },
|
||||
},
|
||||
- }, {
|
||||
- 74250000, {
|
||||
- { 0x0072, 0x0001},
|
||||
- { 0x2145, 0x0002},
|
||||
- { 0x4061, 0x0002}
|
||||
+ }, {
|
||||
+ 147200000, {
|
||||
+ { 0x0051, 0x0002 },
|
||||
+ { 0x2145, 0x0002 },
|
||||
+ { 0x4064, 0x0003 },
|
||||
},
|
||||
- }, {
|
||||
- 83500000, {
|
||||
- { 0x0072, 0x0001},
|
||||
+ }, {
|
||||
+ 184000000, {
|
||||
+ { 0x0051, 0x0002 },
|
||||
+ { 0x214c, 0x0003 },
|
||||
+ { 0x4064, 0x0003 },
|
||||
},
|
||||
- }, {
|
||||
- 108000000, {
|
||||
- { 0x0051, 0x0002},
|
||||
- { 0x2145, 0x0002},
|
||||
- { 0x4061, 0x0002}
|
||||
+ }, {
|
||||
+ 226666000, {
|
||||
+ { 0x0040, 0x0003 },
|
||||
+ { 0x214c, 0x0003 },
|
||||
+ { 0x4064, 0x0003 },
|
||||
},
|
||||
- }, {
|
||||
- 106500000, {
|
||||
- { 0x0051, 0x0002},
|
||||
- { 0x2145, 0x0002},
|
||||
- { 0x4061, 0x0002}
|
||||
+ }, {
|
||||
+ 272000000, {
|
||||
+ { 0x0040, 0x0003 },
|
||||
+ { 0x214c, 0x0003 },
|
||||
+ { 0x5a64, 0x0003 },
|
||||
},
|
||||
- }, {
|
||||
- 146250000, {
|
||||
- { 0x0051, 0x0002},
|
||||
- { 0x2145, 0x0002},
|
||||
- { 0x4061, 0x0002}
|
||||
+ }, {
|
||||
+ 340000000, {
|
||||
+ { 0x0040, 0x0003 },
|
||||
+ { 0x3b4c, 0x0003 },
|
||||
+ { 0x5a64, 0x0003 },
|
||||
},
|
||||
- }, {
|
||||
- 148500000, {
|
||||
- { 0x0051, 0x0003},
|
||||
- { 0x214c, 0x0003},
|
||||
- { 0x4064, 0x0003}
|
||||
+ }, {
|
||||
+ 600000000, {
|
||||
+ { 0x1a40, 0x0003 },
|
||||
+ { 0x3b4c, 0x0003 },
|
||||
+ { 0x5a64, 0x0003 },
|
||||
},
|
||||
- }, {
|
||||
+ }, {
|
||||
~0UL, {
|
||||
- { 0x00a0, 0x000a },
|
||||
- { 0x2001, 0x000f },
|
||||
- { 0x4002, 0x000f },
|
||||
+ { 0x0000, 0x0000 },
|
||||
+ { 0x0000, 0x0000 },
|
||||
+ { 0x0000, 0x0000 },
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
|
||||
- /* pixelclk bpp8 bpp10 bpp12 */
|
||||
+ /* pixelclk bpp8 bpp10 bpp12 */
|
||||
{
|
||||
- 40000000, { 0x0018, 0x0018, 0x0018 },
|
||||
- }, {
|
||||
- 65000000, { 0x0028, 0x0028, 0x0028 },
|
||||
- }, {
|
||||
- 66000000, { 0x0038, 0x0038, 0x0038 },
|
||||
- }, {
|
||||
- 74250000, { 0x0028, 0x0038, 0x0038 },
|
||||
- }, {
|
||||
- 83500000, { 0x0028, 0x0038, 0x0038 },
|
||||
- }, {
|
||||
- 146250000, { 0x0038, 0x0038, 0x0038 },
|
||||
- }, {
|
||||
- 148500000, { 0x0000, 0x0038, 0x0038 },
|
||||
- }, {
|
||||
- ~0UL, { 0x0000, 0x0000, 0x0000},
|
||||
- }
|
||||
+ 600000000, { 0x0000, 0x0000, 0x0000 },
|
||||
+ }, {
|
||||
+ ~0UL, { 0x0000, 0x0000, 0x0000 },
|
||||
+ },
|
||||
};
|
||||
|
||||
static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
|
||||
/*pixelclk symbol term vlev*/
|
||||
- { 74250000, 0x8009, 0x0004, 0x0272},
|
||||
- { 148500000, 0x802b, 0x0004, 0x028d},
|
||||
- { 297000000, 0x8039, 0x0005, 0x028d},
|
||||
- { ~0UL, 0x0000, 0x0000, 0x0000}
|
||||
+ { CLK_PLUS_SLOP(74250000), 0x8009, 0x0004, 0x0272},
|
||||
+ { CLK_PLUS_SLOP(165000000), 0x802b, 0x0004, 0x0209},
|
||||
+ { CLK_PLUS_SLOP(297000000), 0x8039, 0x0005, 0x028d},
|
||||
+ { ~0UL, 0x0000, 0x0000, 0x0000}
|
||||
};
|
||||
|
||||
static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
|
||||
{
|
||||
struct device_node *np = hdmi->dev->of_node;
|
||||
+ int rates_cnt;
|
||||
|
||||
hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
|
||||
if (IS_ERR(hdmi->regmap)) {
|
||||
@@ -192,26 +211,55 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
|
||||
return PTR_ERR(hdmi->grf_clk);
|
||||
}
|
||||
|
||||
+ if ((rates_cnt = of_property_count_u32_elems(np, "rockchip,hdmi-rates-hz")) > 0) {
|
||||
+ int rv;
|
||||
+ u32 *rates = devm_kmalloc_array(hdmi->dev, rates_cnt, sizeof(u32), GFP_KERNEL);
|
||||
+ if (!rates)
|
||||
+ return -ENOMEM;
|
||||
+ rv = of_property_read_u32_array(np, "rockchip,hdmi-rates-hz", rates, rates_cnt);
|
||||
+ if (rv)
|
||||
+ return rv;
|
||||
+ hdmi->rates = rates;
|
||||
+ hdmi->rates_cnt = rates_cnt;
|
||||
+ } else {
|
||||
+ rates_cnt = ARRAY_SIZE(dw_hdmi_fallback_rates);
|
||||
+ hdmi->rates = devm_kmalloc_array(hdmi->dev, rates_cnt, sizeof(u32), GFP_KERNEL);
|
||||
+ if (!hdmi->rates)
|
||||
+ return -ENOMEM;
|
||||
+ memcpy(hdmi->rates, dw_hdmi_fallback_rates, rates_cnt * sizeof(u32));
|
||||
+ hdmi->rates_cnt = rates_cnt;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
-dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
|
||||
+dw_hdmi_rockchip_encoder_mode_valid(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
- const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
|
||||
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
|
||||
int pclk = mode->clock * 1000;
|
||||
- bool valid = false;
|
||||
+ int num_rates = hdmi->rates_cnt;
|
||||
int i;
|
||||
|
||||
- for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
|
||||
- if (pclk == mpll_cfg[i].mpixelclock) {
|
||||
- valid = true;
|
||||
- break;
|
||||
- }
|
||||
+ /*
|
||||
+ * Pixel clocks we support are always < 2GHz and so fit in an
|
||||
+ * int. We should make sure source rate does too so we don't get
|
||||
+ * overflow when we multiply by 1000.
|
||||
+ */
|
||||
+ if (mode->clock > INT_MAX / 1000)
|
||||
+ return MODE_BAD;
|
||||
+
|
||||
+ for (i = 0; i < num_rates; i++) {
|
||||
+ int slop = CLK_SLOP(pclk);
|
||||
+
|
||||
+ if ((pclk >= hdmi->rates[i] - slop) &&
|
||||
+ (pclk <= hdmi->rates[i] + slop))
|
||||
+ return MODE_OK;
|
||||
}
|
||||
|
||||
- return (valid) ? MODE_OK : MODE_BAD;
|
||||
+ return MODE_BAD;
|
||||
}
|
||||
|
||||
static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
|
||||
@@ -227,7 +275,39 @@ dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adj_mode)
|
||||
{
|
||||
- return true;
|
||||
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
|
||||
+ int pclk = adj_mode->clock * 1000;
|
||||
+ int best_diff = INT_MAX;
|
||||
+ int best_clock = 0;
|
||||
+ int slop;
|
||||
+ int i;
|
||||
+
|
||||
+ /* Pick the best clock */
|
||||
+ for (i = 0; i < hdmi->rates_cnt; i++) {
|
||||
+ int diff = hdmi->rates[i] - pclk;
|
||||
+
|
||||
+ if (diff < 0)
|
||||
+ diff = -diff;
|
||||
+ if (diff < best_diff) {
|
||||
+ best_diff = diff;
|
||||
+ best_clock = hdmi->rates[i];
|
||||
+
|
||||
+ /* Bail early if we're exact */
|
||||
+ if (best_diff == 0)
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Double check that it's OK */
|
||||
+ slop = CLK_SLOP(pclk);
|
||||
+ if ((pclk >= best_clock - slop) && (pclk <= best_clock + slop)) {
|
||||
+ adj_mode->clock = DIV_ROUND_UP(best_clock, 1000);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ /* Shoudn't be here; we should have said rate wasn't valid */
|
||||
+ dev_warn(hdmi->dev, "tried to set invalid rate %d\n", adj_mode->clock);
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
|
||||
@@ -280,6 +360,7 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
|
||||
+ .mode_valid = dw_hdmi_rockchip_encoder_mode_valid,
|
||||
.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
|
||||
.mode_set = dw_hdmi_rockchip_encoder_mode_set,
|
||||
.enable = dw_hdmi_rockchip_encoder_enable,
|
||||
@@ -294,7 +375,6 @@ static struct rockchip_hdmi_chip_data rk3288_chip_data = {
|
||||
};
|
||||
|
||||
static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
|
||||
- .mode_valid = dw_hdmi_rockchip_mode_valid,
|
||||
.mpll_cfg = rockchip_mpll_cfg,
|
||||
.cur_ctr = rockchip_cur_ctr,
|
||||
.phy_config = rockchip_phy_config,
|
||||
@@ -308,7 +388,6 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = {
|
||||
};
|
||||
|
||||
static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
|
||||
- .mode_valid = dw_hdmi_rockchip_mode_valid,
|
||||
.mpll_cfg = rockchip_mpll_cfg,
|
||||
.cur_ctr = rockchip_cur_ctr,
|
||||
.phy_config = rockchip_phy_config,
|
||||
@@ -387,6 +466,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
||||
*/
|
||||
if (IS_ERR(hdmi->hdmi)) {
|
||||
ret = PTR_ERR(hdmi->hdmi);
|
||||
+ devm_kfree(hdmi->dev, hdmi->rates);
|
||||
drm_encoder_cleanup(encoder);
|
||||
clk_disable_unprepare(hdmi->vpll_clk);
|
||||
}
|
||||
@@ -399,6 +479,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
|
||||
{
|
||||
struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
+ devm_kfree(hdmi->dev, hdmi->rates);
|
||||
dw_hdmi_unbind(hdmi->hdmi);
|
||||
clk_disable_unprepare(hdmi->vpll_clk);
|
||||
}
|
||||
--
|
||||
2.18.0
|
||||
|
@ -1,27 +0,0 @@
|
||||
From ac220d592aa38b9b717d36f7bb93f7be5a08f6b3 Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Thu, 19 Oct 2017 21:43:51 +0200
|
||||
Subject: [PATCH 14/28] ARM: DTSI: rk3288.dtsi: Adding missing EDP power domain
|
||||
|
||||
Imported from Rockchip 4.4 kernel patches.
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
arch/arm/boot/dts/rk3288.dtsi | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
|
||||
index 14ef8202..10ecebb4 100644
|
||||
--- a/arch/arm/boot/dts/rk3288.dtsi
|
||||
+++ b/arch/arm/boot/dts/rk3288.dtsi
|
||||
@@ -1105,6 +1105,7 @@
|
||||
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
|
||||
clock-names = "dp", "pclk";
|
||||
+ power-domains = <&power RK3288_PD_VIO>;
|
||||
phys = <&edp_phy>;
|
||||
phy-names = "dp";
|
||||
resets = <&cru SRST_EDP>;
|
||||
--
|
||||
2.11.0
|
||||
|
@ -1,28 +0,0 @@
|
||||
From c5af6798c9a411b3f550f463182a4b4904a21ec2 Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Thu, 19 Oct 2017 21:51:14 +0200
|
||||
Subject: [PATCH 16/28] ARM: DTSI: rk3288.dtsi: Adding missing VOPB registers
|
||||
|
||||
Imported from @wzyy2 patches... I think...
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
arch/arm/boot/dts/rk3288.dtsi | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
|
||||
index 455446f6..125f8835 100644
|
||||
--- a/arch/arm/boot/dts/rk3288.dtsi
|
||||
+++ b/arch/arm/boot/dts/rk3288.dtsi
|
||||
@@ -987,7 +987,7 @@
|
||||
|
||||
vopb: vop@ff930000 {
|
||||
compatible = "rockchip,rk3288-vop";
|
||||
- reg = <0x0 0xff930000 0x0 0x19c>;
|
||||
+ reg = <0x0 0xff930000 0x0 0x19c>, <0x0 0xff931000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>;
|
||||
clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
|
||||
--
|
||||
2.11.0
|
||||
|
@ -1,31 +0,0 @@
|
||||
From a0602b2724893de7ac9b4190a7a6bb66458da2d5 Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Thu, 19 Oct 2017 21:54:37 +0200
|
||||
Subject: [PATCH 17/28] ARM: DTSI: rk3288.dtsi: Fixed the SPDIF node address
|
||||
|
||||
Now, the typo is only in the name of the node itself, not in the
|
||||
actual registers addresses definition.
|
||||
|
||||
Still, this ought to be fixed one day !
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
arch/arm/boot/dts/rk3288.dtsi | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
|
||||
index 125f8835..e5d3d3c9 100644
|
||||
--- a/arch/arm/boot/dts/rk3288.dtsi
|
||||
+++ b/arch/arm/boot/dts/rk3288.dtsi
|
||||
@@ -922,7 +922,7 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
- spdif: sound@ff88b0000 {
|
||||
+ spdif: sound@ff8b0000 {
|
||||
compatible = "rockchip,rk3288-spdif", "rockchip,rk3066-spdif";
|
||||
reg = <0x0 0xff8b0000 0x0 0x10000>;
|
||||
#sound-dai-cells = <0>;
|
||||
--
|
||||
2.11.0
|
||||
|
@ -1,107 +0,0 @@
|
||||
From f4480cb8198085607c15e523b49aa21bc38cf62c Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Tue, 21 Nov 2017 21:47:33 +0100
|
||||
Subject: [PATCH 1/5] ARM: DTSI: rk3288.dtsi: Define the VPU services
|
||||
|
||||
Still, you will need appropriate drivers to use them.
|
||||
|
||||
Contrary to the previous versions of this patch, these services are :
|
||||
* NOT enabled by default;
|
||||
* MUST be activated in each individual DTS;
|
||||
|
||||
I currently do not own enough RK3288 boards to ensure that the
|
||||
VPU and HEVC MMU + services can be activated without issues.
|
||||
|
||||
Still this patch does not generate issues like the previous one AND
|
||||
still enable these services on boot, when activated properly in
|
||||
individual DTS files.
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
arch/arm/boot/dts/rk3288.dtsi | 63 +++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 63 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
|
||||
index 30b04257..bc3601ac 100644
|
||||
--- a/arch/arm/boot/dts/rk3288.dtsi
|
||||
+++ b/arch/arm/boot/dts/rk3288.dtsi
|
||||
@@ -1182,6 +1182,27 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ vpu_service: vpu-service@ff9a0000 {
|
||||
+ compatible = "rockchip,vpu_service";
|
||||
+ reg = <0x0 0xff9a0000 0x0 0x800>;
|
||||
+ interrupts =
|
||||
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "irq_enc", "irq_dec";
|
||||
+ clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
|
||||
+ clock-names = "aclk_vcodec", "hclk_vcodec";
|
||||
+ power-domains = <&power RK3288_PD_VIDEO>;
|
||||
+ rockchip,grf = <&grf>;
|
||||
+ resets = <&cru SRST_VCODEC_AXI>, <&cru SRST_VCODEC_AHB>;
|
||||
+ reset-names = "video_a", "video_h";
|
||||
+ iommus = <&vpu_mmu>;
|
||||
+ iommu_enabled = <1>;
|
||||
+ dev_mode = <0>;
|
||||
+ status = "disabled";
|
||||
+ /* 0 means ion, 1 means drm */
|
||||
+ allocator = <1>;
|
||||
+ };
|
||||
+
|
||||
hevc_mmu: iommu@ff9c0440 {
|
||||
compatible = "rockchip,iommu";
|
||||
reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0 0x40>;
|
||||
@@ -1191,6 +1212,48 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ hevc_service: hevc-service@ff9c0000 {
|
||||
+ compatible = "rockchip,hevc_service";
|
||||
+ reg = <0x0 0xff9c0000 0x0 0x400>;
|
||||
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "irq_dec";
|
||||
+ clocks =
|
||||
+ <&cru ACLK_HEVC>,
|
||||
+ <&cru HCLK_HEVC>,
|
||||
+ <&cru SCLK_HEVC_CORE>,
|
||||
+ <&cru SCLK_HEVC_CABAC>;
|
||||
+ clock-names =
|
||||
+ "aclk_vcodec",
|
||||
+ "hclk_vcodec",
|
||||
+ "clk_core",
|
||||
+ "clk_cabac";
|
||||
+ /*
|
||||
+ * The 4K hevc would also work well with 500/125/300/300,
|
||||
+ * no more err irq and reset request.
|
||||
+ */
|
||||
+ assigned-clocks =
|
||||
+ <&cru ACLK_HEVC>,
|
||||
+ <&cru HCLK_HEVC>,
|
||||
+ <&cru SCLK_HEVC_CORE>,
|
||||
+ <&cru SCLK_HEVC_CABAC>;
|
||||
+ assigned-clock-rates =
|
||||
+ <400000000>,
|
||||
+ <100000000>,
|
||||
+ <300000000>,
|
||||
+ <300000000>;
|
||||
+
|
||||
+ resets = <&cru SRST_HEVC>;
|
||||
+ reset-names = "video";
|
||||
+ power-domains = <&power RK3288_PD_HEVC>;
|
||||
+ rockchip,grf = <&grf>;
|
||||
+ dev_mode = <1>;
|
||||
+ iommus = <&hevc_mmu>;
|
||||
+ iommu_enabled = <1>;
|
||||
+ status = "disabled";
|
||||
+ /* 0 means ion, 1 means drm */
|
||||
+ allocator = <1>;
|
||||
+ };
|
||||
+
|
||||
gpu: gpu@ffa30000 {
|
||||
compatible = "rockchip,rk3288-mali", "arm,mali-t760";
|
||||
reg = <0x0 0xffa30000 0x0 0x10000>;
|
||||
--
|
||||
2.14.1
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 4766516bcbf023813ad883c2d61c422316770d12 Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Tue, 21 Nov 2017 21:58:22 +0100
|
||||
Subject: [PATCH 5/5] ARM: DTSI: rk3288-veyron: Enable the Video encoding MMU
|
||||
and services
|
||||
|
||||
Enable the :
|
||||
* VPU MMU;
|
||||
* VPU Service;
|
||||
* HEVC MMU;
|
||||
* HEVC Service;
|
||||
for RK3288 Chromebook laptops.
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
arch/arm/boot/dts/rk3288-veyron.dtsi | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi
|
||||
index 6e5bd897..517b9242 100644
|
||||
--- a/arch/arm/boot/dts/rk3288-veyron.dtsi
|
||||
+++ b/arch/arm/boot/dts/rk3288-veyron.dtsi
|
||||
@@ -450,6 +450,22 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&vpu_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vpu_service {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hevc_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hevc_service {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&wdt {
|
||||
status = "okay";
|
||||
};
|
||||
--
|
||||
2.14.1
|
||||
|
@ -1,41 +0,0 @@
|
||||
From b82f540967f6a732a22bbd236457b864951aeda7 Mon Sep 17 00:00:00 2001
|
||||
From: Myy <myy@miouyouyou.fr>
|
||||
Date: Sun, 14 May 2017 10:13:26 +0000
|
||||
Subject: [PATCH] clk: rockchip: rk3288: prefer vdpu for vcodec clock source
|
||||
|
||||
Patch provided by Randy Li. The original commit message reads :
|
||||
|
||||
_______________
|
||||
The RK3288 CRU system clock solution would suggest use
|
||||
the vdpu clock source for the VPU(aclk_vpu and hclk_vpu).
|
||||
|
||||
Reading the registers of VPU(both VEPU and VDPU) would become all high
|
||||
when the vepu is used as the clock source. It may be a bug in the SoC,
|
||||
not sure whether it is fixed at RK3288W.
|
||||
|
||||
Signed-off-by: Randy Li <ayaka@soulik.info>
|
||||
_______________
|
||||
|
||||
This also resolves a freeze when loading the OOT Video Codec driver
|
||||
|
||||
Signed-off-by: Myy <myy@miouyouyou.fr>
|
||||
---
|
||||
drivers/clk/rockchip/clk-rk3288.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
|
||||
index 1227f74..f218256 100644
|
||||
--- a/drivers/clk/rockchip/clk-rk3288.c
|
||||
+++ b/drivers/clk/rockchip/clk-rk3288.c
|
||||
@@ -215,7 +215,7 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
|
||||
PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" };
|
||||
PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" };
|
||||
|
||||
-PNAME(mux_aclk_vcodec_pre_p) = { "aclk_vepu", "aclk_vdpu" };
|
||||
+PNAME(mux_aclk_vcodec_pre_p) = { "aclk_vdpu", "aclk_vepu" };
|
||||
PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m",
|
||||
"sclk_otgphy0_480m" };
|
||||
PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" };
|
||||
--
|
||||
2.10.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From c1c8509bb90f2b3ed046d99cf0fedbddc24290ec Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Thu, 3 May 2018 21:47:40 +0200
|
||||
Subject: [PATCH] drivers: drm: rockchip: Enable IRQ on unbind
|
||||
|
||||
Not doing this generate atrocious delays when plugging a screen,
|
||||
making the whole 3D stack unusable.
|
||||
|
||||
This is an adaptation of Jeffy Chen patch, originally provided
|
||||
here :
|
||||
http://lists.infradead.org/pipermail/linux-rockchip/2018-April/020427.html
|
||||
|
||||
Thanks to @JeffyCN for this patch.
|
||||
|
||||
This resolves issue #4
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
||||
index 53d4afe1..f903171a 100644
|
||||
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
||||
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
||||
@@ -1601,6 +1601,7 @@ static void vop_unbind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
struct vop *vop = dev_get_drvdata(dev);
|
||||
|
||||
+ enable_irq(vop->irq);
|
||||
pm_runtime_disable(dev);
|
||||
vop_destroy_crtc(vop);
|
||||
|
||||
--
|
||||
2.17.0
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 239a5e3016b7f676bc3f56ea509ed172bf954001 Mon Sep 17 00:00:00 2001
|
||||
From: Myy <myy@miouyouyou.fr>
|
||||
Date: Sat, 22 Jul 2017 04:07:36 +0000
|
||||
Subject: [PATCH] Remove the dependency to the clk_mali symbol.
|
||||
|
||||
Inspired by @wzzy2 patch
|
||||
|
||||
https://github.com/rockchip-linux/rockchip_forwardports/commit/359865c617129fe5fcc5530f4a88abcfaa6a5cb4
|
||||
|
||||
Signed-off-by: Myy <myy@miouyouyou.fr>
|
||||
---
|
||||
drivers/gpu/arm/midgard/mali_kbase_core_linux.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
|
||||
index 9cc65d2..27dcd9c 100644
|
||||
--- a/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
|
||||
+++ b/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
|
||||
@@ -3793,7 +3793,7 @@ static int power_control_init(struct platform_device *pdev)
|
||||
}
|
||||
#endif /* LINUX_VERSION_CODE >= 3, 12, 0 */
|
||||
|
||||
- kbdev->clock = clk_get(kbdev->dev, "clk_mali");
|
||||
+ kbdev->clock = of_clk_get(kbdev->dev->of_node, 0);
|
||||
if (IS_ERR_OR_NULL(kbdev->clock)) {
|
||||
err = PTR_ERR(kbdev->clock);
|
||||
kbdev->clock = NULL;
|
||||
--
|
||||
2.10.2
|
||||
|
@ -1,82 +0,0 @@
|
||||
From 4ffe79de7272234408a9179aa4c403ee1b67a362 Mon Sep 17 00:00:00 2001
|
||||
From: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
Date: Thu, 7 Dec 2017 21:27:52 +0100
|
||||
Subject: [PATCH] soc: rockchip: power-domain: export idle request
|
||||
|
||||
We need to put the power status of HEVC/RKVDEC IP into IDLE
|
||||
unless we can't reset that IP or the SoC would crash down.
|
||||
rockchip_pmu_idle_request(dev, true)---> enter idle
|
||||
rockchip_pmu_idle_request(dev, false)---> exit idle
|
||||
|
||||
Only the video codec drivers of rockchip platform would
|
||||
request this patch currently.
|
||||
|
||||
I am not sure whether it is necessary to add a new function
|
||||
at generic power domain. I want someone give me some advises
|
||||
here.
|
||||
|
||||
Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
|
||||
---
|
||||
drivers/soc/rockchip/pm_domains.c | 23 +++++++++++++++++++++++
|
||||
include/linux/rockchip_pmu.h | 15 +++++++++++++++
|
||||
2 files changed, 38 insertions(+)
|
||||
create mode 100644 include/linux/rockchip_pmu.h
|
||||
|
||||
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
|
||||
index 40b75748..0006ed53 100644
|
||||
--- a/drivers/soc/rockchip/pm_domains.c
|
||||
+++ b/drivers/soc/rockchip/pm_domains.c
|
||||
@@ -180,6 +180,29 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int rockchip_pmu_idle_request(struct device *dev, bool idle)
|
||||
+{
|
||||
+ struct generic_pm_domain *genpd;
|
||||
+ struct rockchip_pm_domain *pd;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (IS_ERR_OR_NULL(dev))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (IS_ERR_OR_NULL(dev->pm_domain))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ genpd = pd_to_genpd(dev->pm_domain);
|
||||
+ pd = to_rockchip_pd(genpd);
|
||||
+
|
||||
+ mutex_lock(&pd->pmu->mutex);
|
||||
+ ret = rockchip_pmu_set_idle_request(pd, idle);
|
||||
+ mutex_unlock(&pd->pmu->mutex);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(rockchip_pmu_idle_request);
|
||||
+
|
||||
static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
|
||||
{
|
||||
int i;
|
||||
diff --git a/include/linux/rockchip_pmu.h b/include/linux/rockchip_pmu.h
|
||||
new file mode 100644
|
||||
index 00000000..720b3314
|
||||
--- /dev/null
|
||||
+++ b/include/linux/rockchip_pmu.h
|
||||
@@ -0,0 +1,15 @@
|
||||
+/*
|
||||
+ * pm_domain.h - Definitions and headers related to device power domains.
|
||||
+ *
|
||||
+ * Copyright (C) 2017 Randy Li <ayaka@soulik.info>.
|
||||
+ *
|
||||
+ * This file is released under the GPLv2.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LINUX_ROCKCHIP_PM_H
|
||||
+#define _LINUX_ROCKCHIP_PM_H
|
||||
+#include <linux/device.h>
|
||||
+
|
||||
+int rockchip_pmu_idle_request(struct device *dev, bool idle);
|
||||
+
|
||||
+#endif /* _LINUX_ROCKCHIP_PM_H */
|
||||
--
|
||||
2.14.1
|
||||
|
@ -53,9 +53,6 @@ make mrproper
|
||||
[ "$FRESH" = true ] && for i in $RESOURCES/patches-tested/DTS/5.x-dts/*.patch; do echo $i; patch -p1 < $i; done
|
||||
[ "$FRESH" = true ] && for i in $RESOURCES/patches-tested/DTS/*.patch; do echo $i; patch -p1 < $i; done
|
||||
[ "$FRESH" = true ] && for i in $RESOURCES/patches-tested/kernel/*.patch; do echo $i; patch -p1 < $i; done
|
||||
#Apply all of the rockMyy patches that make sense
|
||||
[ "$TEST_PATCHES" = true ] && for i in $RESOURCES/patches-untested/kernel/*.patch; do patch -p1 < $i; done
|
||||
[ "$TEST_PATCHES" = true ] && for i in $RESOURCES/patches-untested/DTS/*.patch; do patch -p1 < $i; done
|
||||
|
||||
#copy in the initramfs and kernel config
|
||||
cp $ROOT_DIR/build/PrawnOS-initramfs.cpio.gz .
|
||||
|
Loading…
Reference in New Issue
Block a user