diff --git a/resources/BuildResources/patches-untested/0004-fix-mvsdio-eMMC-timing.patch b/resources/BuildResources/patches-untested/0004-fix-mvsdio-eMMC-timing.patch deleted file mode 100644 index 4669a97..0000000 --- a/resources/BuildResources/patches-untested/0004-fix-mvsdio-eMMC-timing.patch +++ /dev/null @@ -1,38 +0,0 @@ -From bca0f6d98bb3003178d962f83ba795d524460346 Mon Sep 17 00:00:00 2001 -From: Kevin Mihelich -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 ---- - 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 - diff --git a/resources/BuildResources/patches-untested/0009-power-add-power-sequence-library.patch b/resources/BuildResources/patches-untested/0009-power-add-power-sequence-library.patch deleted file mode 100644 index c0da023..0000000 --- a/resources/BuildResources/patches-untested/0009-power-add-power-sequence-library.patch +++ /dev/null @@ -1,790 +0,0 @@ -From 4ddcbb9ed40c97371724245d0b8d01d471bb6570 Mon Sep 17 00:00:00 2001 -From: Peter Chen -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 -Tested-by: Maciej S. Szmigiero -Tested-by Joshua Clayton -Reviewed-by: Matthias Kaehlcke -Tested-by: Matthias Kaehlcke ---- - 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 -+ -+ -+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 -+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 - 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+ -+/* -+ * 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+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 -+ -+#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 - diff --git a/resources/BuildResources/patches-untested/0020-RK3288-HDMI-clock-hacks-combined.patch b/resources/BuildResources/patches-untested/0020-RK3288-HDMI-clock-hacks-combined.patch deleted file mode 100644 index b2c526c..0000000 --- a/resources/BuildResources/patches-untested/0020-RK3288-HDMI-clock-hacks-combined.patch +++ /dev/null @@ -1,733 +0,0 @@ -From aeb42ff3a2d04e19ff87b1e537e0d84d63132c11 Mon Sep 17 00:00:00 2001 -From: Urja Rannikko -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 ---- - .../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 - diff --git a/resources/BuildResources/patches-untested/DTS/0010-ARM-DTSI-rk3288-Adding-missing-EDP-power-domain.patch b/resources/BuildResources/patches-untested/DTS/0010-ARM-DTSI-rk3288-Adding-missing-EDP-power-domain.patch deleted file mode 100644 index 1ec2018..0000000 --- a/resources/BuildResources/patches-untested/DTS/0010-ARM-DTSI-rk3288-Adding-missing-EDP-power-domain.patch +++ /dev/null @@ -1,27 +0,0 @@ -From ac220d592aa38b9b717d36f7bb93f7be5a08f6b3 Mon Sep 17 00:00:00 2001 -From: Myy Miouyouyou -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 ---- - 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 = ; - 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 - diff --git a/resources/BuildResources/patches-untested/DTS/0011-ARM-DTSI-rk3288-Adding-missing-VOPB-registers.patch b/resources/BuildResources/patches-untested/DTS/0011-ARM-DTSI-rk3288-Adding-missing-VOPB-registers.patch deleted file mode 100644 index 888522c..0000000 --- a/resources/BuildResources/patches-untested/DTS/0011-ARM-DTSI-rk3288-Adding-missing-VOPB-registers.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c5af6798c9a411b3f550f463182a4b4904a21ec2 Mon Sep 17 00:00:00 2001 -From: Myy Miouyouyou -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 ---- - 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 = ; - clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>; - clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; --- -2.11.0 - diff --git a/resources/BuildResources/patches-untested/DTS/0012-ARM-DTSI-rk3288-Fixed-the-SPDIF-node-address.patch b/resources/BuildResources/patches-untested/DTS/0012-ARM-DTSI-rk3288-Fixed-the-SPDIF-node-address.patch deleted file mode 100644 index 2c791cb..0000000 --- a/resources/BuildResources/patches-untested/DTS/0012-ARM-DTSI-rk3288-Fixed-the-SPDIF-node-address.patch +++ /dev/null @@ -1,31 +0,0 @@ -From a0602b2724893de7ac9b4190a7a6bb66458da2d5 Mon Sep 17 00:00:00 2001 -From: Myy Miouyouyou -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 ---- - 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 - diff --git a/resources/BuildResources/patches-untested/DTS/for_video/0020-ARM-DTSI-rk3288-Define-the-VPU-services.patch b/resources/BuildResources/patches-untested/DTS/for_video/0020-ARM-DTSI-rk3288-Define-the-VPU-services.patch deleted file mode 100644 index cd10913..0000000 --- a/resources/BuildResources/patches-untested/DTS/for_video/0020-ARM-DTSI-rk3288-Define-the-VPU-services.patch +++ /dev/null @@ -1,107 +0,0 @@ -From f4480cb8198085607c15e523b49aa21bc38cf62c Mon Sep 17 00:00:00 2001 -From: Myy Miouyouyou -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 ---- - 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 = -+ , -+ ; -+ 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 = ; -+ 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 - diff --git a/resources/BuildResources/patches-untested/DTS/for_video/0024-ARM-DTSI-rk3288-veyron-Enable-the-Video-encoding-MMU.patch b/resources/BuildResources/patches-untested/DTS/for_video/0024-ARM-DTSI-rk3288-veyron-Enable-the-Video-encoding-MMU.patch deleted file mode 100644 index 31c1c5b..0000000 --- a/resources/BuildResources/patches-untested/DTS/for_video/0024-ARM-DTSI-rk3288-veyron-Enable-the-Video-encoding-MMU.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 4766516bcbf023813ad883c2d61c422316770d12 Mon Sep 17 00:00:00 2001 -From: Myy Miouyouyou -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 ---- - 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 - diff --git a/resources/BuildResources/patches-untested/kernel/0003-clk-rockchip-rk3288-prefer-vdpu-for-vcodec-clock-sou.patch b/resources/BuildResources/patches-untested/kernel/0003-clk-rockchip-rk3288-prefer-vdpu-for-vcodec-clock-sou.patch deleted file mode 100644 index a7e2038..0000000 --- a/resources/BuildResources/patches-untested/kernel/0003-clk-rockchip-rk3288-prefer-vdpu-for-vcodec-clock-sou.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b82f540967f6a732a22bbd236457b864951aeda7 Mon Sep 17 00:00:00 2001 -From: Myy -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 -_______________ - -This also resolves a freeze when loading the OOT Video Codec driver - -Signed-off-by: Myy ---- - 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 - diff --git a/resources/BuildResources/patches-untested/kernel/0007-drivers-drm-rockchip-Enable-IRQ-on-unbind.patch b/resources/BuildResources/patches-untested/kernel/0007-drivers-drm-rockchip-Enable-IRQ-on-unbind.patch deleted file mode 100644 index 4f889ae..0000000 --- a/resources/BuildResources/patches-untested/kernel/0007-drivers-drm-rockchip-Enable-IRQ-on-unbind.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c1c8509bb90f2b3ed046d99cf0fedbddc24290ec Mon Sep 17 00:00:00 2001 -From: Myy Miouyouyou -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 ---- - 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 - diff --git a/resources/BuildResources/patches-untested/kernel/for_video/0004-Remove-the-dependency-to-the-clk_mali-symbol.patch b/resources/BuildResources/patches-untested/kernel/for_video/0004-Remove-the-dependency-to-the-clk_mali-symbol.patch deleted file mode 100644 index 882e4fd..0000000 --- a/resources/BuildResources/patches-untested/kernel/for_video/0004-Remove-the-dependency-to-the-clk_mali-symbol.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 239a5e3016b7f676bc3f56ea509ed172bf954001 Mon Sep 17 00:00:00 2001 -From: Myy -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 ---- - 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 - diff --git a/resources/BuildResources/patches-untested/kernel/for_video/0006-soc-rockchip-power-domain-export-idle-request.patch b/resources/BuildResources/patches-untested/kernel/for_video/0006-soc-rockchip-power-domain-export-idle-request.patch deleted file mode 100644 index be15c35..0000000 --- a/resources/BuildResources/patches-untested/kernel/for_video/0006-soc-rockchip-power-domain-export-idle-request.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 4ffe79de7272234408a9179aa4c403ee1b67a362 Mon Sep 17 00:00:00 2001 -From: Myy Miouyouyou -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 ---- - 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 . -+ * -+ * This file is released under the GPLv2. -+ */ -+ -+#ifndef _LINUX_ROCKCHIP_PM_H -+#define _LINUX_ROCKCHIP_PM_H -+#include -+ -+int rockchip_pmu_idle_request(struct device *dev, bool idle); -+ -+#endif /* _LINUX_ROCKCHIP_PM_H */ --- -2.14.1 - diff --git a/scripts/buildKernel.sh b/scripts/buildKernel.sh index 93f6259..c811e2d 100755 --- a/scripts/buildKernel.sh +++ b/scripts/buildKernel.sh @@ -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 .