Attempt cm3588 support
This commit is contained in:
parent
626d2897a4
commit
ea66aa9554
atf.patches
feat-rk3588-support-rk3588.patchfeat-rockchip-support-SCMI-for-clock-reset-domain.patchrk3588-enable-crypto-function.patchrockchip-add-some-pm-helpers-functions.patch
boot.scrcmd
gokr-build-kernel
gokr-build-uboot
gokr-rebuild-kernel
gokr-rebuild-uboot
kernel.patches
0001-dt-bindings-arm-rockchip-Add-FriendlyElec-CM3588-NAS.patch0001-general-add-overlay-support.patch0002-arm64-dts-rockchip-Add-FriendlyElec-CM3588-NAS-board.patch0010-fix-clk-divisions.patch0011-irqchip-fix-its-timeout-issue.patch0012-fix-initial-PERST-GPIO-value.patch0022-RK3588-Add-Thermal-and-CpuFreq-Support.patch0024-RK3588-Add-Crypto-Support.patch0025-RK3588-Add-HW-RNG-Support.patch0026-RK3588-Add-VPU121-H.264-Decoder-Support.patch0027-RK3588-Add-rkvdec2-Support-v3.patch0028-media-v4l2-core-Initialize-h264-frame_mbs_only_flag-.patch0138-arm64-dts-rockchip-Add-HDMI0-bridge-to-rk3588.patch0139-arm64-dts-rockchip-Enable-HDMI0-PHY-clk-provider-on-.patch0144-phy-phy-rockchip-samsung-hdptx-Add-FRL-EARC-support.patch0145-phy-phy-rockchip-samsung-hdptx-Add-clock-provider.patch0146-drm-rockchip-vop2-Improve-display-modes-handling-on-.patch0147-arm64-dts-rockchip-rk3588-add-RGA2-node.patch0161-drm-bridge-synopsys-Add-initial-support-for-DW-HDMI-Controller.patch0162-drm-bridge-synopsys-Fix-HDMI-Controller.patch0170-drm-rockchip-vop2-add-clocks-reset-support.patch0801-wireless-add-bcm43752.patch0802-wireless-add-clk-property.patch1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch1011-board-rock-5b-arm64-dts-enable-spi-flash.patch1012-arm64-dts-rockchip-Enable-HDMI0-on-rock-5b.patch1014-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-rock5b.patch1015-board-rock5b-automatic-fan-control.patch1020-Add-HDMI-and-VOP2-to-Rock-5A.patch1021-arch-arm64-dts-enable-gpu-node-for-rock-5a.patch1021-arm64-dts-Add-missing-nodes-to-Orange-Pi-5-Plus.patch1023-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5a.patch1031-arm64-dts-rockchip-Add-HDMI-support-to-ArmSoM-Sige7.patch1032-arm64-dts-rockchip-Add-ap6275p-wireless-support-to-A.patch1040-board-khadas-edge2-add-nodes.patch1041-board-khadas-edge2-mcu.patch1051-arm64-dts-rockchip-Add-NanoPC-T6-SPI-Flash.patch
rk3328-rock64.dtbrk3588-friendlyelec-cm3588-nas.dtbu-boot-rockchip.binuboot.patches
vmlinuz
6516
atf.patches/feat-rk3588-support-rk3588.patch
Normal file
6516
atf.patches/feat-rk3588-support-rk3588.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,465 @@
|
||||
From 3bd5d90889173031e1a4177835225e3f9ffd6e49 Mon Sep 17 00:00:00 2001
|
||||
From: XiaoDong Huang <derrick.huang@rock-chips.com>
|
||||
Date: Sun, 25 Jun 2023 17:38:13 +0800
|
||||
Subject: [PATCH] feat(rockchip): support SCMI for clock/reset domain
|
||||
|
||||
Signed-off-by: XiaoDong Huang <derrick.huang@rock-chips.com>
|
||||
Change-Id: I5b983877a5b4e8acababbf7e0a3e2725e6479e08
|
||||
---
|
||||
|
||||
diff --git a/plat/rockchip/common/include/rockchip_sip_svc.h b/plat/rockchip/common/include/rockchip_sip_svc.h
|
||||
index 340d653..8836f9b 100644
|
||||
--- a/plat/rockchip/common/include/rockchip_sip_svc.h
|
||||
+++ b/plat/rockchip/common/include/rockchip_sip_svc.h
|
||||
@@ -11,6 +11,7 @@
|
||||
#define SIP_SVC_CALL_COUNT 0x8200ff00
|
||||
#define SIP_SVC_UID 0x8200ff01
|
||||
#define SIP_SVC_VERSION 0x8200ff03
|
||||
+#define RK_SIP_SCMI_AGENT0 0x82000010
|
||||
|
||||
/* rockchip SiP Service Calls version numbers */
|
||||
#define RK_SIP_SVC_VERSION_MAJOR 0x0
|
||||
diff --git a/plat/rockchip/common/scmi/scmi.c b/plat/rockchip/common/scmi/scmi.c
|
||||
new file mode 100644
|
||||
index 0000000..23ea991
|
||||
--- /dev/null
|
||||
+++ b/plat/rockchip/common/scmi/scmi.c
|
||||
@@ -0,0 +1,88 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#include <assert.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <plat_scmi_def.h>
|
||||
+
|
||||
+#include <drivers/scmi-msg.h>
|
||||
+#include <drivers/scmi.h>
|
||||
+#include <lib/utils.h>
|
||||
+#include <lib/utils_def.h>
|
||||
+
|
||||
+#define MAX_PROTOCOL_IN_LIST 8U
|
||||
+
|
||||
+static const char vendor[] = "rockchip";
|
||||
+static const char sub_vendor[] = "";
|
||||
+
|
||||
+#pragma weak rockchip_scmi_protocol_table
|
||||
+
|
||||
+const uint8_t rockchip_scmi_protocol_table[1][MAX_PROTOCOL_IN_LIST] = {
|
||||
+ { SCMI_PROTOCOL_ID_CLOCK,
|
||||
+ SCMI_PROTOCOL_ID_RESET_DOMAIN,
|
||||
+ 0
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+const char *plat_scmi_vendor_name(void)
|
||||
+{
|
||||
+ return vendor;
|
||||
+}
|
||||
+
|
||||
+const char *plat_scmi_sub_vendor_name(void)
|
||||
+{
|
||||
+ return sub_vendor;
|
||||
+}
|
||||
+
|
||||
+size_t plat_scmi_protocol_count(void)
|
||||
+{
|
||||
+ unsigned int count = 0U;
|
||||
+ const uint8_t *protocol_list = rockchip_scmi_protocol_table[0];
|
||||
+
|
||||
+ while (protocol_list[count])
|
||||
+ count++;
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id)
|
||||
+{
|
||||
+ assert(agent_id < ARRAY_SIZE(rockchip_scmi_protocol_table));
|
||||
+
|
||||
+ return rockchip_scmi_protocol_table[agent_id];
|
||||
+}
|
||||
+
|
||||
+static struct scmi_msg_channel scmi_channel[] = {
|
||||
+ [0] = {
|
||||
+ .shm_addr = SMT_BUFFER0_BASE,
|
||||
+ .shm_size = SMT_BUF_SLOT_SIZE,
|
||||
+ },
|
||||
+
|
||||
+#ifdef SMT_BUFFER1_BASE
|
||||
+ [1] = {
|
||||
+ .shm_addr = SMT_BUFFER1_BASE,
|
||||
+ .shm_size = SMT_BUF_SLOT_SIZE,
|
||||
+ },
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
|
||||
+{
|
||||
+ assert(agent_id < ARRAY_SIZE(scmi_channel));
|
||||
+
|
||||
+ return &scmi_channel[agent_id];
|
||||
+}
|
||||
+
|
||||
+#pragma weak rockchip_init_scmi_server
|
||||
+
|
||||
+void rockchip_init_scmi_server(void)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++)
|
||||
+ scmi_smt_init_agent_channel(&scmi_channel[i]);
|
||||
+}
|
||||
diff --git a/plat/rockchip/common/scmi/scmi_clock.c b/plat/rockchip/common/scmi/scmi_clock.c
|
||||
new file mode 100644
|
||||
index 0000000..4921d49
|
||||
--- /dev/null
|
||||
+++ b/plat/rockchip/common/scmi/scmi_clock.c
|
||||
@@ -0,0 +1,157 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#include <drivers/scmi-msg.h>
|
||||
+#include <drivers/scmi.h>
|
||||
+
|
||||
+#include "scmi_clock.h"
|
||||
+
|
||||
+#pragma weak rockchip_scmi_clock_count
|
||||
+#pragma weak rockchip_scmi_get_clock
|
||||
+
|
||||
+size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
|
||||
+ uint32_t scmi_id __unused)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+size_t plat_scmi_clock_count(unsigned int agent_id)
|
||||
+{
|
||||
+ return rockchip_scmi_clock_count(agent_id);
|
||||
+}
|
||||
+
|
||||
+const char *plat_scmi_clock_get_name(unsigned int agent_id,
|
||||
+ unsigned int scmi_id)
|
||||
+{
|
||||
+ rk_scmi_clock_t *clock;
|
||||
+
|
||||
+ clock = rockchip_scmi_get_clock(agent_id, scmi_id);
|
||||
+ if (clock == 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return clock->name;
|
||||
+}
|
||||
+
|
||||
+int32_t plat_scmi_clock_rates_array(unsigned int agent_id,
|
||||
+ unsigned int scmi_id,
|
||||
+ unsigned long *rates,
|
||||
+ size_t *nb_elts,
|
||||
+ uint32_t start_idx)
|
||||
+{
|
||||
+ uint32_t i;
|
||||
+ unsigned long *rate_table;
|
||||
+ rk_scmi_clock_t *clock;
|
||||
+
|
||||
+ clock = rockchip_scmi_get_clock(agent_id, scmi_id);
|
||||
+ if (clock == 0)
|
||||
+ return SCMI_NOT_FOUND;
|
||||
+
|
||||
+ rate_table = clock->rate_table;
|
||||
+ if (rate_table == 0)
|
||||
+ return SCMI_NOT_SUPPORTED;
|
||||
+
|
||||
+ if (rates == 0) {
|
||||
+ *nb_elts = clock->rate_cnt;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (start_idx + *nb_elts > clock->rate_cnt)
|
||||
+ return SCMI_OUT_OF_RANGE;
|
||||
+
|
||||
+ for (i = 0; i < *nb_elts; i++)
|
||||
+ rates[i] = rate_table[start_idx + i];
|
||||
+
|
||||
+out:
|
||||
+ return SCMI_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused,
|
||||
+ unsigned int scmi_id __unused,
|
||||
+ unsigned long *steps __unused)
|
||||
+{
|
||||
+ return SCMI_NOT_SUPPORTED;
|
||||
+}
|
||||
+
|
||||
+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
|
||||
+ unsigned int scmi_id)
|
||||
+{
|
||||
+ rk_scmi_clock_t *clock;
|
||||
+ unsigned long rate = 0;
|
||||
+
|
||||
+ clock = rockchip_scmi_get_clock(agent_id, scmi_id);
|
||||
+ if (clock == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (clock->clk_ops && clock->clk_ops->get_rate)
|
||||
+ rate = clock->clk_ops->get_rate(clock);
|
||||
+
|
||||
+ /* return cur_rate if no get_rate ops or get_rate return 0 */
|
||||
+ if (rate == 0)
|
||||
+ rate = clock->cur_rate;
|
||||
+
|
||||
+ return rate;
|
||||
+}
|
||||
+
|
||||
+int32_t plat_scmi_clock_set_rate(unsigned int agent_id,
|
||||
+ unsigned int scmi_id,
|
||||
+ unsigned long rate)
|
||||
+{
|
||||
+ rk_scmi_clock_t *clock;
|
||||
+ int32_t status = 0;
|
||||
+
|
||||
+ clock = rockchip_scmi_get_clock(agent_id, scmi_id);
|
||||
+ if (clock == 0)
|
||||
+ return SCMI_NOT_FOUND;
|
||||
+
|
||||
+ if (clock->clk_ops && clock->clk_ops->set_rate) {
|
||||
+ status = clock->clk_ops->set_rate(clock, rate);
|
||||
+ if (status == SCMI_SUCCESS)
|
||||
+ clock->cur_rate = rate;
|
||||
+ } else {
|
||||
+ status = SCMI_NOT_SUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+int32_t plat_scmi_clock_get_state(unsigned int agent_id,
|
||||
+ unsigned int scmi_id)
|
||||
+{
|
||||
+ rk_scmi_clock_t *clock;
|
||||
+
|
||||
+ clock = rockchip_scmi_get_clock(agent_id, scmi_id);
|
||||
+ if (clock == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ return clock->enable;
|
||||
+}
|
||||
+
|
||||
+int32_t plat_scmi_clock_set_state(unsigned int agent_id,
|
||||
+ unsigned int scmi_id,
|
||||
+ bool enable_not_disable)
|
||||
+{
|
||||
+ rk_scmi_clock_t *clock;
|
||||
+ int32_t status = 0;
|
||||
+
|
||||
+ clock = rockchip_scmi_get_clock(agent_id, scmi_id);
|
||||
+ if (clock == 0)
|
||||
+ return SCMI_NOT_FOUND;
|
||||
+
|
||||
+ if (clock->clk_ops && clock->clk_ops->set_status) {
|
||||
+ status = clock->clk_ops->set_status(clock, enable_not_disable);
|
||||
+ if (status == SCMI_SUCCESS)
|
||||
+ clock->enable = enable_not_disable;
|
||||
+ } else {
|
||||
+ status = SCMI_NOT_SUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
diff --git a/plat/rockchip/common/scmi/scmi_clock.h b/plat/rockchip/common/scmi/scmi_clock.h
|
||||
new file mode 100644
|
||||
index 0000000..e640fe1
|
||||
--- /dev/null
|
||||
+++ b/plat/rockchip/common/scmi/scmi_clock.h
|
||||
@@ -0,0 +1,50 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#ifndef RK_SCMI_CLOCK_H
|
||||
+#define RK_SCMI_CLOCK_H
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include <common.h>
|
||||
+
|
||||
+struct rk_scmi_clock;
|
||||
+
|
||||
+struct rk_clk_ops {
|
||||
+ unsigned long (*get_rate)(struct rk_scmi_clock *clock);
|
||||
+ int (*set_rate)(struct rk_scmi_clock *clock, unsigned long rate);
|
||||
+ int (*set_status)(struct rk_scmi_clock *clock, bool status);
|
||||
+};
|
||||
+
|
||||
+typedef struct rk_scmi_clock {
|
||||
+ char name[SCMI_CLOCK_NAME_LENGTH_MAX];
|
||||
+ uint8_t enable;
|
||||
+ int8_t is_security;
|
||||
+ uint32_t id;
|
||||
+ uint32_t rate_cnt;
|
||||
+ uint64_t cur_rate;
|
||||
+ uint32_t enable_count;
|
||||
+ const struct rk_clk_ops *clk_ops;
|
||||
+ unsigned long *rate_table;
|
||||
+} rk_scmi_clock_t;
|
||||
+
|
||||
+/*
|
||||
+ * Return number of clock controllers for an agent
|
||||
+ * @agent_id: SCMI agent ID
|
||||
+ * Return number of clock controllers
|
||||
+ */
|
||||
+size_t rockchip_scmi_clock_count(unsigned int agent_id);
|
||||
+
|
||||
+/*
|
||||
+ * Get rk_scmi_clock_t point
|
||||
+ * @agent_id: SCMI agent ID
|
||||
+ * @scmi_id: SCMI clock ID
|
||||
+ * Return a rk_scmi_clock_t point
|
||||
+ */
|
||||
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id,
|
||||
+ uint32_t scmi_id);
|
||||
+
|
||||
+#endif /* RK_SCMI_CLOCK_H */
|
||||
diff --git a/plat/rockchip/common/scmi/scmi_rstd.c b/plat/rockchip/common/scmi/scmi_rstd.c
|
||||
new file mode 100644
|
||||
index 0000000..404d85e
|
||||
--- /dev/null
|
||||
+++ b/plat/rockchip/common/scmi/scmi_rstd.c
|
||||
@@ -0,0 +1,74 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#include <drivers/scmi-msg.h>
|
||||
+#include <drivers/scmi.h>
|
||||
+
|
||||
+#include "scmi_rstd.h"
|
||||
+
|
||||
+#pragma weak rockchip_scmi_rstd_count
|
||||
+#pragma weak rockchip_scmi_get_rstd
|
||||
+
|
||||
+size_t rockchip_scmi_rstd_count(unsigned int agent_id __unused)
|
||||
+{
|
||||
+ return 0U;
|
||||
+}
|
||||
+
|
||||
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id __unused,
|
||||
+ unsigned int scmi_id __unused)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+size_t plat_scmi_rstd_count(unsigned int agent_id)
|
||||
+{
|
||||
+ return rockchip_scmi_rstd_count(agent_id);
|
||||
+}
|
||||
+
|
||||
+const char *plat_scmi_rstd_get_name(unsigned int agent_id,
|
||||
+ unsigned int scmi_id)
|
||||
+{
|
||||
+ rk_scmi_rstd_t *rstd;
|
||||
+
|
||||
+ rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
|
||||
+ if (rstd == 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return rstd->name;
|
||||
+}
|
||||
+
|
||||
+int32_t plat_scmi_rstd_autonomous(unsigned int agent_id,
|
||||
+ unsigned int scmi_id,
|
||||
+ unsigned int state)
|
||||
+{
|
||||
+ rk_scmi_rstd_t *rstd;
|
||||
+
|
||||
+ rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
|
||||
+ if (rstd == 0)
|
||||
+ return SCMI_NOT_FOUND;
|
||||
+
|
||||
+ if ((rstd->rstd_ops && rstd->rstd_ops->reset_auto) != 0)
|
||||
+ return rstd->rstd_ops->reset_auto(rstd, state);
|
||||
+ else
|
||||
+ return SCMI_NOT_SUPPORTED;
|
||||
+}
|
||||
+
|
||||
+int32_t plat_scmi_rstd_set_state(unsigned int agent_id,
|
||||
+ unsigned int scmi_id,
|
||||
+ bool assert_not_deassert)
|
||||
+{
|
||||
+ rk_scmi_rstd_t *rstd;
|
||||
+
|
||||
+ rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
|
||||
+ if (rstd == 0)
|
||||
+ return SCMI_NOT_FOUND;
|
||||
+
|
||||
+ if ((rstd->rstd_ops && rstd->rstd_ops->reset_explicit) != 0)
|
||||
+ return rstd->rstd_ops->reset_explicit(rstd,
|
||||
+ assert_not_deassert);
|
||||
+ else
|
||||
+ return SCMI_NOT_SUPPORTED;
|
||||
+}
|
||||
diff --git a/plat/rockchip/common/scmi/scmi_rstd.h b/plat/rockchip/common/scmi/scmi_rstd.h
|
||||
new file mode 100644
|
||||
index 0000000..1af5881
|
||||
--- /dev/null
|
||||
+++ b/plat/rockchip/common/scmi/scmi_rstd.h
|
||||
@@ -0,0 +1,45 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#ifndef RK_SCMI_RESET_DOMAIN_H
|
||||
+#define RK_SCMI_RESET_DOMAIN_H
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include <common.h>
|
||||
+
|
||||
+struct rk_scmi_rstd;
|
||||
+
|
||||
+struct rk_scmi_rstd_ops {
|
||||
+ int (*reset_auto)(struct rk_scmi_rstd *rstd, uint32_t state);
|
||||
+ int (*reset_explicit)(struct rk_scmi_rstd *rstd, bool assert_not_deassert);
|
||||
+};
|
||||
+
|
||||
+typedef struct rk_scmi_rstd {
|
||||
+ char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ];
|
||||
+ uint32_t id;
|
||||
+ uint32_t attribute;
|
||||
+ uint32_t latency;
|
||||
+ struct rk_scmi_rstd_ops *rstd_ops;
|
||||
+} rk_scmi_rstd_t;
|
||||
+
|
||||
+/*
|
||||
+ * Return number of reset domain for an agent
|
||||
+ * @agent_id: SCMI agent ID
|
||||
+ * Return number of reset domain
|
||||
+ */
|
||||
+size_t rockchip_scmi_rstd_count(unsigned int agent_id);
|
||||
+
|
||||
+/*
|
||||
+ * Get rk_scmi_rstd_t point
|
||||
+ * @agent_id: SCMI agent ID
|
||||
+ * @scmi_id: SCMI rstd ID
|
||||
+ * Return a rk_scmi_rstd_t point
|
||||
+ */
|
||||
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id,
|
||||
+ unsigned int scmi_id);
|
||||
+
|
||||
+#endif /* RK_SCMI_RESET_DOMAIN_H */
|
139
atf.patches/rk3588-enable-crypto-function.patch
Normal file
139
atf.patches/rk3588-enable-crypto-function.patch
Normal file
@ -0,0 +1,139 @@
|
||||
From c805c14c1026b3ae5445e211c2101c60cd76ad0e Mon Sep 17 00:00:00 2001
|
||||
From: XiaoDong Huang <derrick.huang@rock-chips.com>
|
||||
Date: Mon, 17 Jun 2024 10:55:27 +0800
|
||||
Subject: [PATCH] feat(rk3588): enable crypto function
|
||||
|
||||
Signed-off-by: XiaoDong Huang <derrick.huang@rock-chips.com>
|
||||
Change-Id: Ifee2eab55d9c13cef5f15926fb80016845e2a66d
|
||||
---
|
||||
|
||||
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
|
||||
index dfb14e9..6d1e11e 100644
|
||||
--- a/bl31/aarch64/bl31_entrypoint.S
|
||||
+++ b/bl31/aarch64/bl31_entrypoint.S
|
||||
@@ -16,6 +16,11 @@
|
||||
.globl bl31_entrypoint
|
||||
.globl bl31_warm_entrypoint
|
||||
|
||||
+#ifdef PLAT_RK_BL31_ENTRYPOINT
|
||||
+ .globl plat_rockchip_bl31_entrypoint
|
||||
+ .globl plat_rockchip_bl31_entrypoint_set_sp
|
||||
+#endif
|
||||
+
|
||||
/* -----------------------------------------------------
|
||||
* bl31_entrypoint() is the cold boot entrypoint,
|
||||
* executed only by the primary cpu.
|
||||
@@ -23,6 +28,10 @@
|
||||
*/
|
||||
|
||||
func bl31_entrypoint
|
||||
+#ifdef PLAT_RK_BL31_ENTRYPOINT
|
||||
+ bl plat_rockchip_bl31_entrypoint_set_sp
|
||||
+ bl plat_rockchip_bl31_entrypoint
|
||||
+#endif
|
||||
/* ---------------------------------------------------------------
|
||||
* Stash the previous bootloader arguments x0 - x3 for later use.
|
||||
* ---------------------------------------------------------------
|
||||
diff --git a/plat/rockchip/rk3588/drivers/pmu/pmu.c b/plat/rockchip/rk3588/drivers/pmu/pmu.c
|
||||
index 83d6cad..a7c1c47 100644
|
||||
--- a/plat/rockchip/rk3588/drivers/pmu/pmu.c
|
||||
+++ b/plat/rockchip/rk3588/drivers/pmu/pmu.c
|
||||
@@ -136,6 +136,22 @@
|
||||
|
||||
static __pmusramfunc void ddr_resume(void)
|
||||
{
|
||||
+ /* check the crypto function had been enabled or not */
|
||||
+ if (mmio_read_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4)) & BIT(4)) {
|
||||
+ /* enable the crypto function */
|
||||
+ mmio_write_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4), BITS_WITH_WMASK(0, 0x1, 4));
|
||||
+ dsb();
|
||||
+ isb();
|
||||
+
|
||||
+ __asm__ volatile ("mov x0, #3\n"
|
||||
+ "dsb sy\n"
|
||||
+ "msr rmr_el3, x0\n"
|
||||
+ "1:\n"
|
||||
+ "isb\n"
|
||||
+ "wfi\n"
|
||||
+ "b 1b\n");
|
||||
+ }
|
||||
+
|
||||
dsu_restore_early();
|
||||
}
|
||||
|
||||
@@ -1437,3 +1453,66 @@
|
||||
|
||||
pm_reg_rgns_init();
|
||||
}
|
||||
+
|
||||
+void bl31_entrypoint(void);
|
||||
+
|
||||
+static uint64_t boot_cpu_save[4];
|
||||
+
|
||||
+void plat_rockchip_bl31_entrypoint_set_sp(uint64_t reg0, uint64_t reg1,
|
||||
+ uint64_t reg2, uint64_t reg3)
|
||||
+{
|
||||
+ __asm__ volatile("mov x10, %0\n" : : "r" (reg0) : );
|
||||
+
|
||||
+ reg0 = PSRAM_SP_TOP;
|
||||
+ __asm__ volatile("mov sp, %0\n" : : "r" (reg0) : );
|
||||
+
|
||||
+ __asm__ volatile("mov %0, x10\n" : "=r" (reg0) : :);
|
||||
+}
|
||||
+
|
||||
+void plat_rockchip_bl31_entrypoint(uint64_t reg0, uint64_t reg1,
|
||||
+ uint64_t reg2, uint64_t reg3)
|
||||
+{
|
||||
+ uint32_t tmp = mmio_read_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4));
|
||||
+
|
||||
+ /* check the crypto function had been enabled or not */
|
||||
+ if (tmp & BIT(4)) {
|
||||
+ /* save x0~x3 */
|
||||
+ boot_cpu_save[0] = reg0;
|
||||
+ boot_cpu_save[1] = reg1;
|
||||
+ boot_cpu_save[2] = reg2;
|
||||
+ boot_cpu_save[3] = reg3;
|
||||
+
|
||||
+ /* enable the crypto function */
|
||||
+ mmio_write_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4), BITS_WITH_WMASK(0, 0x1, 4));
|
||||
+
|
||||
+ /* remap pmusram to 0xffff0000 */
|
||||
+ mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(2), 0x00030001);
|
||||
+ dsb();
|
||||
+ psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
|
||||
+ cpuson_flags[0] = PMU_CPU_HOTPLUG;
|
||||
+ cpuson_entry_point[0] = (uintptr_t)bl31_entrypoint;
|
||||
+ dsb();
|
||||
+
|
||||
+ /* to enable the crypto function, must reset the core0 */
|
||||
+ __asm__ volatile ("mov x0, #3\n"
|
||||
+ "dsb sy\n"
|
||||
+ "msr rmr_el3, x0\n"
|
||||
+ "1:\n"
|
||||
+ "isb\n"
|
||||
+ "wfi\n"
|
||||
+ "b 1b\n");
|
||||
+ } else {
|
||||
+ /* remap bootrom to 0xffff0000 */
|
||||
+ mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(2), 0x00030000);
|
||||
+
|
||||
+ /*
|
||||
+ * the crypto function has been enabled,
|
||||
+ * restore the x0~x3.
|
||||
+ */
|
||||
+ __asm__ volatile ("ldr x0, [%0]\n"
|
||||
+ "ldr x1, [%0 , 0x8]\n"
|
||||
+ "ldr x2, [%0 , 0x10]\n"
|
||||
+ "ldr x3, [%0 , 0x18]\n"
|
||||
+ : : "r" (&boot_cpu_save[0]));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/plat/rockchip/rk3588/platform.mk b/plat/rockchip/rk3588/platform.mk
|
||||
index 07eda40..3d9dc59 100644
|
||||
--- a/plat/rockchip/rk3588/platform.mk
|
||||
+++ b/plat/rockchip/rk3588/platform.mk
|
||||
@@ -96,3 +96,4 @@
|
||||
|
||||
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
|
||||
$(eval $(call add_define,PLAT_SKIP_DFS_TLB_DCACHE_MAINTENANCE))
|
||||
+$(eval $(call add_define,PLAT_RK_BL31_ENTRYPOINT))
|
293
atf.patches/rockchip-add-some-pm-helpers-functions.patch
Normal file
293
atf.patches/rockchip-add-some-pm-helpers-functions.patch
Normal file
@ -0,0 +1,293 @@
|
||||
From eb5dfe2a76180d85f33fa2e7ed5131852a003dac Mon Sep 17 00:00:00 2001
|
||||
From: XiaoDong Huang <derrick.huang@rock-chips.com>
|
||||
Date: Sun, 25 Jun 2023 19:23:07 +0800
|
||||
Subject: [PATCH] feat(rockchip): add some pm helpers functions
|
||||
|
||||
Some power domains will be powered off when the system suspends,
|
||||
so registers in the power domain need to be save/restore.
|
||||
Now we add some functions to save/restore registers easily:
|
||||
use rockchip_alloc_region_mem to allocate memory to save/restore registers in regions;
|
||||
use rockchip_reg_rgn_save to save registers regions in regions;
|
||||
use rockchip_reg_rgn_restore to restore registers in regions;
|
||||
use rockchip_dump_reg_rgns to dump registers in regions;
|
||||
|
||||
Signed-off-by: XiaoDong Huang <derrick.huang@rock-chips.com>
|
||||
Change-Id: I34f909a103fbe2d51456e1d92df0be570e35e2a1
|
||||
---
|
||||
|
||||
diff --git a/plat/rockchip/common/include/plat_pm_helpers.h b/plat/rockchip/common/include/plat_pm_helpers.h
|
||||
new file mode 100644
|
||||
index 0000000..2204a65
|
||||
--- /dev/null
|
||||
+++ b/plat/rockchip/common/include/plat_pm_helpers.h
|
||||
@@ -0,0 +1,51 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#ifndef PLAT_PM_HELPERS_H
|
||||
+#define PLAT_PM_HELPERS_H
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+/**
|
||||
+ * Use this macro to define a register region.
|
||||
+ * start: start offset from the base address.
|
||||
+ * end: end offset from the base address.
|
||||
+ * stride: stride of registers in region.
|
||||
+ * base: base address of registers in region.
|
||||
+ * wmsk: write mask of registers in region.
|
||||
+ */
|
||||
+#define REG_REGION(_start, _end, _stride, _base, _wmsk) \
|
||||
+{ \
|
||||
+ .start = (_base) + (_start), \
|
||||
+ .end = (_base) + (_end), \
|
||||
+ .stride = _stride, \
|
||||
+ .wmsk = _wmsk \
|
||||
+}
|
||||
+
|
||||
+struct reg_region {
|
||||
+ /* Start address of region */
|
||||
+ uint32_t start;
|
||||
+ /* End address of region */
|
||||
+ uint32_t end;
|
||||
+ /* Stride of registers in region */
|
||||
+ uint32_t stride;
|
||||
+ /* Write mask of registers in region */
|
||||
+ uint32_t wmsk;
|
||||
+ /* Buffer to save/restore registers in region */
|
||||
+ uint32_t *buf;
|
||||
+};
|
||||
+
|
||||
+void rockchip_alloc_region_mem(struct reg_region *rgns, uint32_t rgn_num);
|
||||
+void rockchip_reg_rgn_save(struct reg_region *rgns, uint32_t rgn_num);
|
||||
+void rockchip_reg_rgn_restore(struct reg_region *rgns, uint32_t rgn_num);
|
||||
+void rockchip_reg_rgn_restore_reverse(struct reg_region *rgns, uint32_t rgn_num);
|
||||
+void rockchip_regs_dump(uint32_t base,
|
||||
+ uint32_t start_offset,
|
||||
+ uint32_t end_offset,
|
||||
+ uint32_t stride);
|
||||
+void rockchip_dump_reg_rgns(struct reg_region *rgns, uint32_t rgn_num);
|
||||
+
|
||||
+#endif /* PLAT_PM_HELPERS_H */
|
||||
diff --git a/plat/rockchip/common/plat_pm_helpers.c b/plat/rockchip/common/plat_pm_helpers.c
|
||||
new file mode 100644
|
||||
index 0000000..191b0ca
|
||||
--- /dev/null
|
||||
+++ b/plat/rockchip/common/plat_pm_helpers.c
|
||||
@@ -0,0 +1,213 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#include <assert.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include <arch_helpers.h>
|
||||
+#include <bl31/bl31.h>
|
||||
+#include <common/debug.h>
|
||||
+#include <drivers/console.h>
|
||||
+#include <drivers/delay_timer.h>
|
||||
+#include <lib/mmio.h>
|
||||
+#include <plat/common/platform.h>
|
||||
+#include <platform_def.h>
|
||||
+
|
||||
+#include <plat_pm_helpers.h>
|
||||
+
|
||||
+#define ROCKCHIP_PM_REG_REGION_MEM_LEN (ROCKCHIP_PM_REG_REGION_MEM_SIZE / sizeof(uint32_t))
|
||||
+
|
||||
+/* REG region */
|
||||
+#define RGN_LEN(_rgn) (((_rgn)->end - (_rgn)->start) / (_rgn)->stride + 1)
|
||||
+
|
||||
+#ifndef ROCKCHIP_PM_REG_REGION_MEM_SIZE
|
||||
+#define ROCKCHIP_PM_REG_REGION_MEM_SIZE 0
|
||||
+#endif
|
||||
+
|
||||
+#ifdef ROCKCHIP_REG_RGN_MEM_BASE
|
||||
+static uint32_t *region_mem = (uint32_t *)ROCKCHIP_REG_RGN_MEM_BASE;
|
||||
+#else
|
||||
+static uint32_t region_mem[ROCKCHIP_PM_REG_REGION_MEM_LEN];
|
||||
+#endif
|
||||
+
|
||||
+static int region_mem_idx;
|
||||
+
|
||||
+static int alloc_region_mem(uint32_t *buf, int max_len,
|
||||
+ struct reg_region *rgns, uint32_t rgn_num)
|
||||
+{
|
||||
+ int i;
|
||||
+ int total_len = 0, len = 0;
|
||||
+ struct reg_region *r = rgns;
|
||||
+
|
||||
+ assert(buf && rgns && rgn_num);
|
||||
+
|
||||
+ for (i = 0; i < rgn_num; i++, r++) {
|
||||
+ if (total_len < max_len)
|
||||
+ r->buf = &buf[total_len];
|
||||
+
|
||||
+ len = RGN_LEN(r);
|
||||
+ total_len += len;
|
||||
+ }
|
||||
+
|
||||
+ if (total_len > max_len) {
|
||||
+ ERROR("%s The buffer remain length:%d is too small for region:0x%x, at least %d\n",
|
||||
+ __func__, max_len, rgns[0].start, total_len);
|
||||
+ panic();
|
||||
+ }
|
||||
+
|
||||
+ return total_len;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Alloc memory to reg_region->buf from region_mem.
|
||||
+ * @rgns - struct reg_region array.
|
||||
+ * @rgn_num - struct reg_region array length.
|
||||
+ */
|
||||
+void rockchip_alloc_region_mem(struct reg_region *rgns, uint32_t rgn_num)
|
||||
+{
|
||||
+ int max_len = 0, len;
|
||||
+
|
||||
+ assert(rgns && rgn_num);
|
||||
+
|
||||
+ max_len = ROCKCHIP_PM_REG_REGION_MEM_LEN - region_mem_idx;
|
||||
+
|
||||
+ len = alloc_region_mem(region_mem + region_mem_idx, max_len,
|
||||
+ rgns, rgn_num);
|
||||
+
|
||||
+ region_mem_idx += len;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Save (reg_region->start ~ reg_region->end) to reg_region->buf.
|
||||
+ * @rgns - struct reg_region array.
|
||||
+ * @rgn_num - struct reg_region array length.
|
||||
+ */
|
||||
+void rockchip_reg_rgn_save(struct reg_region *rgns, uint32_t rgn_num)
|
||||
+{
|
||||
+ struct reg_region *r;
|
||||
+ uint32_t addr;
|
||||
+ int i, j;
|
||||
+
|
||||
+ assert(rgns && rgn_num);
|
||||
+
|
||||
+ for (i = 0; i < rgn_num; i++) {
|
||||
+ r = &rgns[i];
|
||||
+ for (j = 0, addr = r->start; addr <= r->end; addr += r->stride, j++)
|
||||
+ r->buf[j] = mmio_read_32(addr);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Restore reg_region->buf to (reg_region->start ~ reg_region->end).
|
||||
+ * @rgns - struct reg_region array.
|
||||
+ * @rgn_num - struct reg_region array length.
|
||||
+ */
|
||||
+void rockchip_reg_rgn_restore(struct reg_region *rgns, uint32_t rgn_num)
|
||||
+{
|
||||
+ struct reg_region *r;
|
||||
+ uint32_t addr;
|
||||
+ int i, j;
|
||||
+
|
||||
+ assert(rgns && rgn_num);
|
||||
+
|
||||
+ for (i = 0; i < rgn_num; i++) {
|
||||
+ r = &rgns[i];
|
||||
+ for (j = 0, addr = r->start; addr <= r->end; addr += r->stride, j++)
|
||||
+ mmio_write_32(addr, r->buf[j] | r->wmsk);
|
||||
+
|
||||
+ dsb();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Restore reg_region->buf to (reg_region->start ~ reg_region->end) reversely.
|
||||
+ * @rgns - struct reg_region array.
|
||||
+ * @rgn_num - struct reg_region array length.
|
||||
+ */
|
||||
+void rockchip_reg_rgn_restore_reverse(struct reg_region *rgns, uint32_t rgn_num)
|
||||
+{
|
||||
+ struct reg_region *r;
|
||||
+ uint32_t addr;
|
||||
+ int i, j;
|
||||
+
|
||||
+ assert(rgns && rgn_num);
|
||||
+
|
||||
+ for (i = rgn_num - 1; i >= 0; i--) {
|
||||
+ r = &rgns[i];
|
||||
+ j = RGN_LEN(r) - 1;
|
||||
+ for (addr = r->end; addr >= r->start; addr -= r->stride, j--)
|
||||
+ mmio_write_32(addr, r->buf[j] | r->wmsk);
|
||||
+
|
||||
+ dsb();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void rockchip_print_hex(uint32_t val)
|
||||
+{
|
||||
+ int i;
|
||||
+ unsigned char tmp;
|
||||
+
|
||||
+ putchar('0');
|
||||
+ putchar('x');
|
||||
+ for (i = 0; i < 8; val <<= 4, ++i) {
|
||||
+ tmp = (val & 0xf0000000) >> 28;
|
||||
+ if (tmp < 10)
|
||||
+ putchar('0' + tmp);
|
||||
+ else
|
||||
+ putchar('a' + tmp - 10);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Dump registers (base + start_offset ~ base + end_offset)
|
||||
+ * @base - the base addr of the register.
|
||||
+ * @start_offset - the start offset to dump.
|
||||
+ * @end_offset - the end offset to dump.
|
||||
+ * @stride - the stride of the registers.
|
||||
+ */
|
||||
+void rockchip_regs_dump(uint32_t base,
|
||||
+ uint32_t start_offset,
|
||||
+ uint32_t end_offset,
|
||||
+ uint32_t stride)
|
||||
+{
|
||||
+ uint32_t i;
|
||||
+
|
||||
+ for (i = start_offset; i <= end_offset; i += stride) {
|
||||
+ if ((i - start_offset) % 16 == 0) {
|
||||
+ putchar('\n');
|
||||
+ rockchip_print_hex(base + i);
|
||||
+ putchar(':');
|
||||
+ putchar(' ');
|
||||
+ putchar(' ');
|
||||
+ putchar(' ');
|
||||
+ putchar(' ');
|
||||
+ }
|
||||
+ rockchip_print_hex(mmio_read_32(base + i));
|
||||
+ putchar(' ');
|
||||
+ putchar(' ');
|
||||
+ putchar(' ');
|
||||
+ putchar(' ');
|
||||
+ }
|
||||
+ putchar('\n');
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Dump reg regions
|
||||
+ * @rgns - struct reg_region array.
|
||||
+ * @rgn_num - struct reg_region array length.
|
||||
+ */
|
||||
+void rockchip_dump_reg_rgns(struct reg_region *rgns, uint32_t rgn_num)
|
||||
+{
|
||||
+ struct reg_region *r;
|
||||
+ int i;
|
||||
+
|
||||
+ assert(rgns && rgn_num);
|
||||
+
|
||||
+ for (i = 0; i < rgn_num; i++) {
|
||||
+ r = &rgns[i];
|
||||
+ rockchip_regs_dump(0x0, r->start, r->end, r->stride);
|
||||
+ }
|
||||
+}
|
BIN
boot.scr
BIN
boot.scr
Binary file not shown.
@ -19,7 +19,7 @@ import (
|
||||
var configContents []byte
|
||||
|
||||
// see https://www.kernel.org/releases.json
|
||||
var latest = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.9.8.tar.xz"
|
||||
var latest = "https://git.kernel.org/torvalds/t/linux-6.10-rc7.tar.gz"
|
||||
|
||||
func downloadKernel() error {
|
||||
out, err := os.Create(filepath.Base(latest))
|
||||
@ -42,7 +42,7 @@ func downloadKernel() error {
|
||||
}
|
||||
|
||||
func applyPatches(srcdir string) error {
|
||||
patches, err := filepath.Glob("*.patch")
|
||||
patches, err := filepath.Glob("kernel.patches/*.patch")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -152,7 +152,7 @@ func main() {
|
||||
log.Fatalf("untar: %v", err)
|
||||
}
|
||||
|
||||
srcdir := strings.TrimSuffix(filepath.Base(latest), ".tar.xz")
|
||||
srcdir := strings.TrimSuffix(filepath.Base(latest), ".tar.gz")
|
||||
|
||||
log.Printf("applying patches")
|
||||
if err := applyPatches(srcdir); err != nil {
|
||||
@ -172,7 +172,7 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := copyFile("/tmp/buildresult/rk3328-rock64.dtb", "arch/arm64/boot/dts/rockchip/rk3328-rock64.dtb"); err != nil {
|
||||
if err := copyFile("/tmp/buildresult/rk3588-friendlyelec-cm3588-nas.dtb", "arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -13,15 +13,15 @@ import (
|
||||
|
||||
const ubootRev = "fd46ea0e701920eb205c2bce9d527bf0dec10b59"
|
||||
const ubootTS = 1720219003
|
||||
const trustedRepoRev = "10eb851f92acc67f7cdb955770e3bdced3026677"
|
||||
const trustedRepoRev = "c970c1c38f6d06a3e48e00ea7533c0e427311bcb"
|
||||
|
||||
const (
|
||||
uBootRepo = "https://github.com/u-boot/u-boot"
|
||||
trustedFirmwareRepo = "https://github.com/ARM-software/arm-trusted-firmware"
|
||||
)
|
||||
|
||||
func applyPatches(srcdir string) error {
|
||||
patches, err := filepath.Glob("*.patch")
|
||||
func applyPatches(srcdir, t string) error {
|
||||
patches, err := filepath.Glob(t+".patches/*.patch")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -47,7 +47,7 @@ func applyPatches(srcdir string) error {
|
||||
}
|
||||
|
||||
func compile(trustedFirmwareDir string) error {
|
||||
defconfig := exec.Command("make", "ARCH=arm64", "rock64-rk3328_defconfig")
|
||||
defconfig := exec.Command("make", "ARCH=arm64", "nanopc-t6-rk3588_defconfig")
|
||||
defconfig.Stdout = os.Stdout
|
||||
defconfig.Stderr = os.Stderr
|
||||
if err := defconfig.Run(); err != nil {
|
||||
@ -70,7 +70,8 @@ func compile(trustedFirmwareDir string) error {
|
||||
"ARCH=arm64",
|
||||
"CROSS_COMPILE=aarch64-linux-gnu-",
|
||||
"SOURCE_DATE_EPOCH="+strconv.Itoa(ubootTS),
|
||||
fmt.Sprintf("BL31=%s/build/rk3328/release/bl31/bl31.elf", trustedFirmwareDir),
|
||||
fmt.Sprintf("BL31=%s/build/rk3588/release/bl31/bl31.elf", trustedFirmwareDir),
|
||||
fmt.Sprintf("ROCKCHIP_TPL=%s","/usr/src/uboot.patches/rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.16.bin"),
|
||||
)
|
||||
make.Stdout = os.Stdout
|
||||
make.Stderr = os.Stderr
|
||||
@ -140,7 +141,23 @@ func main() {
|
||||
{"git", "remote", "add", "origin", trustedFirmwareRepo},
|
||||
{"git", "fetch", "--depth=1", "origin", trustedRepoRev},
|
||||
{"git", "checkout", "FETCH_HEAD"},
|
||||
{"make", "SOURCE_DATE_EPOCH=1600000000", "CROSS_COMPILE=aarch64-linux-gnu-", "PLAT=rk3328"},
|
||||
} {
|
||||
log.Printf("Running %s", cmd)
|
||||
cmdObj := exec.Command(cmd[0], cmd[1:]...)
|
||||
cmdObj.Stdout = os.Stdout
|
||||
cmdObj.Stderr = os.Stderr
|
||||
cmdObj.Dir = trustedFirmwareDir
|
||||
if err := cmdObj.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("applying patches")
|
||||
if err := applyPatches(trustedFirmwareDir, "atf"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, cmd := range [][]string{
|
||||
{"make", "SOURCE_DATE_EPOCH=1600000000", "CROSS_COMPILE=aarch64-linux-gnu-", "PLAT=rk3588"},
|
||||
} {
|
||||
log.Printf("Running %s", cmd)
|
||||
cmdObj := exec.Command(cmd[0], cmd[1:]...)
|
||||
@ -153,7 +170,7 @@ func main() {
|
||||
}
|
||||
|
||||
var bootCmdPath string
|
||||
if p, err := filepath.Abs("boot.cmd"); err != nil {
|
||||
if p, err := filepath.Abs("uboot.patches/boot.cmd"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
bootCmdPath = p
|
||||
@ -180,7 +197,7 @@ func main() {
|
||||
}
|
||||
|
||||
log.Printf("applying patches")
|
||||
if err := applyPatches(ubootDir); err != nil {
|
||||
if err := applyPatches(ubootDir, "uboot"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ const dockerFileContents = `
|
||||
FROM debian:bullseye
|
||||
|
||||
RUN apt-get update && apt-get install -y crossbuild-essential-arm64 bc libssl-dev bison flex
|
||||
RUN mkdir -p /usr/src/kernel.patches
|
||||
|
||||
COPY gokr-build-kernel /usr/bin/gokr-build-kernel
|
||||
{{- range $idx, $path := .Patches }}
|
||||
@ -41,8 +42,43 @@ var dockerFileTmpl = template.Must(template.New("dockerfile").
|
||||
Parse(dockerFileContents))
|
||||
|
||||
var patchFiles = []string{
|
||||
// "0001-ODROID-XU4-regulator-s2mps11-call-shutdown-function-.patch",
|
||||
// "0002-ODROID-XU4-regulator-s2mps11-add-ethernet-power-rese.patch",
|
||||
"kernel.patches/0001-dt-bindings-arm-rockchip-Add-FriendlyElec-CM3588-NAS.patch",
|
||||
"kernel.patches/0002-arm64-dts-rockchip-Add-FriendlyElec-CM3588-NAS-board.patch",
|
||||
"kernel.patches/0010-fix-clk-divisions.patch",
|
||||
"kernel.patches/0011-irqchip-fix-its-timeout-issue.patch",
|
||||
"kernel.patches/0012-fix-initial-PERST-GPIO-value.patch",
|
||||
"kernel.patches/0022-RK3588-Add-Thermal-and-CpuFreq-Support.patch",
|
||||
"kernel.patches/0024-RK3588-Add-Crypto-Support.patch",
|
||||
"kernel.patches/0025-RK3588-Add-HW-RNG-Support.patch",
|
||||
"kernel.patches/0026-RK3588-Add-VPU121-H.264-Decoder-Support.patch",
|
||||
"kernel.patches/0027-RK3588-Add-rkvdec2-Support-v3.patch",
|
||||
"kernel.patches/0028-media-v4l2-core-Initialize-h264-frame_mbs_only_flag-.patch",
|
||||
"kernel.patches/0138-arm64-dts-rockchip-Add-HDMI0-bridge-to-rk3588.patch",
|
||||
"kernel.patches/0139-arm64-dts-rockchip-Enable-HDMI0-PHY-clk-provider-on-.patch",
|
||||
"kernel.patches/0144-phy-phy-rockchip-samsung-hdptx-Add-FRL-EARC-support.patch",
|
||||
"kernel.patches/0145-phy-phy-rockchip-samsung-hdptx-Add-clock-provider.patch",
|
||||
"kernel.patches/0146-drm-rockchip-vop2-Improve-display-modes-handling-on-.patch",
|
||||
"kernel.patches/0147-arm64-dts-rockchip-rk3588-add-RGA2-node.patch",
|
||||
"kernel.patches/0161-drm-bridge-synopsys-Add-initial-support-for-DW-HDMI-Controller.patch",
|
||||
"kernel.patches/0162-drm-bridge-synopsys-Fix-HDMI-Controller.patch",
|
||||
"kernel.patches/0170-drm-rockchip-vop2-add-clocks-reset-support.patch",
|
||||
"kernel.patches/0801-wireless-add-bcm43752.patch",
|
||||
"kernel.patches/0802-wireless-add-clk-property.patch",
|
||||
"kernel.patches/1010-arm64-dts-rock-5b-Slow-down-emmc-to-hs200-and-add-ts.patch",
|
||||
"kernel.patches/1011-board-rock-5b-arm64-dts-enable-spi-flash.patch",
|
||||
"kernel.patches/1012-arm64-dts-rockchip-Enable-HDMI0-on-rock-5b.patch",
|
||||
"kernel.patches/1014-arm64-dts-rockchip-Make-use-of-HDMI0-PHY-PLL-on-rock5b.patch",
|
||||
"kernel.patches/1015-board-rock5b-automatic-fan-control.patch",
|
||||
"kernel.patches/1020-Add-HDMI-and-VOP2-to-Rock-5A.patch",
|
||||
"kernel.patches/1021-arch-arm64-dts-enable-gpu-node-for-rock-5a.patch",
|
||||
"kernel.patches/1021-arm64-dts-Add-missing-nodes-to-Orange-Pi-5-Plus.patch",
|
||||
"kernel.patches/1023-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5a.patch",
|
||||
"kernel.patches/1031-arm64-dts-rockchip-Add-HDMI-support-to-ArmSoM-Sige7.patch",
|
||||
"kernel.patches/1032-arm64-dts-rockchip-Add-ap6275p-wireless-support-to-A.patch",
|
||||
"kernel.patches/1040-board-khadas-edge2-add-nodes.patch",
|
||||
"kernel.patches/1041-board-khadas-edge2-mcu.patch",
|
||||
"kernel.patches/1051-arm64-dts-rockchip-Add-NanoPC-T6-SPI-Flash.patch",
|
||||
// "linux-6.10-rc7.tar.gz",
|
||||
}
|
||||
|
||||
func copyFile(dest, src string) error {
|
||||
@ -135,8 +171,8 @@ func main() {
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
cmd := exec.Command("go", "install", "github.com/anupcshan/gokrazy-rock64-kernel/cmd/gokr-build-kernel")
|
||||
cmd.Env = append(os.Environ(), "GOOS=linux", "CGO_ENABLED=0", "GOBIN="+tmp)
|
||||
cmd := exec.Command("go", "build", "-o", tmp, "github.com/anupcshan/gokrazy-rock64-kernel/cmd/gokr-build-kernel")
|
||||
cmd.Env = append(os.Environ(), "GOOS=linux", "CGO_ENABLED=0")
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalf("%v: %v", cmd.Args, err)
|
||||
@ -157,15 +193,18 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
dtbPath, err := find("rk3328-rock64.dtb")
|
||||
dtbPath, err := find("rk3588-friendlyelec-cm3588-nas.dtb")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = os.MkdirAll(filepath.Join(tmp, "kernel.patches"), 0750)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Copy all files into the temporary directory so that docker
|
||||
// includes them in the build context.
|
||||
for _, path := range patchPaths {
|
||||
if err := copyFile(filepath.Join(tmp, filepath.Base(path)), path); err != nil {
|
||||
if err := copyFile(filepath.Join(tmp, "kernel.patches", filepath.Base(path)), path); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@ -239,7 +278,7 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := copyFile(dtbPath, filepath.Join(tmp, "rk3328-rock64.dtb")); err != nil {
|
||||
if err := copyFile(dtbPath, filepath.Join(tmp, "rk3588-friendlyelec-cm3588-nas.dtb")); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ FROM debian:bookworm
|
||||
RUN apt-get update && apt-get install -y crossbuild-essential-arm64 bc libssl-dev bison flex git python3 python3-setuptools swig python3-dev python3-pyelftools uuid-dev libgnutls28-dev
|
||||
|
||||
COPY gokr-build-uboot /usr/bin/gokr-build-uboot
|
||||
RUN mkdir -p /usr/src/atf.patches
|
||||
RUN mkdir -p /usr/src/uboot.patches
|
||||
{{- range $idx, $path := .Patches }}
|
||||
COPY {{ $path }} /usr/src/{{ $path }}
|
||||
{{- end }}
|
||||
@ -39,7 +41,16 @@ var dockerFileTmpl = template.Must(template.New("dockerfile").
|
||||
}).
|
||||
Parse(dockerFileContents))
|
||||
|
||||
var patchFiles = []string{"boot.cmd"}
|
||||
var ubootPatchFiles = []string{
|
||||
"uboot.patches/boot.cmd",
|
||||
"uboot.patches/rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.16.bin",
|
||||
}
|
||||
var atfPatchFiles = []string{
|
||||
"atf.patches/feat-rk3588-support-rk3588.patch",
|
||||
"atf.patches/rk3588-enable-crypto-function.patch",
|
||||
"atf.patches/feat-rockchip-support-SCMI-for-clock-reset-domain.patch",
|
||||
"atf.patches/rockchip-add-some-pm-helpers-functions.patch",
|
||||
}
|
||||
|
||||
func copyFile(dest, src string) error {
|
||||
out, err := os.Create(dest)
|
||||
@ -131,8 +142,8 @@ func main() {
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
cmd := exec.Command("go", "install", "github.com/anupcshan/gokrazy-rock64-kernel/cmd/gokr-build-uboot")
|
||||
cmd.Env = append(os.Environ(), "GOOS=linux", "CGO_ENABLED=0", "GOBIN="+tmp)
|
||||
cmd := exec.Command("go", "build", "-o", tmp, "github.com/anupcshan/gokrazy-rock64-kernel/cmd/gokr-build-uboot")
|
||||
cmd.Env = append(os.Environ(), "GOOS=linux", "CGO_ENABLED=0")
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalf("%v: %v", cmd.Args, err)
|
||||
@ -141,7 +152,8 @@ func main() {
|
||||
buildPath := filepath.Join(tmp, "gokr-build-uboot")
|
||||
|
||||
var patchPaths []string
|
||||
for _, filename := range patchFiles {
|
||||
|
||||
for _, filename := range ubootPatchFiles {
|
||||
path, err := find(filename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -149,10 +161,37 @@ func main() {
|
||||
patchPaths = append(patchPaths, path)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(filepath.Join(tmp, "uboot.patches"), 0750)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Copy all files into the temporary directory so that docker
|
||||
// includes them in the build context.
|
||||
for _, path := range patchPaths {
|
||||
if err := copyFile(filepath.Join(tmp, filepath.Base(path)), path); err != nil {
|
||||
if err = copyFile(filepath.Join(tmp, "uboot.patches", filepath.Base(path)), path); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
patchPaths = patchPaths[0:0]
|
||||
for _, filename := range atfPatchFiles {
|
||||
path, err := find(filename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
patchPaths = append(patchPaths, path)
|
||||
}
|
||||
|
||||
|
||||
err = os.MkdirAll(filepath.Join(tmp, "atf.patches"), 0750)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Copy all files into the temporary directory so that docker
|
||||
// includes them in the build context.
|
||||
for _, path := range patchPaths {
|
||||
if err := copyFile(filepath.Join(tmp, "atf.patches", filepath.Base(path)), path); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@ -175,7 +214,7 @@ func main() {
|
||||
Uid: u.Uid,
|
||||
Gid: u.Gid,
|
||||
BuildPath: buildPath,
|
||||
Patches: patchFiles,
|
||||
Patches: append(atfPatchFiles, ubootPatchFiles...),
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
From e6b6a82789baf275a597ef312a145c3b4a44da19 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Kropatsch <seb-dev@mail.de>
|
||||
Date: Sun, 16 Jun 2024 23:48:29 +0200
|
||||
Subject: [PATCH 1/2] dt-bindings: arm: rockchip: Add FriendlyElec CM3588 NAS
|
||||
|
||||
Add devicetree bindings for the FriendlyElec CM3588 NAS board.
|
||||
|
||||
The CM3588 NAS by FriendlyElec pairs the CM3588 compute module, based on
|
||||
the Rockchip RK3588 SoC, with the CM3588 NAS Kit carrier board.
|
||||
|
||||
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Sebastian Kropatsch <seb-dev@mail.de>
|
||||
---
|
||||
Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
|
||||
index fcf7316ec..86379b8cc 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
|
||||
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
|
||||
@@ -236,6 +236,13 @@ properties:
|
||||
- const: friendlyarm,nanopc-t6
|
||||
- const: rockchip,rk3588
|
||||
|
||||
+ - description: FriendlyElec CM3588-based boards
|
||||
+ items:
|
||||
+ - enum:
|
||||
+ - friendlyarm,cm3588-nas
|
||||
+ - const: friendlyarm,cm3588
|
||||
+ - const: rockchip,rk3588
|
||||
+
|
||||
- description: GeekBuying GeekBox
|
||||
items:
|
||||
- const: geekbuying,geekbox
|
||||
--
|
||||
2.45.2
|
||||
|
69
kernel.patches/0001-general-add-overlay-support.patch
Normal file
69
kernel.patches/0001-general-add-overlay-support.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Sabatino <paolo.sabatino@gmail.com>
|
||||
Date: Sun, 2 Jun 2024 21:53:01 +0200
|
||||
Subject: compile .scr and install overlays in right path
|
||||
|
||||
---
|
||||
scripts/Makefile.dtbinst | 13 +++++++++-
|
||||
scripts/Makefile.lib | 8 +++++-
|
||||
2 files changed, 19 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/scripts/Makefile.dtbinst
|
||||
+++ b/scripts/Makefile.dtbinst
|
||||
@@ -33,7 +33,18 @@ endef
|
||||
|
||||
$(foreach d, $(sort $(dir $(dtbs))), $(eval $(call gen_install_rules,$(d))))
|
||||
|
||||
-dtbs := $(notdir $(dtbs))
|
||||
+# Very convoluted way to flatten all the device tree
|
||||
+# directories, but keep the "/overlay/" directory
|
||||
+
|
||||
+# topmost directory (ie: from rockchip/overlay/rk322x-emmc.dtbo extracts rockchip)
|
||||
+topmost_dir = $(firstword $(subst /, ,$(dtbs)))
|
||||
+# collect dtbs entries which starts with "$topmost_dir/overlay/", then remove "$topmost_dir"
|
||||
+dtbs_overlays = $(subst $(topmost_dir)/,,$(filter $(topmost_dir)/overlay/%, $(dtbs)))
|
||||
+# collect the non-overlay dtbs
|
||||
+dtbs_regular = $(filter-out $(topmost_dir)/overlay/%, $(dtbs))
|
||||
+# compose the dtbs variable flattening all the non-overlays entries
|
||||
+# and appending the overlays entries
|
||||
+dtbs := $(notdir $(dtbs_regular)) $(dtbs_overlays)
|
||||
|
||||
endif # CONFIG_ARCH_WANT_FLAT_DTB_INSTALL
|
||||
|
||||
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/scripts/Makefile.lib
|
||||
+++ b/scripts/Makefile.lib
|
||||
@@ -402,7 +402,7 @@ $(obj)/%.dtbo.S: $(obj)/%.dtbo FORCE
|
||||
|
||||
quiet_cmd_dtc = DTC $@
|
||||
cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
|
||||
- $(DTC) -o $@ -b 0 \
|
||||
+ $(DTC) -@ -o $@ -b 0 \
|
||||
$(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
|
||||
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
|
||||
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
|
||||
@@ -427,12 +427,18 @@ quiet_cmd_dtb = $(quiet_cmd_dtc)
|
||||
cmd_dtb = $(cmd_dtc)
|
||||
endif
|
||||
|
||||
+quiet_cmd_scr = MKIMAGE $@
|
||||
+cmd_scr = mkimage -C none -A $(ARCH) -T script -d $< $@
|
||||
+
|
||||
$(obj)/%.dtb: $(obj)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE
|
||||
$(call if_changed_dep,dtb)
|
||||
|
||||
$(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE
|
||||
$(call if_changed_dep,dtc)
|
||||
|
||||
+$(obj)/%.scr: $(src)/%.scr-cmd FORCE
|
||||
+ $(call if_changed,scr)
|
||||
+
|
||||
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
|
||||
|
||||
# Bzip2
|
||||
--
|
||||
Armbian
|
||||
|
File diff suppressed because it is too large
Load Diff
142
kernel.patches/0010-fix-clk-divisions.patch
Normal file
142
kernel.patches/0010-fix-clk-divisions.patch
Normal file
@ -0,0 +1,142 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
Date: Tue, 24 Oct 2023 16:09:35 +0200
|
||||
Subject: math.h: add DIV_ROUND_UP_NO_OVERFLOW
|
||||
|
||||
Add a new DIV_ROUND_UP helper, which cannot overflow when
|
||||
big numbers are being used.
|
||||
|
||||
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
---
|
||||
include/linux/math.h | 11 ++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/include/linux/math.h b/include/linux/math.h
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/include/linux/math.h
|
||||
+++ b/include/linux/math.h
|
||||
@@ -36,6 +36,17 @@
|
||||
|
||||
#define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP
|
||||
|
||||
+/**
|
||||
+ * DIV_ROUND_UP_NO_OVERFLOW - divide two numbers and always round up
|
||||
+ * @n: numerator / dividend
|
||||
+ * @d: denominator / divisor
|
||||
+ *
|
||||
+ * This functions does the same as DIV_ROUND_UP, but internally uses a
|
||||
+ * division and a modulo operation instead of math tricks. This way it
|
||||
+ * avoids overflowing when handling big numbers.
|
||||
+ */
|
||||
+#define DIV_ROUND_UP_NO_OVERFLOW(n, d) (((n) / (d)) + !!((n) % (d)))
|
||||
+
|
||||
#define DIV_ROUND_DOWN_ULL(ll, d) \
|
||||
({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; })
|
||||
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
Date: Tue, 24 Oct 2023 16:13:50 +0200
|
||||
Subject: clk: divider: Fix divisor masking on 64 bit platforms
|
||||
|
||||
The clock framework handles clock rates as "unsigned long", so u32 on
|
||||
32-bit architectures and u64 on 64-bit architectures.
|
||||
|
||||
The current code casts the dividend to u64 on 32-bit to avoid a
|
||||
potential overflow. For example DIV_ROUND_UP(3000000000, 1500000000)
|
||||
= (3.0G + 1.5G - 1) / 1.5G = = OVERFLOW / 1.5G, which has been
|
||||
introduced in commit 9556f9dad8f5 ("clk: divider: handle integer overflow
|
||||
when dividing large clock rates").
|
||||
|
||||
On 64 bit platforms this masks the divisor, so that only the lower
|
||||
32 bit are used. Thus requesting a frequency >= 4.3GHz results
|
||||
in incorrect values. For example requesting 4300000000 (4.3 GHz) will
|
||||
effectively request ca. 5 MHz. Requesting clk_round_rate(clk, ULONG_MAX)
|
||||
is a bit of a special case, since that still returns correct values as
|
||||
long as the parent clock is below 8.5 GHz.
|
||||
|
||||
Fix this by switching to DIV_ROUND_UP_NO_OVERFLOW, which cannot
|
||||
overflow. This avoids any requirements on the arguments (except
|
||||
that divisor should not be 0 obviously).
|
||||
|
||||
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
---
|
||||
drivers/clk/clk-divider.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/clk/clk-divider.c
|
||||
+++ b/drivers/clk/clk-divider.c
|
||||
@@ -220,7 +220,7 @@ static int _div_round_up(const struct clk_div_table *table,
|
||||
unsigned long parent_rate, unsigned long rate,
|
||||
unsigned long flags)
|
||||
{
|
||||
- int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
|
||||
+ int div = DIV_ROUND_UP_NO_OVERFLOW(parent_rate, rate);
|
||||
|
||||
if (flags & CLK_DIVIDER_POWER_OF_TWO)
|
||||
div = __roundup_pow_of_two(div);
|
||||
@@ -237,7 +237,7 @@ static int _div_round_closest(const struct clk_div_table *table,
|
||||
int up, down;
|
||||
unsigned long up_rate, down_rate;
|
||||
|
||||
- up = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
|
||||
+ up = DIV_ROUND_UP_NO_OVERFLOW(parent_rate, rate);
|
||||
down = parent_rate / rate;
|
||||
|
||||
if (flags & CLK_DIVIDER_POWER_OF_TWO) {
|
||||
@@ -473,7 +473,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
|
||||
{
|
||||
unsigned int div, value;
|
||||
|
||||
- div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
|
||||
+ div = DIV_ROUND_UP_NO_OVERFLOW(parent_rate, rate);
|
||||
|
||||
if (!_is_valid_div(table, div, flags))
|
||||
return -EINVAL;
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
Date: Tue, 24 Oct 2023 18:09:57 +0200
|
||||
Subject: clk: composite: replace open-coded abs_diff()
|
||||
|
||||
Replace the open coded abs_diff() with the existing helper function.
|
||||
|
||||
Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
|
||||
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
---
|
||||
drivers/clk/clk-composite.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/clk/clk-composite.c
|
||||
+++ b/drivers/clk/clk-composite.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
+#include <linux/math.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static u8 clk_composite_get_parent(struct clk_hw *hw)
|
||||
@@ -119,10 +120,7 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
- if (req->rate >= tmp_req.rate)
|
||||
- rate_diff = req->rate - tmp_req.rate;
|
||||
- else
|
||||
- rate_diff = tmp_req.rate - req->rate;
|
||||
+ rate_diff = abs_diff(req->rate, tmp_req.rate);
|
||||
|
||||
if (!rate_diff || !req->best_parent_hw
|
||||
|| best_rate_diff > rate_diff) {
|
||||
--
|
||||
Armbian
|
||||
|
214
kernel.patches/0011-irqchip-fix-its-timeout-issue.patch
Normal file
214
kernel.patches/0011-irqchip-fix-its-timeout-issue.patch
Normal file
@ -0,0 +1,214 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Fri, 11 Aug 2023 17:56:00 +0300
|
||||
Subject: irqchip/irq-gic-v3-its: fix its timeout issue for rk35xx boards
|
||||
|
||||
---
|
||||
drivers/irqchip/irq-gic-v3-its.c | 79 +++++++++-
|
||||
1 file changed, 72 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/irqchip/irq-gic-v3-its.c
|
||||
+++ b/drivers/irqchip/irq-gic-v3-its.c
|
||||
@@ -163,6 +163,7 @@ struct its_device {
|
||||
struct its_node *its;
|
||||
struct event_lpi_map event_map;
|
||||
void *itt;
|
||||
+ u32 itt_sz;
|
||||
u32 nr_ites;
|
||||
u32 device_id;
|
||||
bool shared;
|
||||
@@ -2191,6 +2192,9 @@ static void gic_reset_prop_table(void *va)
|
||||
static struct page *its_allocate_prop_table(gfp_t gfp_flags)
|
||||
{
|
||||
struct page *prop_page;
|
||||
+
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ gfp_flags |= GFP_DMA32;
|
||||
|
||||
prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
|
||||
if (!prop_page)
|
||||
@@ -2315,6 +2319,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
|
||||
u32 alloc_pages, psz;
|
||||
struct page *page;
|
||||
void *base;
|
||||
+ gfp_t gfp_flags;
|
||||
|
||||
psz = baser->psz;
|
||||
alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
|
||||
@@ -2326,7 +2331,11 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
|
||||
order = get_order(GITS_BASER_PAGES_MAX * psz);
|
||||
}
|
||||
|
||||
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
|
||||
+ gfp_flags = GFP_KERNEL | __GFP_ZERO;
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ gfp_flags |= GFP_DMA32;
|
||||
+
|
||||
+ page = alloc_pages_node(its->numa_node, gfp_flags, order);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -2376,6 +2385,15 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
|
||||
its_write_baser(its, baser, val);
|
||||
tmp = baser->val;
|
||||
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3566") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3588")) {
|
||||
+ if (tmp & GITS_BASER_SHAREABILITY_MASK)
|
||||
+ tmp &= ~GITS_BASER_SHAREABILITY_MASK;
|
||||
+ else
|
||||
+ gic_flush_dcache_to_poc(base, PAGE_ORDER_TO_SIZE(order));
|
||||
+ }
|
||||
+
|
||||
if ((val ^ tmp) & GITS_BASER_SHAREABILITY_MASK) {
|
||||
/*
|
||||
* Shareability didn't stick. Just use
|
||||
@@ -2965,7 +2983,9 @@ static int its_alloc_collections(struct its_node *its)
|
||||
static struct page *its_allocate_pending_table(gfp_t gfp_flags)
|
||||
{
|
||||
struct page *pend_page;
|
||||
-
|
||||
+
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ gfp_flags |= GFP_DMA32;
|
||||
pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
|
||||
get_order(LPI_PENDBASE_SZ));
|
||||
if (!pend_page)
|
||||
@@ -3124,6 +3144,11 @@ static void its_cpu_init_lpis(void)
|
||||
if (!rdists_support_shareable())
|
||||
tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;
|
||||
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3566") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;
|
||||
+
|
||||
if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
|
||||
if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
|
||||
/*
|
||||
@@ -3151,6 +3176,11 @@ static void its_cpu_init_lpis(void)
|
||||
if (!rdists_support_shareable())
|
||||
tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
|
||||
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3566") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
|
||||
+
|
||||
if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
|
||||
/*
|
||||
* The HW reports non-shareable, we must remove the
|
||||
@@ -3314,7 +3344,11 @@ static bool its_alloc_table_entry(struct its_node *its,
|
||||
|
||||
/* Allocate memory for 2nd level table */
|
||||
if (!table[idx]) {
|
||||
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
|
||||
+ gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO;
|
||||
+
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ gfp_flags |= GFP_DMA32;
|
||||
+ page = alloc_pages_node(its->numa_node, gfp_flags,
|
||||
get_order(baser->psz));
|
||||
if (!page)
|
||||
return false;
|
||||
@@ -3403,6 +3437,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
|
||||
int nr_lpis;
|
||||
int nr_ites;
|
||||
int sz;
|
||||
+ gfp_t gfp_flags;
|
||||
|
||||
if (!its_alloc_device_table(its, dev_id))
|
||||
return NULL;
|
||||
@@ -3418,7 +3453,15 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
|
||||
nr_ites = max(2, nvecs);
|
||||
sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
|
||||
sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
|
||||
- itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
|
||||
+ gfp_flags = GFP_KERNEL;
|
||||
+
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588")) {
|
||||
+ gfp_flags |= GFP_DMA32;
|
||||
+ itt = (void *)__get_free_pages(gfp_flags, get_order(sz));
|
||||
+ } else {
|
||||
+ itt = kzalloc_node(sz, gfp_flags, its->numa_node);
|
||||
+ }
|
||||
+
|
||||
if (alloc_lpis) {
|
||||
lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
|
||||
if (lpi_map)
|
||||
@@ -3432,7 +3475,13 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
|
||||
|
||||
if (!dev || !itt || !col_map || (!lpi_map && alloc_lpis)) {
|
||||
kfree(dev);
|
||||
- kfree(itt);
|
||||
+
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ free_pages((unsigned long)itt, get_order(sz));
|
||||
+ else
|
||||
+ kfree(itt);
|
||||
+
|
||||
bitmap_free(lpi_map);
|
||||
kfree(col_map);
|
||||
return NULL;
|
||||
@@ -3442,6 +3491,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
|
||||
|
||||
dev->its = its;
|
||||
dev->itt = itt;
|
||||
+ dev->itt_sz = sz;
|
||||
dev->nr_ites = nr_ites;
|
||||
dev->event_map.lpi_map = lpi_map;
|
||||
dev->event_map.col_map = col_map;
|
||||
@@ -3469,7 +3519,13 @@ static void its_free_device(struct its_device *its_dev)
|
||||
list_del(&its_dev->entry);
|
||||
raw_spin_unlock_irqrestore(&its_dev->its->lock, flags);
|
||||
kfree(its_dev->event_map.col_map);
|
||||
- kfree(its_dev->itt);
|
||||
+
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ free_pages((unsigned long)its_dev->itt, get_order(its_dev->itt_sz));
|
||||
+ else
|
||||
+ kfree(its_dev->itt);
|
||||
+
|
||||
kfree(its_dev);
|
||||
}
|
||||
|
||||
@@ -5078,6 +5134,7 @@ static int __init its_probe_one(struct its_node *its)
|
||||
struct page *page;
|
||||
u32 ctlr;
|
||||
int err;
|
||||
+ gfp_t gfp_flags;
|
||||
|
||||
its_enable_quirks(its);
|
||||
|
||||
@@ -5111,7 +5168,10 @@ static int __init its_probe_one(struct its_node *its)
|
||||
}
|
||||
}
|
||||
|
||||
- page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
|
||||
+ gfp_flags = GFP_KERNEL | __GFP_ZERO;
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ gfp_flags |= GFP_DMA32;
|
||||
+ page = alloc_pages_node(its->numa_node, gfp_flags,
|
||||
get_order(ITS_CMD_QUEUE_SZ));
|
||||
if (!page) {
|
||||
err = -ENOMEM;
|
||||
@@ -5140,6 +5200,11 @@ static int __init its_probe_one(struct its_node *its)
|
||||
if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE)
|
||||
tmp &= ~GITS_CBASER_SHAREABILITY_MASK;
|
||||
|
||||
+ if (of_machine_is_compatible("rockchip,rk3568") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3566") ||
|
||||
+ of_machine_is_compatible("rockchip,rk3588"))
|
||||
+ tmp &= ~GITS_CBASER_SHAREABILITY_MASK;
|
||||
+
|
||||
if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
|
||||
if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
|
||||
/*
|
||||
--
|
||||
Armbian
|
||||
|
30
kernel.patches/0012-fix-initial-PERST-GPIO-value.patch
Normal file
30
kernel.patches/0012-fix-initial-PERST-GPIO-value.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: yangchaohong <45483831+yangchaohong@users.noreply.github.com>
|
||||
Date: Wed, 1 May 2024 08:30:43 +0100
|
||||
Subject: [ARCHEOLOGY] Fix PCIe for RK35xx+Fix ROCK5A PCIe device tree
|
||||
|
||||
> X-Git-Archeology: - Revision b1f648ee755de73a922a33d6a432f310ea4ff3e0: https://github.com/armbian/build/commit/b1f648ee755de73a922a33d6a432f310ea4ff3e0
|
||||
> X-Git-Archeology: Date: Wed, 01 May 2024 08:30:43 +0100
|
||||
> X-Git-Archeology: From: yangchaohong <45483831+yangchaohong@users.noreply.github.com>
|
||||
> X-Git-Archeology: Subject: Fix PCIe for RK35xx+Fix ROCK5A PCIe device tree
|
||||
> X-Git-Archeology:
|
||||
---
|
||||
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
|
||||
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
|
||||
@@ -240,7 +240,7 @@ static int rockchip_pcie_resource_get(struct platform_device *pdev,
|
||||
return PTR_ERR(rockchip->apb_base);
|
||||
|
||||
rockchip->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
|
||||
- GPIOD_OUT_HIGH);
|
||||
+ GPIOD_OUT_LOW);
|
||||
if (IS_ERR(rockchip->rst_gpio))
|
||||
return PTR_ERR(rockchip->rst_gpio);
|
||||
|
||||
--
|
||||
Armbian
|
||||
|
758
kernel.patches/0022-RK3588-Add-Thermal-and-CpuFreq-Support.patch
Normal file
758
kernel.patches/0022-RK3588-Add-Thermal-and-CpuFreq-Support.patch
Normal file
@ -0,0 +1,758 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Charkov <alchark@gmail.com>
|
||||
Date: Mon, 6 May 2024 13:36:32 +0400
|
||||
Subject: arm64: dts: rockchip: add thermal zones information on RK3588
|
||||
|
||||
This includes the necessary device tree data to allow thermal
|
||||
monitoring on RK3588(s) using the on-chip TSADC device, along with
|
||||
trip points for automatic thermal management.
|
||||
|
||||
Each of the CPU clusters (one for the little cores and two for
|
||||
the big cores) get a passive cooling trip point at 85C, which
|
||||
will trigger DVFS throttling of the respective cluster upon
|
||||
reaching a high temperature condition.
|
||||
|
||||
All zones also have a critical trip point at 115C, which will
|
||||
trigger a reset.
|
||||
|
||||
Signed-off-by: Alexey Charkov <alchark@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 147 ++++++++++
|
||||
1 file changed, 147 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <dt-bindings/reset/rockchip,rk3588-cru.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <dt-bindings/ata/ahci.h>
|
||||
+#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
/ {
|
||||
compatible = "rockchip,rk3588";
|
||||
@@ -2368,6 +2369,152 @@ pwm15: pwm@febf0030 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ thermal_zones: thermal-zones {
|
||||
+ /* sensor near the center of the SoC */
|
||||
+ package_thermal: package-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsadc 0>;
|
||||
+
|
||||
+ trips {
|
||||
+ package_crit: package-crit {
|
||||
+ temperature = <115000>;
|
||||
+ hysteresis = <0>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ /* sensor between A76 cores 0 and 1 */
|
||||
+ bigcore0_thermal: bigcore0-thermal {
|
||||
+ polling-delay-passive = <100>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsadc 1>;
|
||||
+
|
||||
+ trips {
|
||||
+ bigcore0_alert: bigcore0-alert {
|
||||
+ temperature = <85000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+ bigcore0_crit: bigcore0-crit {
|
||||
+ temperature = <115000>;
|
||||
+ hysteresis = <0>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ cooling-maps {
|
||||
+ map0 {
|
||||
+ trip = <&bigcore0_alert>;
|
||||
+ cooling-device =
|
||||
+ <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ /* sensor between A76 cores 2 and 3 */
|
||||
+ bigcore2_thermal: bigcore2-thermal {
|
||||
+ polling-delay-passive = <100>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsadc 2>;
|
||||
+
|
||||
+ trips {
|
||||
+ bigcore2_alert: bigcore2-alert {
|
||||
+ temperature = <85000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+ bigcore2_crit: bigcore2-crit {
|
||||
+ temperature = <115000>;
|
||||
+ hysteresis = <0>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ cooling-maps {
|
||||
+ map0 {
|
||||
+ trip = <&bigcore2_alert>;
|
||||
+ cooling-device =
|
||||
+ <&cpu_b2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu_b3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ /* sensor between the four A55 cores */
|
||||
+ little_core_thermal: littlecore-thermal {
|
||||
+ polling-delay-passive = <100>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsadc 3>;
|
||||
+
|
||||
+ trips {
|
||||
+ littlecore_alert: littlecore-alert {
|
||||
+ temperature = <85000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+ littlecore_crit: littlecore-crit {
|
||||
+ temperature = <115000>;
|
||||
+ hysteresis = <0>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ cooling-maps {
|
||||
+ map0 {
|
||||
+ trip = <&littlecore_alert>;
|
||||
+ cooling-device =
|
||||
+ <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu_l1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu_l2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu_l3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ /* sensor near the PD_CENTER power domain */
|
||||
+ center_thermal: center-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsadc 4>;
|
||||
+
|
||||
+ trips {
|
||||
+ center_crit: center-crit {
|
||||
+ temperature = <115000>;
|
||||
+ hysteresis = <0>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ gpu_thermal: gpu-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsadc 5>;
|
||||
+
|
||||
+ trips {
|
||||
+ gpu_crit: gpu-crit {
|
||||
+ temperature = <115000>;
|
||||
+ hysteresis = <0>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ npu_thermal: npu-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsadc 6>;
|
||||
+
|
||||
+ trips {
|
||||
+ npu_crit: npu-crit {
|
||||
+ temperature = <115000>;
|
||||
+ hysteresis = <0>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
tsadc: tsadc@fec00000 {
|
||||
compatible = "rockchip,rk3588-tsadc";
|
||||
reg = <0x0 0xfec00000 0x0 0x400>;
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Charkov <alchark@gmail.com>
|
||||
Date: Mon, 6 May 2024 13:36:33 +0400
|
||||
Subject: arm64: dts: rockchip: enable thermal management on all RK3588 boards
|
||||
|
||||
This enables the on-chip thermal monitoring sensor (TSADC) on all
|
||||
RK3588(s) boards that don't have it enabled yet. It provides temperature
|
||||
monitoring for the SoC and emergency thermal shutdowns, and is thus
|
||||
important to have in place before CPU DVFS is enabled, as high CPU
|
||||
operating performance points can overheat the chip quickly in the
|
||||
absence of thermal management.
|
||||
|
||||
Signed-off-by: Alexey Charkov <alchark@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts | 4 ++++
|
||||
arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi | 4 ++++
|
||||
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 4 ++++
|
||||
arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts | 4 ++++
|
||||
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 4 ++++
|
||||
arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts | 4 ++++
|
||||
arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi | 4 ++++
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 4 ++++
|
||||
8 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
@@ -673,6 +673,10 @@ regulator-state-mem {
|
||||
};
|
||||
};
|
||||
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&u2phy0 {
|
||||
status = "okay";
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
|
||||
@@ -466,3 +466,7 @@ regulator-state-mem {
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
||||
@@ -1131,6 +1131,10 @@ &sata0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&u2phy0 {
|
||||
status = "okay";
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts
|
||||
@@ -376,6 +376,10 @@ &sdmmc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&u2phy2 {
|
||||
status = "okay";
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
@@ -743,6 +743,10 @@ regulator-state-mem {
|
||||
};
|
||||
};
|
||||
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&uart2 {
|
||||
pinctrl-0 = <&uart2m0_xfer>;
|
||||
status = "okay";
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
|
||||
@@ -648,6 +648,10 @@ regulator-state-mem {
|
||||
};
|
||||
};
|
||||
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&u2phy2 {
|
||||
status = "okay";
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
|
||||
@@ -601,6 +601,10 @@ regulator-state-mem {
|
||||
};
|
||||
};
|
||||
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&uart2 {
|
||||
pinctrl-0 = <&uart2m0_xfer>;
|
||||
status = "okay";
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
@@ -699,6 +699,10 @@ regulator-state-mem {
|
||||
};
|
||||
};
|
||||
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&u2phy0 {
|
||||
status = "okay";
|
||||
};
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Charkov <alchark@gmail.com>
|
||||
Date: Mon, 6 May 2024 13:36:34 +0400
|
||||
Subject: arm64: dts: rockchip: add passive GPU cooling on RK3588
|
||||
|
||||
As the GPU support on RK3588 has been merged upstream, along with OPP
|
||||
values, add a corresponding cooling map for passive cooling using the GPU.
|
||||
|
||||
Signed-off-by: Alexey Charkov <alchark@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 14 +++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -2487,17 +2487,29 @@ center_crit: center-crit {
|
||||
};
|
||||
|
||||
gpu_thermal: gpu-thermal {
|
||||
- polling-delay-passive = <0>;
|
||||
+ polling-delay-passive = <100>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsadc 5>;
|
||||
|
||||
trips {
|
||||
+ gpu_alert: gpu-alert {
|
||||
+ temperature = <85000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
gpu_crit: gpu-crit {
|
||||
temperature = <115000>;
|
||||
hysteresis = <0>;
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
+ cooling-maps {
|
||||
+ map0 {
|
||||
+ trip = <&gpu_alert>;
|
||||
+ cooling-device =
|
||||
+ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
npu_thermal: npu-thermal {
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Charkov <alchark@gmail.com>
|
||||
Date: Mon, 6 May 2024 13:36:36 +0400
|
||||
Subject: arm64: dts: rockchip: Add CPU/memory regulator coupling for RK3588
|
||||
|
||||
RK3588 chips allow for their CPU cores to be powered by a different
|
||||
supply vs. their corresponding memory interfaces, and two of the
|
||||
boards currently upstream do that (EVB1 and QuartzPro64).
|
||||
|
||||
The voltage of the memory interface though has to match that of the
|
||||
CPU cores that use it, which downstream kernels achieve by the means
|
||||
of a custom cpufreq driver which adjusts both at the same time.
|
||||
|
||||
It seems that regulator coupling is a more appropriate generic
|
||||
interface for it, so this patch introduces coupling to affected
|
||||
device trees to ensure that memory interface voltage is also updated
|
||||
whenever cpufreq switches between CPU OPPs.
|
||||
|
||||
Note that other boards, such as Radxa Rock 5B, define both the CPU
|
||||
and memory interface regulators as aliases to the same DT node, so
|
||||
this doesn't apply there.
|
||||
|
||||
Signed-off-by: Alexey Charkov <alchark@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 12 ++++++++++
|
||||
arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts | 12 ++++++++++
|
||||
2 files changed, 24 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
|
||||
@@ -878,6 +878,8 @@ regulators {
|
||||
vdd_cpu_big1_s0: dcdc-reg1 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_big1_mem_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -890,6 +892,8 @@ regulator-state-mem {
|
||||
vdd_cpu_big0_s0: dcdc-reg2 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_big0_mem_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -902,6 +906,8 @@ regulator-state-mem {
|
||||
vdd_cpu_lit_s0: dcdc-reg3 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_lit_mem_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -926,6 +932,8 @@ regulator-state-mem {
|
||||
vdd_cpu_big1_mem_s0: dcdc-reg5 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_big1_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -939,6 +947,8 @@ regulator-state-mem {
|
||||
vdd_cpu_big0_mem_s0: dcdc-reg6 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_big0_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -963,6 +973,8 @@ regulator-state-mem {
|
||||
vdd_cpu_lit_mem_s0: dcdc-reg8 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_lit_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
|
||||
@@ -833,6 +833,8 @@ vdd_cpu_big1_s0: dcdc-reg1 {
|
||||
regulator-name = "vdd_cpu_big1_s0";
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_big1_mem_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -846,6 +848,8 @@ vdd_cpu_big0_s0: dcdc-reg2 {
|
||||
regulator-name = "vdd_cpu_big0_s0";
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_big0_mem_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -859,6 +863,8 @@ vdd_cpu_lit_s0: dcdc-reg3 {
|
||||
regulator-name = "vdd_cpu_lit_s0";
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_lit_mem_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -885,6 +891,8 @@ vdd_cpu_big1_mem_s0: dcdc-reg5 {
|
||||
regulator-name = "vdd_cpu_big1_mem_s0";
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_big1_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -899,6 +907,8 @@ vdd_cpu_big0_mem_s0: dcdc-reg6 {
|
||||
regulator-name = "vdd_cpu_big0_mem_s0";
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_big0_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
@@ -925,6 +935,8 @@ vdd_cpu_lit_mem_s0: dcdc-reg8 {
|
||||
regulator-name = "vdd_cpu_lit_mem_s0";
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
+ regulator-coupled-with = <&vdd_cpu_lit_s0>;
|
||||
+ regulator-coupled-max-spread = <10000>;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Charkov <alchark@gmail.com>
|
||||
Date: Mon, 6 May 2024 13:36:37 +0400
|
||||
Subject: arm64: dts: rockchip: Add OPP data for CPU cores on RK3588
|
||||
|
||||
By default the CPUs on RK3588 start up in a conservative performance
|
||||
mode. Add frequency and voltage mappings to the device tree to enable
|
||||
dynamic scaling via cpufreq.
|
||||
|
||||
OPP values are adapted from Radxa's downstream kernel for Rock 5B [1],
|
||||
stripping them down to the minimum frequency and voltage combinations
|
||||
as expected by the generic upstream cpufreq-dt driver, and also dropping
|
||||
those OPPs that don't differ in voltage but only in frequency (keeping
|
||||
the top frequency OPP in each case).
|
||||
|
||||
Note that this patch ignores voltage scaling for the CPU memory
|
||||
interface which the downstream kernel does through a custom cpufreq
|
||||
driver, and which is why the downstream version has two sets of voltage
|
||||
values for each OPP (the second one being meant for the memory
|
||||
interface supply regulator). This is done instead via regulator
|
||||
coupling between CPU and memory interface supplies on affected boards.
|
||||
|
||||
This has been tested on Rock 5B with u-boot 2023.11 compiled from
|
||||
Collabora's integration tree [2] with binary bl31 and appears to be
|
||||
stable both under active cooling and passive cooling (with throttling)
|
||||
|
||||
[1] https://github.com/radxa/kernel/blob/stable-5.10-rock5/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
[2] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/u-boot
|
||||
|
||||
Signed-off-by: Alexey Charkov <alchark@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 122 ++++++++++
|
||||
1 file changed, 122 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -97,6 +97,7 @@ cpu_l0: cpu@0 {
|
||||
clocks = <&scmi_clk SCMI_CLK_CPUL>;
|
||||
assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>;
|
||||
assigned-clock-rates = <816000000>;
|
||||
+ operating-points-v2 = <&cluster0_opp_table>;
|
||||
cpu-idle-states = <&CPU_SLEEP>;
|
||||
i-cache-size = <32768>;
|
||||
i-cache-line-size = <64>;
|
||||
@@ -116,6 +117,7 @@ cpu_l1: cpu@100 {
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <530>;
|
||||
clocks = <&scmi_clk SCMI_CLK_CPUL>;
|
||||
+ operating-points-v2 = <&cluster0_opp_table>;
|
||||
cpu-idle-states = <&CPU_SLEEP>;
|
||||
i-cache-size = <32768>;
|
||||
i-cache-line-size = <64>;
|
||||
@@ -135,6 +137,7 @@ cpu_l2: cpu@200 {
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <530>;
|
||||
clocks = <&scmi_clk SCMI_CLK_CPUL>;
|
||||
+ operating-points-v2 = <&cluster0_opp_table>;
|
||||
cpu-idle-states = <&CPU_SLEEP>;
|
||||
i-cache-size = <32768>;
|
||||
i-cache-line-size = <64>;
|
||||
@@ -154,6 +157,7 @@ cpu_l3: cpu@300 {
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <530>;
|
||||
clocks = <&scmi_clk SCMI_CLK_CPUL>;
|
||||
+ operating-points-v2 = <&cluster0_opp_table>;
|
||||
cpu-idle-states = <&CPU_SLEEP>;
|
||||
i-cache-size = <32768>;
|
||||
i-cache-line-size = <64>;
|
||||
@@ -175,6 +179,7 @@ cpu_b0: cpu@400 {
|
||||
clocks = <&scmi_clk SCMI_CLK_CPUB01>;
|
||||
assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>;
|
||||
assigned-clock-rates = <816000000>;
|
||||
+ operating-points-v2 = <&cluster1_opp_table>;
|
||||
cpu-idle-states = <&CPU_SLEEP>;
|
||||
i-cache-size = <65536>;
|
||||
i-cache-line-size = <64>;
|
||||
@@ -194,6 +199,7 @@ cpu_b1: cpu@500 {
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
clocks = <&scmi_clk SCMI_CLK_CPUB01>;
|
||||
+ operating-points-v2 = <&cluster1_opp_table>;
|
||||
cpu-idle-states = <&CPU_SLEEP>;
|
||||
i-cache-size = <65536>;
|
||||
i-cache-line-size = <64>;
|
||||
@@ -215,6 +221,7 @@ cpu_b2: cpu@600 {
|
||||
clocks = <&scmi_clk SCMI_CLK_CPUB23>;
|
||||
assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>;
|
||||
assigned-clock-rates = <816000000>;
|
||||
+ operating-points-v2 = <&cluster2_opp_table>;
|
||||
cpu-idle-states = <&CPU_SLEEP>;
|
||||
i-cache-size = <65536>;
|
||||
i-cache-line-size = <64>;
|
||||
@@ -234,6 +241,7 @@ cpu_b3: cpu@700 {
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
clocks = <&scmi_clk SCMI_CLK_CPUB23>;
|
||||
+ operating-points-v2 = <&cluster2_opp_table>;
|
||||
cpu-idle-states = <&CPU_SLEEP>;
|
||||
i-cache-size = <65536>;
|
||||
i-cache-line-size = <64>;
|
||||
@@ -348,6 +356,120 @@ l3_cache: l3-cache {
|
||||
};
|
||||
};
|
||||
|
||||
+ cluster0_opp_table: opp-table-cluster0 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp-1008000000 {
|
||||
+ opp-hz = /bits/ 64 <1008000000>;
|
||||
+ opp-microvolt = <675000 675000 950000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1200000000 {
|
||||
+ opp-hz = /bits/ 64 <1200000000>;
|
||||
+ opp-microvolt = <712500 712500 950000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1416000000 {
|
||||
+ opp-hz = /bits/ 64 <1416000000>;
|
||||
+ opp-microvolt = <762500 762500 950000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ opp-suspend;
|
||||
+ };
|
||||
+ opp-1608000000 {
|
||||
+ opp-hz = /bits/ 64 <1608000000>;
|
||||
+ opp-microvolt = <850000 850000 950000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1800000000 {
|
||||
+ opp-hz = /bits/ 64 <1800000000>;
|
||||
+ opp-microvolt = <950000 950000 950000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cluster1_opp_table: opp-table-cluster1 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp-1200000000 {
|
||||
+ opp-hz = /bits/ 64 <1200000000>;
|
||||
+ opp-microvolt = <675000 675000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1416000000 {
|
||||
+ opp-hz = /bits/ 64 <1416000000>;
|
||||
+ opp-microvolt = <725000 725000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1608000000 {
|
||||
+ opp-hz = /bits/ 64 <1608000000>;
|
||||
+ opp-microvolt = <762500 762500 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1800000000 {
|
||||
+ opp-hz = /bits/ 64 <1800000000>;
|
||||
+ opp-microvolt = <850000 850000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-2016000000 {
|
||||
+ opp-hz = /bits/ 64 <2016000000>;
|
||||
+ opp-microvolt = <925000 925000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-2208000000 {
|
||||
+ opp-hz = /bits/ 64 <2208000000>;
|
||||
+ opp-microvolt = <987500 987500 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-2400000000 {
|
||||
+ opp-hz = /bits/ 64 <2400000000>;
|
||||
+ opp-microvolt = <1000000 1000000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cluster2_opp_table: opp-table-cluster2 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp-1200000000 {
|
||||
+ opp-hz = /bits/ 64 <1200000000>;
|
||||
+ opp-microvolt = <675000 675000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1416000000 {
|
||||
+ opp-hz = /bits/ 64 <1416000000>;
|
||||
+ opp-microvolt = <725000 725000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1608000000 {
|
||||
+ opp-hz = /bits/ 64 <1608000000>;
|
||||
+ opp-microvolt = <762500 762500 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-1800000000 {
|
||||
+ opp-hz = /bits/ 64 <1800000000>;
|
||||
+ opp-microvolt = <850000 850000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-2016000000 {
|
||||
+ opp-hz = /bits/ 64 <2016000000>;
|
||||
+ opp-microvolt = <925000 925000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-2208000000 {
|
||||
+ opp-hz = /bits/ 64 <2208000000>;
|
||||
+ opp-microvolt = <987500 987500 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ opp-2400000000 {
|
||||
+ opp-hz = /bits/ 64 <2400000000>;
|
||||
+ opp-microvolt = <1000000 1000000 1000000>;
|
||||
+ clock-latency-ns = <40000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
display_subsystem: display-subsystem {
|
||||
compatible = "rockchip,display-subsystem";
|
||||
ports = <&vop_out>;
|
||||
--
|
||||
Armbian
|
||||
|
2328
kernel.patches/0024-RK3588-Add-Crypto-Support.patch
Normal file
2328
kernel.patches/0024-RK3588-Add-Crypto-Support.patch
Normal file
File diff suppressed because it is too large
Load Diff
663
kernel.patches/0025-RK3588-Add-HW-RNG-Support.patch
Normal file
663
kernel.patches/0025-RK3588-Add-HW-RNG-Support.patch
Normal file
@ -0,0 +1,663 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Thu, 16 Nov 2023 17:49:42 +0300
|
||||
Subject: hwrng: rockchip: Add support for Rockchip HW RNG
|
||||
|
||||
---
|
||||
drivers/char/hw_random/Kconfig | 13 +
|
||||
drivers/char/hw_random/Makefile | 1 +
|
||||
drivers/char/hw_random/rockchip-rng.c | 574 ++++++++++
|
||||
3 files changed, 588 insertions(+)
|
||||
|
||||
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/char/hw_random/Kconfig
|
||||
+++ b/drivers/char/hw_random/Kconfig
|
||||
@@ -538,6 +538,19 @@ config HW_RANDOM_XIPHERA
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called xiphera-trng.
|
||||
|
||||
+config HW_RANDOM_ROCKCHIP
|
||||
+ tristate "Rockchip Random Number Generator support"
|
||||
+ depends on ARCH_ROCKCHIP
|
||||
+ default HW_RANDOM
|
||||
+ help
|
||||
+ This driver provides kernel-side support for the Random Number
|
||||
+ Generator hardware found on Rockchip cpus.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called rockchip-rng.
|
||||
+
|
||||
+ If unsure, say Y.
|
||||
+
|
||||
config HW_RANDOM_ARM_SMCCC_TRNG
|
||||
tristate "Arm SMCCC TRNG firmware interface support"
|
||||
depends on HAVE_ARM_SMCCC_DISCOVERY
|
||||
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/char/hw_random/Makefile
|
||||
+++ b/drivers/char/hw_random/Makefile
|
||||
@@ -35,6 +35,7 @@ obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
|
||||
obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o
|
||||
+obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o
|
||||
diff --git a/drivers/char/hw_random/rockchip-rng.c b/drivers/char/hw_random/rockchip-rng.c
|
||||
new file mode 100644
|
||||
index 000000000000..111111111111
|
||||
--- /dev/null
|
||||
+++ b/drivers/char/hw_random/rockchip-rng.c
|
||||
@@ -0,0 +1,574 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * rockchip-rng.c Random Number Generator driver for the Rockchip
|
||||
+ *
|
||||
+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd.
|
||||
+ * Author: Lin Jinhan <troy.lin@rock-chips.com>
|
||||
+ *
|
||||
+ */
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/hw_random.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+
|
||||
+#define _SBF(s, v) ((v) << (s))
|
||||
+#define HIWORD_UPDATE(val, mask, shift) \
|
||||
+ ((val) << (shift) | (mask) << ((shift) + 16))
|
||||
+
|
||||
+#define ROCKCHIP_AUTOSUSPEND_DELAY 100
|
||||
+#define ROCKCHIP_POLL_PERIOD_US 100
|
||||
+#define ROCKCHIP_POLL_TIMEOUT_US 50000
|
||||
+#define RK_MAX_RNG_BYTE (32)
|
||||
+
|
||||
+/* start of CRYPTO V1 register define */
|
||||
+#define CRYPTO_V1_CTRL 0x0008
|
||||
+#define CRYPTO_V1_RNG_START BIT(8)
|
||||
+#define CRYPTO_V1_RNG_FLUSH BIT(9)
|
||||
+
|
||||
+#define CRYPTO_V1_TRNG_CTRL 0x0200
|
||||
+#define CRYPTO_V1_OSC_ENABLE BIT(16)
|
||||
+#define CRYPTO_V1_TRNG_SAMPLE_PERIOD(x) (x)
|
||||
+
|
||||
+#define CRYPTO_V1_TRNG_DOUT_0 0x0204
|
||||
+/* end of CRYPTO V1 register define */
|
||||
+
|
||||
+/* start of CRYPTO V2 register define */
|
||||
+#define CRYPTO_V2_RNG_DEFAULT_OFFSET 0x0400
|
||||
+#define CRYPTO_V2_RNG_CTL 0x0
|
||||
+#define CRYPTO_V2_RNG_64_BIT_LEN _SBF(4, 0x00)
|
||||
+#define CRYPTO_V2_RNG_128_BIT_LEN _SBF(4, 0x01)
|
||||
+#define CRYPTO_V2_RNG_192_BIT_LEN _SBF(4, 0x02)
|
||||
+#define CRYPTO_V2_RNG_256_BIT_LEN _SBF(4, 0x03)
|
||||
+#define CRYPTO_V2_RNG_FATESY_SOC_RING _SBF(2, 0x00)
|
||||
+#define CRYPTO_V2_RNG_SLOWER_SOC_RING_0 _SBF(2, 0x01)
|
||||
+#define CRYPTO_V2_RNG_SLOWER_SOC_RING_1 _SBF(2, 0x02)
|
||||
+#define CRYPTO_V2_RNG_SLOWEST_SOC_RING _SBF(2, 0x03)
|
||||
+#define CRYPTO_V2_RNG_ENABLE BIT(1)
|
||||
+#define CRYPTO_V2_RNG_START BIT(0)
|
||||
+#define CRYPTO_V2_RNG_SAMPLE_CNT 0x0004
|
||||
+#define CRYPTO_V2_RNG_DOUT_0 0x0010
|
||||
+/* end of CRYPTO V2 register define */
|
||||
+
|
||||
+/* start of TRNG_V1 register define */
|
||||
+/* TRNG is no longer subordinate to the Crypto module */
|
||||
+#define TRNG_V1_CTRL 0x0000
|
||||
+#define TRNG_V1_CTRL_NOP _SBF(0, 0x00)
|
||||
+#define TRNG_V1_CTRL_RAND _SBF(0, 0x01)
|
||||
+#define TRNG_V1_CTRL_SEED _SBF(0, 0x02)
|
||||
+
|
||||
+#define TRNG_V1_STAT 0x0004
|
||||
+#define TRNG_V1_STAT_SEEDED BIT(9)
|
||||
+#define TRNG_V1_STAT_GENERATING BIT(30)
|
||||
+#define TRNG_V1_STAT_RESEEDING BIT(31)
|
||||
+
|
||||
+#define TRNG_V1_MODE 0x0008
|
||||
+#define TRNG_V1_MODE_128_BIT _SBF(3, 0x00)
|
||||
+#define TRNG_V1_MODE_256_BIT _SBF(3, 0x01)
|
||||
+
|
||||
+#define TRNG_V1_IE 0x0010
|
||||
+#define TRNG_V1_IE_GLBL_EN BIT(31)
|
||||
+#define TRNG_V1_IE_SEED_DONE_EN BIT(1)
|
||||
+#define TRNG_V1_IE_RAND_RDY_EN BIT(0)
|
||||
+
|
||||
+#define TRNG_V1_ISTAT 0x0014
|
||||
+#define TRNG_V1_ISTAT_RAND_RDY BIT(0)
|
||||
+
|
||||
+/* RAND0 ~ RAND7 */
|
||||
+#define TRNG_V1_RAND0 0x0020
|
||||
+#define TRNG_V1_RAND7 0x003C
|
||||
+
|
||||
+#define TRNG_V1_AUTO_RQSTS 0x0060
|
||||
+
|
||||
+#define TRNG_V1_VERSION 0x00F0
|
||||
+#define TRNG_v1_VERSION_CODE 0x46bc
|
||||
+/* end of TRNG_V1 register define */
|
||||
+
|
||||
+/* start of RKRNG register define */
|
||||
+#define RKRNG_CTRL 0x0010
|
||||
+#define RKRNG_CTRL_INST_REQ BIT(0)
|
||||
+#define RKRNG_CTRL_RESEED_REQ BIT(1)
|
||||
+#define RKRNG_CTRL_TEST_REQ BIT(2)
|
||||
+#define RKRNG_CTRL_SW_DRNG_REQ BIT(3)
|
||||
+#define RKRNG_CTRL_SW_TRNG_REQ BIT(4)
|
||||
+
|
||||
+#define RKRNG_STATE 0x0014
|
||||
+#define RKRNG_STATE_INST_ACK BIT(0)
|
||||
+#define RKRNG_STATE_RESEED_ACK BIT(1)
|
||||
+#define RKRNG_STATE_TEST_ACK BIT(2)
|
||||
+#define RKRNG_STATE_SW_DRNG_ACK BIT(3)
|
||||
+#define RKRNG_STATE_SW_TRNG_ACK BIT(4)
|
||||
+
|
||||
+/* DRNG_DATA_0 ~ DNG_DATA_7 */
|
||||
+#define RKRNG_DRNG_DATA_0 0x0070
|
||||
+#define RKRNG_DRNG_DATA_7 0x008C
|
||||
+
|
||||
+/* end of RKRNG register define */
|
||||
+
|
||||
+struct rk_rng_soc_data {
|
||||
+ u32 default_offset;
|
||||
+
|
||||
+ int (*rk_rng_init)(struct hwrng *rng);
|
||||
+ int (*rk_rng_read)(struct hwrng *rng, void *buf, size_t max, bool wait);
|
||||
+};
|
||||
+
|
||||
+struct rk_rng {
|
||||
+ struct device *dev;
|
||||
+ struct hwrng rng;
|
||||
+ void __iomem *mem;
|
||||
+ struct rk_rng_soc_data *soc_data;
|
||||
+ int clk_num;
|
||||
+ struct clk_bulk_data *clk_bulks;
|
||||
+};
|
||||
+
|
||||
+static void rk_rng_writel(struct rk_rng *rng, u32 val, u32 offset)
|
||||
+{
|
||||
+ __raw_writel(val, rng->mem + offset);
|
||||
+}
|
||||
+
|
||||
+static u32 rk_rng_readl(struct rk_rng *rng, u32 offset)
|
||||
+{
|
||||
+ return __raw_readl(rng->mem + offset);
|
||||
+}
|
||||
+
|
||||
+static int rk_rng_init(struct hwrng *rng)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+
|
||||
+ dev_dbg(rk_rng->dev, "clk_bulk_prepare_enable.\n");
|
||||
+
|
||||
+ ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(rk_rng->dev, "failed to enable clks %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void rk_rng_cleanup(struct hwrng *rng)
|
||||
+{
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+
|
||||
+ dev_dbg(rk_rng->dev, "clk_bulk_disable_unprepare.\n");
|
||||
+ clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
|
||||
+}
|
||||
+
|
||||
+static int rk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int read_len = 0;
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+
|
||||
+ if (!rk_rng->soc_data->rk_rng_read)
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ ret = pm_runtime_get_sync(rk_rng->dev);
|
||||
+ if (ret < 0) {
|
||||
+ pm_runtime_put_noidle(rk_rng->dev);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+ while (max > ret) {
|
||||
+ read_len = rk_rng->soc_data->rk_rng_read(rng, buf + ret,
|
||||
+ max - ret, wait);
|
||||
+ if (read_len < 0) {
|
||||
+ ret = read_len;
|
||||
+ break;
|
||||
+ }
|
||||
+ ret += read_len;
|
||||
+ }
|
||||
+
|
||||
+ pm_runtime_mark_last_busy(rk_rng->dev);
|
||||
+ pm_runtime_put_sync_autosuspend(rk_rng->dev);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void rk_rng_read_regs(struct rk_rng *rng, u32 offset, void *buf,
|
||||
+ size_t size)
|
||||
+{
|
||||
+ u32 i;
|
||||
+
|
||||
+ for (i = 0; i < size; i += 4)
|
||||
+ *(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i));
|
||||
+}
|
||||
+
|
||||
+static int crypto_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ u32 reg_ctrl = 0;
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+
|
||||
+ /* enable osc_ring to get entropy, sample period is set as 100 */
|
||||
+ reg_ctrl = CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100);
|
||||
+ rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_TRNG_CTRL);
|
||||
+
|
||||
+ reg_ctrl = HIWORD_UPDATE(CRYPTO_V1_RNG_START, CRYPTO_V1_RNG_START, 0);
|
||||
+
|
||||
+ rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL);
|
||||
+
|
||||
+ ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
|
||||
+ !(reg_ctrl & CRYPTO_V1_RNG_START),
|
||||
+ ROCKCHIP_POLL_PERIOD_US,
|
||||
+ ROCKCHIP_POLL_TIMEOUT_US, false,
|
||||
+ rk_rng, CRYPTO_V1_CTRL);
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = min_t(size_t, max, RK_MAX_RNG_BYTE);
|
||||
+
|
||||
+ rk_rng_read_regs(rk_rng, CRYPTO_V1_TRNG_DOUT_0, buf, ret);
|
||||
+
|
||||
+out:
|
||||
+ /* close TRNG */
|
||||
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, CRYPTO_V1_RNG_START, 0),
|
||||
+ CRYPTO_V1_CTRL);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int crypto_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ u32 reg_ctrl = 0;
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+
|
||||
+ /* enable osc_ring to get entropy, sample period is set as 100 */
|
||||
+ rk_rng_writel(rk_rng, 100, CRYPTO_V2_RNG_SAMPLE_CNT);
|
||||
+
|
||||
+ reg_ctrl |= CRYPTO_V2_RNG_256_BIT_LEN;
|
||||
+ reg_ctrl |= CRYPTO_V2_RNG_SLOWER_SOC_RING_0;
|
||||
+ reg_ctrl |= CRYPTO_V2_RNG_ENABLE;
|
||||
+ reg_ctrl |= CRYPTO_V2_RNG_START;
|
||||
+
|
||||
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0),
|
||||
+ CRYPTO_V2_RNG_CTL);
|
||||
+
|
||||
+ ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
|
||||
+ !(reg_ctrl & CRYPTO_V2_RNG_START),
|
||||
+ ROCKCHIP_POLL_PERIOD_US,
|
||||
+ ROCKCHIP_POLL_TIMEOUT_US, false,
|
||||
+ rk_rng, CRYPTO_V2_RNG_CTL);
|
||||
+ if (ret < 0)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = min_t(size_t, max, RK_MAX_RNG_BYTE);
|
||||
+
|
||||
+ rk_rng_read_regs(rk_rng, CRYPTO_V2_RNG_DOUT_0, buf, ret);
|
||||
+
|
||||
+out:
|
||||
+ /* close TRNG */
|
||||
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_V2_RNG_CTL);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int trng_v1_init(struct hwrng *rng)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint32_t auto_reseed_cnt = 1000;
|
||||
+ uint32_t reg_ctrl, status, version;
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+
|
||||
+ version = rk_rng_readl(rk_rng, TRNG_V1_VERSION);
|
||||
+ if (version != TRNG_v1_VERSION_CODE) {
|
||||
+ dev_err(rk_rng->dev,
|
||||
+ "wrong trng version, expected = %08x, actual = %08x\n",
|
||||
+ TRNG_V1_VERSION, version);
|
||||
+ ret = -EFAULT;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ status = rk_rng_readl(rk_rng, TRNG_V1_STAT);
|
||||
+
|
||||
+ /* TRNG should wait RAND_RDY triggered if it is busy or not seeded */
|
||||
+ if (!(status & TRNG_V1_STAT_SEEDED) ||
|
||||
+ (status & TRNG_V1_STAT_GENERATING) ||
|
||||
+ (status & TRNG_V1_STAT_RESEEDING)) {
|
||||
+ uint32_t mask = TRNG_V1_STAT_SEEDED |
|
||||
+ TRNG_V1_STAT_GENERATING |
|
||||
+ TRNG_V1_STAT_RESEEDING;
|
||||
+
|
||||
+ udelay(10);
|
||||
+
|
||||
+ /* wait for GENERATING and RESEEDING flag to clear */
|
||||
+ read_poll_timeout(rk_rng_readl, reg_ctrl,
|
||||
+ (reg_ctrl & mask) == TRNG_V1_STAT_SEEDED,
|
||||
+ ROCKCHIP_POLL_PERIOD_US,
|
||||
+ ROCKCHIP_POLL_TIMEOUT_US, false,
|
||||
+ rk_rng, TRNG_V1_STAT);
|
||||
+ }
|
||||
+
|
||||
+ /* clear ISTAT flag because trng may auto reseeding when power on */
|
||||
+ reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT);
|
||||
+ rk_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
|
||||
+
|
||||
+ /* auto reseed after (auto_reseed_cnt * 16) byte rand generate */
|
||||
+ rk_rng_writel(rk_rng, auto_reseed_cnt, TRNG_V1_AUTO_RQSTS);
|
||||
+
|
||||
+ ret = 0;
|
||||
+exit:
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int trng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ u32 reg_ctrl = 0;
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+
|
||||
+ /* clear ISTAT anyway */
|
||||
+ reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT);
|
||||
+ rk_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
|
||||
+
|
||||
+ /* generate 256bit random */
|
||||
+ rk_rng_writel(rk_rng, TRNG_V1_MODE_256_BIT, TRNG_V1_MODE);
|
||||
+ rk_rng_writel(rk_rng, TRNG_V1_CTRL_RAND, TRNG_V1_CTRL);
|
||||
+
|
||||
+ /*
|
||||
+ * Generate2 56 bit random data will cost 1024 clock cycles.
|
||||
+ * Estimated at 150M RNG module frequency, it takes 6.7 microseconds.
|
||||
+ */
|
||||
+ udelay(10);
|
||||
+ reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT);
|
||||
+ if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY)) {
|
||||
+ /* wait RAND_RDY triggered */
|
||||
+ ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
|
||||
+ (reg_ctrl & TRNG_V1_ISTAT_RAND_RDY),
|
||||
+ ROCKCHIP_POLL_PERIOD_US,
|
||||
+ ROCKCHIP_POLL_TIMEOUT_US, false,
|
||||
+ rk_rng, TRNG_V1_ISTAT);
|
||||
+ if (ret < 0)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = min_t(size_t, max, RK_MAX_RNG_BYTE);
|
||||
+
|
||||
+ rk_rng_read_regs(rk_rng, TRNG_V1_RAND0, buf, ret);
|
||||
+
|
||||
+ /* clear all status flag */
|
||||
+ rk_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
|
||||
+out:
|
||||
+ /* close TRNG */
|
||||
+ rk_rng_writel(rk_rng, TRNG_V1_CTRL_NOP, TRNG_V1_CTRL);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rkrng_init(struct hwrng *rng)
|
||||
+{
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+ u32 reg = 0;
|
||||
+
|
||||
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL);
|
||||
+
|
||||
+ reg = rk_rng_readl(rk_rng, RKRNG_STATE);
|
||||
+ rk_rng_writel(rk_rng, reg, RKRNG_STATE);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rkrng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
|
||||
+{
|
||||
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
|
||||
+ u32 reg_ctrl = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ reg_ctrl = RKRNG_CTRL_SW_DRNG_REQ;
|
||||
+
|
||||
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), RKRNG_CTRL);
|
||||
+
|
||||
+ ret = readl_poll_timeout(rk_rng->mem + RKRNG_STATE, reg_ctrl,
|
||||
+ (reg_ctrl & RKRNG_STATE_SW_DRNG_ACK),
|
||||
+ ROCKCHIP_POLL_PERIOD_US,
|
||||
+ ROCKCHIP_POLL_TIMEOUT_US);
|
||||
+
|
||||
+ if (ret)
|
||||
+ goto exit;
|
||||
+
|
||||
+ rk_rng_writel(rk_rng, reg_ctrl, RKRNG_STATE);
|
||||
+
|
||||
+ ret = min_t(size_t, max, RK_MAX_RNG_BYTE);
|
||||
+
|
||||
+ rk_rng_read_regs(rk_rng, RKRNG_DRNG_DATA_0, buf, ret);
|
||||
+
|
||||
+exit:
|
||||
+ /* close TRNG */
|
||||
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct rk_rng_soc_data crypto_v1_soc_data = {
|
||||
+ .default_offset = 0,
|
||||
+
|
||||
+ .rk_rng_read = crypto_v1_read,
|
||||
+};
|
||||
+
|
||||
+static const struct rk_rng_soc_data crypto_v2_soc_data = {
|
||||
+ .default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET,
|
||||
+
|
||||
+ .rk_rng_read = crypto_v2_read,
|
||||
+};
|
||||
+
|
||||
+static const struct rk_rng_soc_data trng_v1_soc_data = {
|
||||
+ .default_offset = 0,
|
||||
+
|
||||
+ .rk_rng_init = trng_v1_init,
|
||||
+ .rk_rng_read = trng_v1_read,
|
||||
+};
|
||||
+
|
||||
+static const struct rk_rng_soc_data rkrng_soc_data = {
|
||||
+ .default_offset = 0,
|
||||
+
|
||||
+ .rk_rng_init = rkrng_init,
|
||||
+ .rk_rng_read = rkrng_read,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id rk_rng_dt_match[] = {
|
||||
+ {
|
||||
+ .compatible = "rockchip,cryptov1-rng",
|
||||
+ .data = (void *)&crypto_v1_soc_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "rockchip,cryptov2-rng",
|
||||
+ .data = (void *)&crypto_v2_soc_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "rockchip,trngv1",
|
||||
+ .data = (void *)&trng_v1_soc_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "rockchip,rkrng",
|
||||
+ .data = (void *)&rkrng_soc_data,
|
||||
+ },
|
||||
+ { },
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, rk_rng_dt_match);
|
||||
+
|
||||
+static int rk_rng_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct rk_rng *rk_rng;
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ const struct of_device_id *match;
|
||||
+ resource_size_t map_size;
|
||||
+
|
||||
+ dev_dbg(&pdev->dev, "probing...\n");
|
||||
+ rk_rng = devm_kzalloc(&pdev->dev, sizeof(struct rk_rng), GFP_KERNEL);
|
||||
+ if (!rk_rng)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ match = of_match_node(rk_rng_dt_match, np);
|
||||
+ rk_rng->soc_data = (struct rk_rng_soc_data *)match->data;
|
||||
+
|
||||
+ rk_rng->dev = &pdev->dev;
|
||||
+ rk_rng->rng.name = "rockchip";
|
||||
+#ifndef CONFIG_PM
|
||||
+ rk_rng->rng.init = rk_rng_init;
|
||||
+ rk_rng->rng.cleanup = rk_rng_cleanup,
|
||||
+#endif
|
||||
+ rk_rng->rng.read = rk_rng_read;
|
||||
+ rk_rng->rng.quality = 999;
|
||||
+
|
||||
+ rk_rng->mem = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, &map_size);
|
||||
+ if (IS_ERR(rk_rng->mem))
|
||||
+ return PTR_ERR(rk_rng->mem);
|
||||
+
|
||||
+ /* compatible with crypto v2 module */
|
||||
+ /*
|
||||
+ * With old dtsi configurations, the RNG base was equal to the crypto
|
||||
+ * base, so both drivers could not be enabled at the same time.
|
||||
+ * RNG base = CRYPTO base + RNG offset
|
||||
+ * (Since RK356X, RNG module is no longer belongs to CRYPTO module)
|
||||
+ *
|
||||
+ * With new dtsi configurations, CRYPTO regs is divided into two parts
|
||||
+ * |---cipher---|---rng---|---pka---|, and RNG base is real RNG base.
|
||||
+ * RNG driver and CRYPTO driver could be enabled at the same time.
|
||||
+ */
|
||||
+ if (map_size > rk_rng->soc_data->default_offset)
|
||||
+ rk_rng->mem += rk_rng->soc_data->default_offset;
|
||||
+
|
||||
+ rk_rng->clk_num = devm_clk_bulk_get_all(&pdev->dev, &rk_rng->clk_bulks);
|
||||
+ if (rk_rng->clk_num < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to get clks property\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, rk_rng);
|
||||
+
|
||||
+ pm_runtime_set_autosuspend_delay(&pdev->dev,
|
||||
+ ROCKCHIP_AUTOSUSPEND_DELAY);
|
||||
+ pm_runtime_use_autosuspend(&pdev->dev);
|
||||
+ pm_runtime_enable(&pdev->dev);
|
||||
+
|
||||
+ ret = devm_hwrng_register(&pdev->dev, &rk_rng->rng);
|
||||
+ if (ret) {
|
||||
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+ }
|
||||
+
|
||||
+ /* for some platform need hardware operation when probe */
|
||||
+ if (rk_rng->soc_data->rk_rng_init) {
|
||||
+ pm_runtime_get_sync(rk_rng->dev);
|
||||
+
|
||||
+ ret = rk_rng->soc_data->rk_rng_init(&rk_rng->rng);
|
||||
+
|
||||
+ pm_runtime_mark_last_busy(rk_rng->dev);
|
||||
+ pm_runtime_put_sync_autosuspend(rk_rng->dev);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int rk_rng_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct rk_rng *rk_rng = dev_get_drvdata(dev);
|
||||
+
|
||||
+ rk_rng_cleanup(&rk_rng->rng);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rk_rng_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct rk_rng *rk_rng = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return rk_rng_init(&rk_rng->rng);
|
||||
+}
|
||||
+
|
||||
+static const struct dev_pm_ops rk_rng_pm_ops = {
|
||||
+ SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend,
|
||||
+ rk_rng_runtime_resume, NULL)
|
||||
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
+ pm_runtime_force_resume)
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+static struct platform_driver rk_rng_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "rockchip-rng",
|
||||
+#ifdef CONFIG_PM
|
||||
+ .pm = &rk_rng_pm_ops,
|
||||
+#endif
|
||||
+ .of_match_table = rk_rng_dt_match,
|
||||
+ },
|
||||
+ .probe = rk_rng_probe,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(rk_rng_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("ROCKCHIP H/W Random Number Generator driver");
|
||||
+MODULE_AUTHOR("Lin Jinhan <troy.lin@rock-chips.com>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Thu, 16 Nov 2023 17:52:35 +0300
|
||||
Subject: arm64: dts: Add HW RNG support to RK3588S
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -1935,6 +1935,16 @@ crypto: crypto@fe370000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+ rng: rng@fe378000 {
|
||||
+ compatible = "rockchip,trngv1";
|
||||
+ reg = <0x0 0xfe378000 0x0 0x200>;
|
||||
+ interrupts = <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&scmi_clk SCMI_HCLK_SECURE_NS>;
|
||||
+ clock-names = "hclk_trng";
|
||||
+ resets = <&scmi_reset SRST_H_TRNG_NS>;
|
||||
+ reset-names = "reset";
|
||||
+ };
|
||||
+
|
||||
i2s0_8ch: i2s@fe470000 {
|
||||
compatible = "rockchip,rk3588-i2s-tdm";
|
||||
reg = <0x0 0xfe470000 0x0 0x1000>;
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,311 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
Date: Thu, 13 Jun 2024 15:48:42 +0200
|
||||
Subject: media: dt-bindings: rk3568-vepu: Add RK3588 VEPU121
|
||||
|
||||
From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
|
||||
This encoder-only device is present four times on this SoC, and should
|
||||
support everything the rk3568 vepu supports (so JPEG, H.264 and VP8
|
||||
encoding). No fallback compatible has been added, since the operating
|
||||
systems might already support RK3568 VEPU and want to avoid registering
|
||||
four of them separately considering they can be used as a cluster.
|
||||
|
||||
Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
|
||||
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
|
||||
@@ -17,6 +17,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rockchip,rk3568-vepu
|
||||
+ - rockchip,rk3588-vepu121
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
Date: Thu, 13 Jun 2024 15:48:44 +0200
|
||||
Subject: media: hantro: Disable multicore support
|
||||
|
||||
Avoid exposing equal Hantro video codecs to userspace. Equal video
|
||||
codecs allow scheduling work between the cores. For that kernel support
|
||||
is required, which does not yet exist. Until that is implemented avoid
|
||||
exposing each core separately to userspace so that multicore can be
|
||||
added in the future without breaking userspace ABI.
|
||||
|
||||
This was written with Rockchip RK3588 in mind (which has 4 Hantro H1
|
||||
cores), but applies to all SoCs.
|
||||
|
||||
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
---
|
||||
drivers/media/platform/verisilicon/hantro_drv.c | 37 ++++++++++
|
||||
1 file changed, 37 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
@@ -992,6 +992,39 @@ static const struct media_device_ops hantro_m2m_media_ops = {
|
||||
.req_queue = v4l2_m2m_request_queue,
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Some SoCs, like RK3588 have multiple identical Hantro cores, but the
|
||||
+ * kernel is currently missing support for multi-core handling. Exposing
|
||||
+ * separate devices for each core to userspace is bad, since that does
|
||||
+ * not allow scheduling tasks properly (and creates ABI). With this workaround
|
||||
+ * the driver will only probe for the first core and early exit for the other
|
||||
+ * cores. Once the driver gains multi-core support, the same technique
|
||||
+ * for detecting the main core can be used to cluster all cores together.
|
||||
+ */
|
||||
+static int hantro_disable_multicore(struct hantro_dev *vpu)
|
||||
+{
|
||||
+ const char *compatible;
|
||||
+ struct device_node *node;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Intentionally ignores the fallback strings */
|
||||
+ ret = of_property_read_string(vpu->dev->of_node, "compatible", &compatible);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* first compatible node found from the root node is considered the main core */
|
||||
+ node = of_find_compatible_node(NULL, NULL, compatible);
|
||||
+ if (!node)
|
||||
+ return -EINVAL; /* broken DT? */
|
||||
+
|
||||
+ if (vpu->dev->of_node != node) {
|
||||
+ dev_info(vpu->dev, "missing multi-core support, ignoring this instance\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int hantro_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
@@ -1011,6 +1044,10 @@ static int hantro_probe(struct platform_device *pdev)
|
||||
match = of_match_node(of_hantro_match, pdev->dev.of_node);
|
||||
vpu->variant = match->data;
|
||||
|
||||
+ ret = hantro_disable_multicore(vpu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
/*
|
||||
* Support for nxp,imx8mq-vpu is kept for backwards compatibility
|
||||
* but it's deprecated. Please update your DTS file to use
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
Date: Thu, 13 Jun 2024 15:48:45 +0200
|
||||
Subject: media: hantro: Add RK3588 VEPU121
|
||||
|
||||
RK3588 handling is exactly the same as RK3568. This is not
|
||||
handled using fallback compatibles to avoid exposing multiple
|
||||
video devices on kernels not having the multicore disable
|
||||
patch.
|
||||
|
||||
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
---
|
||||
drivers/media/platform/verisilicon/hantro_drv.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
|
||||
@@ -722,6 +722,7 @@ static const struct of_device_id of_hantro_match[] = {
|
||||
{ .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },
|
||||
{ .compatible = "rockchip,rk3568-vepu", .data = &rk3568_vepu_variant, },
|
||||
{ .compatible = "rockchip,rk3568-vpu", .data = &rk3568_vpu_variant, },
|
||||
+ { .compatible = "rockchip,rk3588-vepu121", .data = &rk3568_vepu_variant, },
|
||||
{ .compatible = "rockchip,rk3588-av1-vpu", .data = &rk3588_vpu981_variant, },
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_HANTRO_IMX8M
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
Date: Thu, 13 Jun 2024 15:48:46 +0200
|
||||
Subject: arm64: dts: rockchip: Add VEPU121 to RK3588
|
||||
|
||||
From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
|
||||
RK3588 has 4 Hantro G1 encoder-only cores. They are all independent IP,
|
||||
but can be used as a cluster (i.e. sharing work between the cores).
|
||||
These cores are called VEPU121 in the TRM. The TRM describes one more
|
||||
VEPU121, but that is combined with a Hantro H1. That one will be handled
|
||||
using the VPU binding instead.
|
||||
|
||||
Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 80 ++++++++++
|
||||
1 file changed, 80 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -1282,6 +1282,86 @@ power-domain@RK3588_PD_SDMMC {
|
||||
};
|
||||
};
|
||||
|
||||
+ vepu121_0: video-codec@fdba0000 {
|
||||
+ compatible = "rockchip,rk3588-vepu121";
|
||||
+ reg = <0x0 0xfdba0000 0x0 0x800>;
|
||||
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_JPEG_ENCODER0>, <&cru HCLK_JPEG_ENCODER0>;
|
||||
+ clock-names = "aclk", "hclk";
|
||||
+ iommus = <&vepu121_0_mmu>;
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ };
|
||||
+
|
||||
+ vepu121_0_mmu: iommu@fdba0800 {
|
||||
+ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
|
||||
+ reg = <0x0 0xfdba0800 0x0 0x40>;
|
||||
+ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_JPEG_ENCODER0>, <&cru HCLK_JPEG_ENCODER0>;
|
||||
+ clock-names = "aclk", "iface";
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ #iommu-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ vepu121_1: video-codec@fdba4000 {
|
||||
+ compatible = "rockchip,rk3588-vepu121";
|
||||
+ reg = <0x0 0xfdba4000 0x0 0x800>;
|
||||
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_JPEG_ENCODER1>, <&cru HCLK_JPEG_ENCODER1>;
|
||||
+ clock-names = "aclk", "hclk";
|
||||
+ iommus = <&vepu121_1_mmu>;
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ };
|
||||
+
|
||||
+ vepu121_1_mmu: iommu@fdba4800 {
|
||||
+ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
|
||||
+ reg = <0x0 0xfdba4800 0x0 0x40>;
|
||||
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_JPEG_ENCODER1>, <&cru HCLK_JPEG_ENCODER1>;
|
||||
+ clock-names = "aclk", "iface";
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ #iommu-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ vepu121_2: video-codec@fdba8000 {
|
||||
+ compatible = "rockchip,rk3588-vepu121";
|
||||
+ reg = <0x0 0xfdba8000 0x0 0x800>;
|
||||
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_JPEG_ENCODER2>, <&cru HCLK_JPEG_ENCODER2>;
|
||||
+ clock-names = "aclk", "hclk";
|
||||
+ iommus = <&vepu121_2_mmu>;
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ };
|
||||
+
|
||||
+ vepu121_2_mmu: iommu@fdba8800 {
|
||||
+ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
|
||||
+ reg = <0x0 0xfdba8800 0x0 0x40>;
|
||||
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_JPEG_ENCODER2>, <&cru HCLK_JPEG_ENCODER2>;
|
||||
+ clock-names = "aclk", "iface";
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ #iommu-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ vepu121_3: video-codec@fdbac000 {
|
||||
+ compatible = "rockchip,rk3588-vepu121";
|
||||
+ reg = <0x0 0xfdbac000 0x0 0x800>;
|
||||
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_JPEG_ENCODER3>, <&cru HCLK_JPEG_ENCODER3>;
|
||||
+ clock-names = "aclk", "hclk";
|
||||
+ iommus = <&vepu121_3_mmu>;
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ };
|
||||
+
|
||||
+ vepu121_3_mmu: iommu@fdbac800 {
|
||||
+ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
|
||||
+ reg = <0x0 0xfdbac800 0x0 0x40>;
|
||||
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_JPEG_ENCODER3>, <&cru HCLK_JPEG_ENCODER3>;
|
||||
+ clock-names = "aclk", "iface";
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ #iommu-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
av1d: video-codec@fdc70000 {
|
||||
compatible = "rockchip,rk3588-av1-vpu";
|
||||
reg = <0x0 0xfdc70000 0x0 0x800>;
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
Date: Thu, 13 Jun 2024 15:48:47 +0200
|
||||
Subject: arm64: dts: rockchip: Add VPU121 support for RK3588
|
||||
|
||||
From: Jianfeng Liu <liujianfeng1994@gmail.com>
|
||||
|
||||
Enable Hantro G1 video decoder in RK3588's devicetree.
|
||||
|
||||
Tested with FFmpeg v4l2_request code taken from [1]
|
||||
with MPEG2, H.264 and VP8 samples.
|
||||
|
||||
[1] https://github.com/LibreELEC/LibreELEC.tv/blob/master/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch
|
||||
|
||||
Signed-off-by: Jianfeng Liu <liujianfeng1994@gmail.com>
|
||||
Tested-by: Hugh Cole-Baker <sigmaris@gmail.com>
|
||||
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 22 ++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -1282,6 +1282,28 @@ power-domain@RK3588_PD_SDMMC {
|
||||
};
|
||||
};
|
||||
|
||||
+ vpu121: video-codec@fdb50000 {
|
||||
+ compatible = "rockchip,rk3588-vpu121", "rockchip,rk3399-vpu";
|
||||
+ reg = <0x0 0xfdb50000 0x0 0x800>;
|
||||
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>,
|
||||
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ interrupt-names = "vepu", "vdpu";
|
||||
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
|
||||
+ clock-names = "aclk", "hclk";
|
||||
+ iommus = <&vpu121_mmu>;
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ };
|
||||
+
|
||||
+ vpu121_mmu: iommu@fdb50800 {
|
||||
+ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
|
||||
+ reg = <0x0 0xfdb50800 0x0 0x40>;
|
||||
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clock-names = "aclk", "iface";
|
||||
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ #iommu-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
vepu121_0: video-codec@fdba0000 {
|
||||
compatible = "rockchip,rk3588-vepu121";
|
||||
reg = <0x0 0xfdba0000 0x0 0x800>;
|
||||
--
|
||||
Armbian
|
||||
|
3746
kernel.patches/0027-RK3588-Add-rkvdec2-Support-v3.patch
Normal file
3746
kernel.patches/0027-RK3588-Add-rkvdec2-Support-v3.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: amazingfate <liujianfeng1994@gmail.com>
|
||||
Date: Fri, 21 Jun 2024 16:32:55 +0800
|
||||
Subject: media: v4l2-core: Initialize h264 frame_mbs_only_flag as 1
|
||||
|
||||
---
|
||||
drivers/media/v4l2-core/v4l2-ctrls-core.c | 13 ++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
|
||||
@@ -111,6 +111,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
struct v4l2_ctrl_vp9_frame *p_vp9_frame;
|
||||
struct v4l2_ctrl_fwht_params *p_fwht_params;
|
||||
struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
|
||||
+ struct v4l2_ctrl_h264_sps *p_h264_sps;
|
||||
struct v4l2_ctrl_av1_sequence *p_av1_sequence;
|
||||
void *p = ptr.p + idx * ctrl->elem_size;
|
||||
|
||||
@@ -179,6 +180,18 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
*/
|
||||
memset(p_h264_scaling_matrix, 16, sizeof(*p_h264_scaling_matrix));
|
||||
break;
|
||||
+ case V4L2_CTRL_TYPE_H264_SPS:
|
||||
+ p_h264_sps = p;
|
||||
+ /*
|
||||
+ * Without V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY,
|
||||
+ * frame_mbs_only_flag set to 0 will translate to a miniumum
|
||||
+ * height of 32 (see H.264 specification 7-8). Some driver may
|
||||
+ * have a minimum size lower then 32, which would fail
|
||||
+ * validation with the SPS value. Set this flag, so that there
|
||||
+ * is now doubling in the height, allowing a valid default.
|
||||
+ */
|
||||
+ p_h264_sps->flags = V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,81 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Mon, 15 Jan 2024 22:47:41 +0200
|
||||
Subject: arm64: dts: rockchip: Add HDMI0 bridge to rk3588
|
||||
|
||||
Add DT node for the HDMI0 bridge found on RK3588 SoC.
|
||||
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 55 ++++++++++
|
||||
1 file changed, 55 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -1516,6 +1516,61 @@ i2s9_8ch: i2s@fddfc000 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ hdmi0: hdmi@fde80000 {
|
||||
+ compatible = "rockchip,rk3588-dw-hdmi";
|
||||
+ reg = <0x0 0xfde80000 0x0 0x20000>;
|
||||
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>,
|
||||
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>,
|
||||
+ <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH 0>,
|
||||
+ <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>,
|
||||
+ <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru PCLK_HDMITX0>,
|
||||
+ <&cru CLK_HDMIHDP0>,
|
||||
+ <&cru CLK_HDMITX0_EARC>,
|
||||
+ <&cru CLK_HDMITX0_REF>,
|
||||
+ <&cru MCLK_I2S5_8CH_TX>,
|
||||
+ <&cru DCLK_VOP0>,
|
||||
+ <&cru DCLK_VOP1>,
|
||||
+ <&cru DCLK_VOP2>,
|
||||
+ <&cru DCLK_VOP3>,
|
||||
+ <&cru HCLK_VO1>;
|
||||
+ clock-names = "pclk",
|
||||
+ "hpd",
|
||||
+ "earc",
|
||||
+ "hdmitx_ref",
|
||||
+ "aud",
|
||||
+ "dclk_vp0",
|
||||
+ "dclk_vp1",
|
||||
+ "dclk_vp2",
|
||||
+ "dclk_vp3",
|
||||
+ "hclk_vo1";
|
||||
+ resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>;
|
||||
+ reset-names = "ref", "hdp";
|
||||
+ power-domains = <&power RK3588_PD_VO1>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd
|
||||
+ &hdmim0_tx0_scl &hdmim0_tx0_sda>;
|
||||
+ reg-io-width = <4>;
|
||||
+ rockchip,grf = <&sys_grf>;
|
||||
+ rockchip,vo1_grf = <&vo1_grf>;
|
||||
+ phys = <&hdptxphy_hdmi0>;
|
||||
+ phy-names = "hdmi";
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ hdmi0_in: port@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+
|
||||
+ hdmi0_out: port@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
qos_gpu_m0: qos@fdf35000 {
|
||||
compatible = "rockchip,rk3588-qos", "syscon";
|
||||
reg = <0x0 0xfdf35000 0x0 0x20>;
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Tue, 16 Jan 2024 03:13:38 +0200
|
||||
Subject: arm64: dts: rockchip: Enable HDMI0 PHY clk provider on rk3588
|
||||
|
||||
The HDMI0 PHY can be used as a clock provider on RK3588, hence add the
|
||||
missing #clock-cells property.
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -2985,6 +2985,7 @@ hdptxphy_hdmi0: phy@fed60000 {
|
||||
reg = <0x0 0xfed60000 0x0 0x2000>;
|
||||
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
|
||||
clock-names = "ref", "apb";
|
||||
+ #clock-cells = <0>;
|
||||
#phy-cells = <0>;
|
||||
resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
|
||||
<&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,549 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Mon, 5 Feb 2024 01:38:48 +0200
|
||||
Subject: phy: phy-rockchip-samsung-hdptx: Add FRL & EARC support
|
||||
|
||||
For upstreaming, this requires extending the standard PHY API to support
|
||||
HDMI configuration options [1].
|
||||
|
||||
Currently, the bus_width PHY attribute is used to pass clock rate and
|
||||
flags for 10-bit color depth, FRL and EARC. This is done by the HDMI
|
||||
bridge driver via phy_set_bus_width().
|
||||
|
||||
[1]: https://lore.kernel.org/all/59d5595a24bbcca897e814440179fa2caf3dff38.1707040881.git.Sandor.yu@nxp.com/
|
||||
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
---
|
||||
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 434 +++++++++-
|
||||
1 file changed, 431 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
||||
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
||||
@@ -190,6 +190,12 @@
|
||||
#define LN3_TX_SER_RATE_SEL_HBR2 BIT(3)
|
||||
#define LN3_TX_SER_RATE_SEL_HBR3 BIT(2)
|
||||
|
||||
+#define HDMI20_MAX_RATE 600000000
|
||||
+#define DATA_RATE_MASK 0xFFFFFFF
|
||||
+#define COLOR_DEPTH_MASK BIT(31)
|
||||
+#define HDMI_MODE_MASK BIT(30)
|
||||
+#define HDMI_EARC_MASK BIT(29)
|
||||
+
|
||||
struct lcpll_config {
|
||||
u32 bit_rate;
|
||||
u8 lcvco_mode_en;
|
||||
@@ -272,6 +278,25 @@ struct rk_hdptx_phy {
|
||||
struct clk_bulk_data *clks;
|
||||
int nr_clks;
|
||||
struct reset_control_bulk_data rsts[RST_MAX];
|
||||
+ bool earc_en;
|
||||
+};
|
||||
+
|
||||
+static const struct lcpll_config lcpll_cfg[] = {
|
||||
+ { 48000000, 1, 0, 0, 0x7d, 0x7d, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
|
||||
+ 0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
|
||||
+ { 40000000, 1, 1, 0, 0x68, 0x68, 1, 1, 0, 0, 0, 1, 1, 1, 1, 9, 0, 1, 1,
|
||||
+ 0, 2, 3, 1, 0, 0x20, 0x0c, 1, 0, },
|
||||
+ { 32000000, 1, 1, 1, 0x6b, 0x6b, 1, 1, 0, 1, 2, 1, 1, 1, 1, 9, 1, 2, 1,
|
||||
+ 0, 0x0d, 0x18, 1, 0, 0x20, 0x0c, 1, 1, },
|
||||
+};
|
||||
+
|
||||
+static const struct ropll_config ropll_frl_cfg[] = {
|
||||
+ { 24000000, 0x19, 0x19, 1, 1, 0, 1, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
||||
+ 0, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
|
||||
+ { 18000000, 0x7d, 0x7d, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
||||
+ 0, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
|
||||
+ { 9000000, 0x7d, 0x7d, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
||||
+ 0, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
|
||||
};
|
||||
|
||||
static const struct ropll_config ropll_tmds_cfg[] = {
|
||||
@@ -449,6 +474,73 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
|
||||
REG_SEQ0(CMN_REG(009b), 0x00),
|
||||
};
|
||||
|
||||
+static const struct reg_sequence rk_hdtpx_frl_cmn_init_seq[] = {
|
||||
+ REG_SEQ0(CMN_REG(0011), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0017), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0026), 0x53),
|
||||
+ REG_SEQ0(CMN_REG(0030), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0031), 0x20),
|
||||
+ REG_SEQ0(CMN_REG(0032), 0x30),
|
||||
+ REG_SEQ0(CMN_REG(0033), 0x0b),
|
||||
+ REG_SEQ0(CMN_REG(0034), 0x23),
|
||||
+ REG_SEQ0(CMN_REG(0042), 0xb8),
|
||||
+ REG_SEQ0(CMN_REG(004e), 0x14),
|
||||
+ REG_SEQ0(CMN_REG(0074), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0081), 0x09),
|
||||
+ REG_SEQ0(CMN_REG(0086), 0x01),
|
||||
+ REG_SEQ0(CMN_REG(0087), 0x0c),
|
||||
+ REG_SEQ0(CMN_REG(009b), 0x10),
|
||||
+};
|
||||
+
|
||||
+static const struct reg_sequence rk_hdtpx_frl_ropll_cmn_init_seq[] = {
|
||||
+ REG_SEQ0(CMN_REG(0008), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(001e), 0x14),
|
||||
+ REG_SEQ0(CMN_REG(0020), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0021), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0022), 0x11),
|
||||
+ REG_SEQ0(CMN_REG(0023), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0025), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0027), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0028), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(002a), 0x01),
|
||||
+ REG_SEQ0(CMN_REG(002b), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(002c), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(002d), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(002e), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(002f), 0x04),
|
||||
+ REG_SEQ0(CMN_REG(003d), 0x40),
|
||||
+ REG_SEQ0(CMN_REG(005c), 0x25),
|
||||
+ REG_SEQ0(CMN_REG(0089), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0094), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0097), 0x02),
|
||||
+ REG_SEQ0(CMN_REG(0099), 0x04),
|
||||
+};
|
||||
+
|
||||
+static const struct reg_sequence rk_hdtpx_frl_lcpll_cmn_init_seq[] = {
|
||||
+ REG_SEQ0(CMN_REG(0025), 0x10),
|
||||
+ REG_SEQ0(CMN_REG(0027), 0x01),
|
||||
+ REG_SEQ0(CMN_REG(0028), 0x0d),
|
||||
+ REG_SEQ0(CMN_REG(002e), 0x02),
|
||||
+ REG_SEQ0(CMN_REG(002f), 0x0d),
|
||||
+ REG_SEQ0(CMN_REG(003d), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0051), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0055), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0059), 0x11),
|
||||
+ REG_SEQ0(CMN_REG(005a), 0x03),
|
||||
+ REG_SEQ0(CMN_REG(005c), 0x05),
|
||||
+ REG_SEQ0(CMN_REG(005e), 0x07),
|
||||
+ REG_SEQ0(CMN_REG(0060), 0x01),
|
||||
+ REG_SEQ0(CMN_REG(0064), 0x07),
|
||||
+ REG_SEQ0(CMN_REG(0065), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0069), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(006c), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0070), 0x01),
|
||||
+ REG_SEQ0(CMN_REG(0089), 0x02),
|
||||
+ REG_SEQ0(CMN_REG(0095), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0097), 0x00),
|
||||
+ REG_SEQ0(CMN_REG(0099), 0x00),
|
||||
+};
|
||||
+
|
||||
static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = {
|
||||
REG_SEQ0(SB_REG(0114), 0x00),
|
||||
REG_SEQ0(SB_REG(0115), 0x00),
|
||||
@@ -472,6 +564,17 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
|
||||
REG_SEQ0(LNTOP_REG(0205), 0x1f),
|
||||
};
|
||||
|
||||
+static const struct reg_sequence rk_hdtpx_frl_lntop_init_seq[] = {
|
||||
+ REG_SEQ0(LNTOP_REG(0200), 0x04),
|
||||
+ REG_SEQ0(LNTOP_REG(0201), 0x00),
|
||||
+ REG_SEQ0(LNTOP_REG(0202), 0x00),
|
||||
+ REG_SEQ0(LNTOP_REG(0203), 0xf0),
|
||||
+ REG_SEQ0(LNTOP_REG(0204), 0xff),
|
||||
+ REG_SEQ0(LNTOP_REG(0205), 0xff),
|
||||
+ REG_SEQ0(LNTOP_REG(0206), 0x05),
|
||||
+ REG_SEQ0(LNTOP_REG(0207), 0x0f),
|
||||
+};
|
||||
+
|
||||
static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
|
||||
REG_SEQ0(LANE_REG(0303), 0x0c),
|
||||
REG_SEQ0(LANE_REG(0307), 0x20),
|
||||
@@ -550,6 +653,40 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
|
||||
REG_SEQ0(LANE_REG(0606), 0x1c),
|
||||
};
|
||||
|
||||
+static const struct reg_sequence rk_hdtpx_frl_ropll_lane_init_seq[] = {
|
||||
+ REG_SEQ0(LANE_REG(0312), 0x3c),
|
||||
+ REG_SEQ0(LANE_REG(0412), 0x3c),
|
||||
+ REG_SEQ0(LANE_REG(0512), 0x3c),
|
||||
+ REG_SEQ0(LANE_REG(0612), 0x3c),
|
||||
+};
|
||||
+
|
||||
+static const struct reg_sequence rk_hdtpx_frl_lcpll_lane_init_seq[] = {
|
||||
+ REG_SEQ0(LANE_REG(0312), 0x3c),
|
||||
+ REG_SEQ0(LANE_REG(0412), 0x3c),
|
||||
+ REG_SEQ0(LANE_REG(0512), 0x3c),
|
||||
+ REG_SEQ0(LANE_REG(0612), 0x3c),
|
||||
+ REG_SEQ0(LANE_REG(0303), 0x2f),
|
||||
+ REG_SEQ0(LANE_REG(0403), 0x2f),
|
||||
+ REG_SEQ0(LANE_REG(0503), 0x2f),
|
||||
+ REG_SEQ0(LANE_REG(0603), 0x2f),
|
||||
+ REG_SEQ0(LANE_REG(0305), 0x03),
|
||||
+ REG_SEQ0(LANE_REG(0405), 0x03),
|
||||
+ REG_SEQ0(LANE_REG(0505), 0x03),
|
||||
+ REG_SEQ0(LANE_REG(0605), 0x03),
|
||||
+ REG_SEQ0(LANE_REG(0306), 0xfc),
|
||||
+ REG_SEQ0(LANE_REG(0406), 0xfc),
|
||||
+ REG_SEQ0(LANE_REG(0506), 0xfc),
|
||||
+ REG_SEQ0(LANE_REG(0606), 0xfc),
|
||||
+ REG_SEQ0(LANE_REG(0305), 0x4f),
|
||||
+ REG_SEQ0(LANE_REG(0405), 0x4f),
|
||||
+ REG_SEQ0(LANE_REG(0505), 0x4f),
|
||||
+ REG_SEQ0(LANE_REG(0605), 0x4f),
|
||||
+ REG_SEQ0(LANE_REG(0304), 0x14),
|
||||
+ REG_SEQ0(LANE_REG(0404), 0x14),
|
||||
+ REG_SEQ0(LANE_REG(0504), 0x14),
|
||||
+ REG_SEQ0(LANE_REG(0604), 0x14),
|
||||
+};
|
||||
+
|
||||
static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
@@ -651,6 +788,47 @@ static int rk_hdptx_post_enable_pll(struct rk_hdptx_phy *hdptx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rk_hdptx_post_power_up(struct rk_hdptx_phy *hdptx)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
|
||||
+ HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
|
||||
+ regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
|
||||
+
|
||||
+ usleep_range(10, 15);
|
||||
+ reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
|
||||
+
|
||||
+ usleep_range(10, 15);
|
||||
+ val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN;
|
||||
+ regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
|
||||
+
|
||||
+ usleep_range(10, 15);
|
||||
+ reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
|
||||
+
|
||||
+ ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
|
||||
+ val & HDPTX_O_PLL_LOCK_DONE, 20, 400);
|
||||
+ if (ret) {
|
||||
+ dev_err(hdptx->dev, "Failed to get PHY PLL lock: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ usleep_range(20, 30);
|
||||
+ reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
|
||||
+
|
||||
+ ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
|
||||
+ val & HDPTX_O_PHY_RDY, 100, 5000);
|
||||
+ if (ret) {
|
||||
+ dev_err(hdptx->dev, "Failed to get PHY ready: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(hdptx->dev, "PHY ready\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
|
||||
{
|
||||
u32 val;
|
||||
@@ -680,6 +858,99 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
|
||||
}
|
||||
|
||||
+static void rk_hdptx_earc_config(struct rk_hdptx_phy *hdptx)
|
||||
+{
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0113), SB_RX_RCAL_OPT_CODE_MASK,
|
||||
+ FIELD_PREP(SB_RX_RCAL_OPT_CODE_MASK, 1));
|
||||
+ regmap_write(hdptx->regmap, SB_REG(011c), 0x04);
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(011b), SB_AFC_TOL_MASK,
|
||||
+ FIELD_PREP(SB_AFC_TOL_MASK, 3));
|
||||
+ regmap_write(hdptx->regmap, SB_REG(0109), 0x05);
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0120),
|
||||
+ SB_EARC_EN_MASK | SB_EARC_AFC_EN_MASK,
|
||||
+ FIELD_PREP(SB_EARC_EN_MASK, 1) |
|
||||
+ FIELD_PREP(SB_EARC_AFC_EN_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(011b), SB_EARC_SIG_DET_BYPASS_MASK,
|
||||
+ FIELD_PREP(SB_EARC_SIG_DET_BYPASS_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(011f),
|
||||
+ SB_PWM_AFC_CTRL_MASK | SB_RCAL_RSTN_MASK,
|
||||
+ FIELD_PREP(SB_PWM_AFC_CTRL_MASK, 0xc) |
|
||||
+ FIELD_PREP(SB_RCAL_RSTN_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0115), SB_READY_DELAY_TIME_MASK,
|
||||
+ FIELD_PREP(SB_READY_DELAY_TIME_MASK, 2));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0113), SB_RX_RTERM_CTRL_MASK,
|
||||
+ FIELD_PREP(SB_RX_RTERM_CTRL_MASK, 3));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0102), ANA_SB_RXTERM_OFFSP_MASK,
|
||||
+ FIELD_PREP(ANA_SB_RXTERM_OFFSP_MASK, 3));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0103), ANA_SB_RXTERM_OFFSN_MASK,
|
||||
+ FIELD_PREP(ANA_SB_RXTERM_OFFSN_MASK, 3));
|
||||
+
|
||||
+ regmap_write(hdptx->regmap, SB_REG(011a), 0x03);
|
||||
+ regmap_write(hdptx->regmap, SB_REG(0118), 0x0a);
|
||||
+ regmap_write(hdptx->regmap, SB_REG(011e), 0x6a);
|
||||
+ regmap_write(hdptx->regmap, SB_REG(011d), 0x67);
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0117), FAST_PULSE_TIME_MASK,
|
||||
+ FIELD_PREP(FAST_PULSE_TIME_MASK, 4));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0114),
|
||||
+ SB_TG_SB_EN_DELAY_TIME_MASK | SB_TG_RXTERM_EN_DELAY_TIME_MASK,
|
||||
+ FIELD_PREP(SB_TG_SB_EN_DELAY_TIME_MASK, 2) |
|
||||
+ FIELD_PREP(SB_TG_RXTERM_EN_DELAY_TIME_MASK, 2));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0105), ANA_SB_TX_HLVL_PROG_MASK,
|
||||
+ FIELD_PREP(ANA_SB_TX_HLVL_PROG_MASK, 7));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0106), ANA_SB_TX_LLVL_PROG_MASK,
|
||||
+ FIELD_PREP(ANA_SB_TX_LLVL_PROG_MASK, 7));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(010f), ANA_SB_VREG_GAIN_CTRL_MASK,
|
||||
+ FIELD_PREP(ANA_SB_VREG_GAIN_CTRL_MASK, 0));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0110), ANA_SB_VREG_REF_SEL_MASK,
|
||||
+ FIELD_PREP(ANA_SB_VREG_REF_SEL_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0115), SB_TG_OSC_EN_DELAY_TIME_MASK,
|
||||
+ FIELD_PREP(SB_TG_OSC_EN_DELAY_TIME_MASK, 2));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0116), AFC_RSTN_DELAY_TIME_MASK,
|
||||
+ FIELD_PREP(AFC_RSTN_DELAY_TIME_MASK, 2));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0109), ANA_SB_DMRX_AFC_DIV_RATIO_MASK,
|
||||
+ FIELD_PREP(ANA_SB_DMRX_AFC_DIV_RATIO_MASK, 5));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
|
||||
+ FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_EN_MASK,
|
||||
+ FIELD_PREP(OVRD_SB_EN_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0102), OVRD_SB_RXTERM_EN_MASK,
|
||||
+ FIELD_PREP(OVRD_SB_RXTERM_EN_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0105), OVRD_SB_EARC_CMDC_EN_MASK,
|
||||
+ FIELD_PREP(OVRD_SB_EARC_CMDC_EN_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(010f),
|
||||
+ OVRD_SB_VREG_EN_MASK | OVRD_SB_VREG_LPF_BYPASS_MASK,
|
||||
+ FIELD_PREP(OVRD_SB_VREG_EN_MASK, 1) |
|
||||
+ FIELD_PREP(OVRD_SB_VREG_LPF_BYPASS_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0123), OVRD_SB_READY_MASK,
|
||||
+ FIELD_PREP(OVRD_SB_READY_MASK, 1));
|
||||
+
|
||||
+ usleep_range(1000, 1100);
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0103), SB_RX_RESCAL_DONE_MASK,
|
||||
+ FIELD_PREP(SB_RX_RESCAL_DONE_MASK, 1));
|
||||
+ usleep_range(50, 60);
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_EN_MASK,
|
||||
+ FIELD_PREP(SB_EN_MASK, 1));
|
||||
+ usleep_range(50, 60);
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0102), SB_RXTERM_EN_MASK,
|
||||
+ FIELD_PREP(SB_RXTERM_EN_MASK, 1));
|
||||
+ usleep_range(50, 60);
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0105), SB_EARC_CMDC_EN_MASK,
|
||||
+ FIELD_PREP(SB_EARC_CMDC_EN_MASK, 1));
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(010f), SB_VREG_EN_MASK,
|
||||
+ FIELD_PREP(SB_VREG_EN_MASK, 1));
|
||||
+ usleep_range(50, 60);
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(010f), OVRD_SB_VREG_LPF_BYPASS_MASK,
|
||||
+ FIELD_PREP(OVRD_SB_VREG_LPF_BYPASS_MASK, 1));
|
||||
+ usleep_range(250, 300);
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(010f), OVRD_SB_VREG_LPF_BYPASS_MASK,
|
||||
+ FIELD_PREP(OVRD_SB_VREG_LPF_BYPASS_MASK, 0));
|
||||
+ usleep_range(100, 120);
|
||||
+ regmap_update_bits(hdptx->regmap, SB_REG(0123), SB_READY_MASK,
|
||||
+ FIELD_PREP(SB_READY_MASK, 1));
|
||||
+}
|
||||
+
|
||||
static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate,
|
||||
struct ropll_config *cfg)
|
||||
{
|
||||
@@ -755,9 +1026,13 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate,
|
||||
static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
|
||||
unsigned int rate)
|
||||
{
|
||||
+ int i, bus_width = phy_get_bus_width(hdptx->phy);
|
||||
+ u8 color_depth = (bus_width & COLOR_DEPTH_MASK) ? 1 : 0;
|
||||
const struct ropll_config *cfg = NULL;
|
||||
struct ropll_config rc = {0};
|
||||
- int i;
|
||||
+
|
||||
+ if (color_depth)
|
||||
+ rate = rate * 10 / 8;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
|
||||
if (rate == ropll_tmds_cfg[i].bit_rate) {
|
||||
@@ -813,6 +1088,9 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
|
||||
regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
|
||||
FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
|
||||
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK,
|
||||
+ FIELD_PREP(PLL_PCG_CLK_SEL_MASK, color_depth));
|
||||
+
|
||||
regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN,
|
||||
PLL_PCG_CLK_EN);
|
||||
|
||||
@@ -853,9 +1131,146 @@ static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq);
|
||||
|
||||
+ if (hdptx->earc_en)
|
||||
+ rk_hdptx_earc_config(hdptx);
|
||||
+
|
||||
return rk_hdptx_post_enable_lane(hdptx);
|
||||
}
|
||||
|
||||
+static int rk_hdptx_ropll_frl_mode_config(struct rk_hdptx_phy *hdptx,
|
||||
+ u32 bus_width)
|
||||
+{
|
||||
+ u32 bit_rate = bus_width & DATA_RATE_MASK;
|
||||
+ u8 color_depth = (bus_width & COLOR_DEPTH_MASK) ? 1 : 0;
|
||||
+ const struct ropll_config *cfg = NULL;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(ropll_frl_cfg); i++)
|
||||
+ if (bit_rate == ropll_frl_cfg[i].bit_rate) {
|
||||
+ cfg = &ropll_frl_cfg[i];
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!cfg) {
|
||||
+ dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ rk_hdptx_pre_power_up(hdptx);
|
||||
+
|
||||
+ reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);
|
||||
+ usleep_range(10, 20);
|
||||
+ reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);
|
||||
+
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_cmn_init_seq);
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_ropll_cmn_init_seq);
|
||||
+
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0059),
|
||||
+ (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(005a), cfg->pms_sdiv << 4);
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
|
||||
+ FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en));
|
||||
+ if (!cfg->sdm_en)
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(005e), 0xf, 0);
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK,
|
||||
+ FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign));
|
||||
+
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0060), cfg->sdm_deno);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0065), cfg->sdm_num);
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
|
||||
+ FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n));
|
||||
+
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(006c), cfg->sdc_num);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0070), cfg->sdc_deno);
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
|
||||
+ FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK,
|
||||
+ FIELD_PREP(PLL_PCG_CLK_SEL_MASK, color_depth));
|
||||
+
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_lntop_init_seq);
|
||||
+
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_ropll_lane_init_seq);
|
||||
+
|
||||
+ if (hdptx->earc_en)
|
||||
+ rk_hdptx_earc_config(hdptx);
|
||||
+
|
||||
+ return rk_hdptx_post_power_up(hdptx);
|
||||
+}
|
||||
+
|
||||
+static int rk_hdptx_lcpll_frl_mode_config(struct rk_hdptx_phy *hdptx,
|
||||
+ u32 bus_width)
|
||||
+{
|
||||
+ u32 bit_rate = bus_width & DATA_RATE_MASK;
|
||||
+ u8 color_depth = (bus_width & COLOR_DEPTH_MASK) ? 1 : 0;
|
||||
+ const struct lcpll_config *cfg = NULL;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(lcpll_cfg); i++)
|
||||
+ if (bit_rate == lcpll_cfg[i].bit_rate) {
|
||||
+ cfg = &lcpll_cfg[i];
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!cfg) {
|
||||
+ dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ rk_hdptx_pre_power_up(hdptx);
|
||||
+
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_cmn_init_seq);
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_lcpll_cmn_init_seq);
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(0008),
|
||||
+ LCPLL_EN_MASK | LCPLL_LCVCO_MODE_EN_MASK,
|
||||
+ FIELD_PREP(LCPLL_EN_MASK, 1) |
|
||||
+ FIELD_PREP(LCPLL_LCVCO_MODE_EN_MASK, cfg->lcvco_mode_en));
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(001e),
|
||||
+ LCPLL_PI_EN_MASK | LCPLL_100M_CLK_EN_MASK,
|
||||
+ FIELD_PREP(LCPLL_PI_EN_MASK, cfg->pi_en) |
|
||||
+ FIELD_PREP(LCPLL_100M_CLK_EN_MASK, cfg->clk_en_100m));
|
||||
+
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0020), cfg->pms_mdiv);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0021), cfg->pms_mdiv_afc);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0022),
|
||||
+ (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(0023),
|
||||
+ (cfg->pms_sdiv << 4) | cfg->pms_sdiv);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(002a), cfg->sdm_deno);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(002b), cfg->sdm_num_sign);
|
||||
+ regmap_write(hdptx->regmap, CMN_REG(002c), cfg->sdm_num);
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(002d), LCPLL_SDC_N_MASK,
|
||||
+ FIELD_PREP(LCPLL_SDC_N_MASK, cfg->sdc_n));
|
||||
+
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
|
||||
+ FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
|
||||
+ regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK,
|
||||
+ FIELD_PREP(PLL_PCG_CLK_SEL_MASK, color_depth));
|
||||
+
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_lntop_init_seq);
|
||||
+
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);
|
||||
+ rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_frl_lcpll_lane_init_seq);
|
||||
+
|
||||
+ if (hdptx->earc_en)
|
||||
+ rk_hdptx_earc_config(hdptx);
|
||||
+
|
||||
+ return rk_hdptx_post_power_up(hdptx);
|
||||
+}
|
||||
+
|
||||
static int rk_hdptx_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
|
||||
@@ -865,7 +1280,7 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
|
||||
* from the HDMI bridge driver until phy_configure_opts_hdmi
|
||||
* becomes available in the PHY API.
|
||||
*/
|
||||
- unsigned int rate = bus_width & 0xfffffff;
|
||||
+ unsigned int rate = bus_width & DATA_RATE_MASK;
|
||||
|
||||
dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
|
||||
__func__, bus_width, rate);
|
||||
@@ -876,7 +1291,20 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
|
||||
+ if (bus_width & HDMI_EARC_MASK)
|
||||
+ hdptx->earc_en = true;
|
||||
+ else
|
||||
+ hdptx->earc_en = false;
|
||||
+
|
||||
+ if (bus_width & HDMI_MODE_MASK) {
|
||||
+ if (rate > 24000000)
|
||||
+ ret = rk_hdptx_lcpll_frl_mode_config(hdptx, bus_width);
|
||||
+ else
|
||||
+ ret = rk_hdptx_ropll_frl_mode_config(hdptx, bus_width);
|
||||
+ } else {
|
||||
+ ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
|
||||
+ }
|
||||
+
|
||||
if (ret)
|
||||
pm_runtime_put(hdptx->dev);
|
||||
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,222 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Tue, 16 Jan 2024 19:27:40 +0200
|
||||
Subject: phy: phy-rockchip-samsung-hdptx: Add clock provider
|
||||
|
||||
The HDMI PHY PLL can be used as an alternative dclk source to SoC CRU.
|
||||
It provides more accurate clock rates required to properly support
|
||||
various display modes, e.g. those relying on non-integer refresh rates.
|
||||
|
||||
Also note this only works for HDMI 2.0 or bellow, e.g. cannot be used to
|
||||
support HDMI 2.1 4K@120Hz mode.
|
||||
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
---
|
||||
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 148 +++++++++-
|
||||
1 file changed, 143 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
||||
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
@@ -279,6 +280,12 @@ struct rk_hdptx_phy {
|
||||
int nr_clks;
|
||||
struct reset_control_bulk_data rsts[RST_MAX];
|
||||
bool earc_en;
|
||||
+
|
||||
+ /* clk provider */
|
||||
+ struct clk_hw hw;
|
||||
+ unsigned long rate;
|
||||
+ int id;
|
||||
+ int count;
|
||||
};
|
||||
|
||||
static const struct lcpll_config lcpll_cfg[] = {
|
||||
@@ -1031,6 +1038,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
|
||||
const struct ropll_config *cfg = NULL;
|
||||
struct ropll_config rc = {0};
|
||||
|
||||
+ hdptx->rate = rate * 100;
|
||||
+
|
||||
if (color_depth)
|
||||
rate = rate * 10 / 8;
|
||||
|
||||
@@ -1315,11 +1324,13 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
|
||||
u32 val;
|
||||
- int ret;
|
||||
+ int ret = 0;
|
||||
|
||||
- ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
|
||||
- if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE))
|
||||
- rk_hdptx_phy_disable(hdptx);
|
||||
+ if (hdptx->count == 0) {
|
||||
+ ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
|
||||
+ if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE))
|
||||
+ rk_hdptx_phy_disable(hdptx);
|
||||
+ }
|
||||
|
||||
pm_runtime_put(hdptx->dev);
|
||||
|
||||
@@ -1332,6 +1343,129 @@ static const struct phy_ops rk_hdptx_phy_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
+static struct rk_hdptx_phy *to_rk_hdptx_phy(struct clk_hw *hw)
|
||||
+{
|
||||
+ return container_of(hw, struct rk_hdptx_phy, hw);
|
||||
+}
|
||||
+
|
||||
+static int rk_hdptx_phy_clk_prepare(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pm_runtime_resume_and_get(hdptx->dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(hdptx->dev, "Failed to resume phy clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (!hdptx->count && hdptx->rate) {
|
||||
+ ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, hdptx->rate / 100);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(hdptx->dev, "Failed to init PHY PLL: %d\n", ret);
|
||||
+ pm_runtime_put(hdptx->dev);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ hdptx->count++;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
+
|
||||
+ if (hdptx->count == 1) {
|
||||
+ u32 val;
|
||||
+ int ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
|
||||
+ if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE))
|
||||
+ rk_hdptx_phy_disable(hdptx);
|
||||
+ }
|
||||
+
|
||||
+ hdptx->count--;
|
||||
+ pm_runtime_put(hdptx->dev);
|
||||
+}
|
||||
+
|
||||
+static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
+
|
||||
+ return hdptx->rate;
|
||||
+}
|
||||
+
|
||||
+static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long *parent_rate)
|
||||
+{
|
||||
+ const struct ropll_config *cfg = NULL;
|
||||
+ u32 bit_rate = rate / 100;
|
||||
+ int i;
|
||||
+
|
||||
+ if (rate > HDMI20_MAX_RATE)
|
||||
+ return rate;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
|
||||
+ if (bit_rate == ropll_tmds_cfg[i].bit_rate) {
|
||||
+ cfg = &ropll_tmds_cfg[i];
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!cfg && !rk_hdptx_phy_clk_pll_calc(bit_rate, NULL))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return rate;
|
||||
+}
|
||||
+
|
||||
+static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
+ u32 val;
|
||||
+ int ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
|
||||
+ if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE))
|
||||
+ rk_hdptx_phy_disable(hdptx);
|
||||
+
|
||||
+ return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100);
|
||||
+}
|
||||
+
|
||||
+static const struct clk_ops hdptx_phy_clk_ops = {
|
||||
+ .prepare = rk_hdptx_phy_clk_prepare,
|
||||
+ .unprepare = rk_hdptx_phy_clk_unprepare,
|
||||
+ .recalc_rate = rk_hdptx_phy_clk_recalc_rate,
|
||||
+ .round_rate = rk_hdptx_phy_clk_round_rate,
|
||||
+ .set_rate = rk_hdptx_phy_clk_set_rate,
|
||||
+};
|
||||
+
|
||||
+static int rk_hdptx_phy_clk_register(struct rk_hdptx_phy *hdptx)
|
||||
+{
|
||||
+ struct device *dev = hdptx->dev;
|
||||
+ const char *name, *pname;
|
||||
+ struct clk *refclk;
|
||||
+ int ret;
|
||||
+
|
||||
+ refclk = devm_clk_get(dev, "ref");
|
||||
+ if (IS_ERR(refclk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(refclk),
|
||||
+ "Failed to get ref clock\n");
|
||||
+
|
||||
+ pname = __clk_get_name(refclk);
|
||||
+ name = hdptx->id ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0";
|
||||
+ hdptx->hw.init = CLK_HW_INIT(name, pname, &hdptx_phy_clk_ops,
|
||||
+ CLK_GET_RATE_NOCACHE);
|
||||
+
|
||||
+ ret = devm_clk_hw_register(dev, &hdptx->hw);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Failed to register clock\n");
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &hdptx->hw);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret,
|
||||
+ "Failed to register clk provider\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int rk_hdptx_phy_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev);
|
||||
@@ -1367,6 +1501,10 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
|
||||
|
||||
hdptx->dev = dev;
|
||||
|
||||
+ hdptx->id = of_alias_get_id(dev->of_node, "hdptxphy");
|
||||
+ if (hdptx->id < 0)
|
||||
+ hdptx->id = 0;
|
||||
+
|
||||
regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(regs))
|
||||
return dev_err_probe(dev, PTR_ERR(regs),
|
||||
@@ -1426,7 +1564,7 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
|
||||
reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
|
||||
reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
|
||||
|
||||
- return 0;
|
||||
+ return rk_hdptx_phy_clk_register(hdptx);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rk_hdptx_phy_pm_ops = {
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,679 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Fri, 3 Nov 2023 19:58:02 +0200
|
||||
Subject: drm/rockchip: vop2: Improve display modes handling on rk3588
|
||||
|
||||
The initial vop2 support for rk3588 in mainline is not able to handle
|
||||
all display modes supported by connected displays, e.g.
|
||||
2560x1440-75.00Hz, 2048x1152-60.00Hz, 1024x768-60.00Hz.
|
||||
|
||||
Additionally, it doesn't cope with non-integer refresh rates like 59.94,
|
||||
29.97, 23.98, etc.
|
||||
|
||||
Improve HDMI0 clocking in order to support the additional display modes.
|
||||
|
||||
Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
---
|
||||
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 553 +++++++++-
|
||||
1 file changed, 552 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
|
||||
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
|
||||
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/clkdev.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/iopoll.h>
|
||||
@@ -212,6 +214,10 @@ struct vop2 {
|
||||
struct clk *hclk;
|
||||
struct clk *aclk;
|
||||
struct clk *pclk;
|
||||
+ // [CC:] hack to support additional display modes
|
||||
+ struct clk *hdmi0_phy_pll;
|
||||
+ /* list_head of internal clk */
|
||||
+ struct list_head clk_list_head;
|
||||
|
||||
/* optional internal rgb encoder */
|
||||
struct rockchip_rgb *rgb;
|
||||
@@ -220,6 +226,19 @@ struct vop2 {
|
||||
struct vop2_win win[];
|
||||
};
|
||||
|
||||
+struct vop2_clk {
|
||||
+ struct vop2 *vop2;
|
||||
+ struct list_head list;
|
||||
+ unsigned long rate;
|
||||
+ struct clk_hw hw;
|
||||
+ struct clk_divider div;
|
||||
+ int div_val;
|
||||
+ u8 parent_index;
|
||||
+};
|
||||
+
|
||||
+#define to_vop2_clk(_hw) container_of(_hw, struct vop2_clk, hw)
|
||||
+#define VOP2_MAX_DCLK_RATE 600000 /* kHz */
|
||||
+
|
||||
#define vop2_output_if_is_hdmi(x) ((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
|
||||
(x) == ROCKCHIP_VOP2_EP_HDMI1)
|
||||
|
||||
@@ -1476,9 +1495,30 @@ static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adj_mode)
|
||||
{
|
||||
+ struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
+ struct drm_connector *connector;
|
||||
+ struct drm_connector_list_iter conn_iter;
|
||||
+ struct drm_crtc_state *new_crtc_state = container_of(mode, struct drm_crtc_state, mode);
|
||||
drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V |
|
||||
CRTC_STEREO_DOUBLE);
|
||||
|
||||
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
+ adj_mode->crtc_clock *= 2;
|
||||
+
|
||||
+ drm_connector_list_iter_begin(crtc->dev, &conn_iter);
|
||||
+ drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
+ if ((new_crtc_state->connector_mask & drm_connector_mask(connector)) &&
|
||||
+ ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
|
||||
+ (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))) {
|
||||
+ drm_connector_list_iter_end(&conn_iter);
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ drm_connector_list_iter_end(&conn_iter);
|
||||
+
|
||||
+ if (adj_mode->crtc_clock <= VOP2_MAX_DCLK_RATE)
|
||||
+ adj_mode->crtc_clock = DIV_ROUND_UP(clk_round_rate(vp->dclk,
|
||||
+ adj_mode->crtc_clock * 1000), 1000);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1663,6 +1703,31 @@ static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static struct vop2_clk *vop2_clk_get(struct vop2 *vop2, const char *name);
|
||||
+
|
||||
+static int vop2_cru_set_rate(struct vop2_clk *if_pixclk, struct vop2_clk *if_dclk)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (if_pixclk) {
|
||||
+ ret = clk_set_rate(if_pixclk->hw.clk, if_pixclk->rate);
|
||||
+ if (ret < 0) {
|
||||
+ DRM_DEV_ERROR(if_pixclk->vop2->dev, "set %s to %ld failed: %d\n",
|
||||
+ clk_hw_get_name(&if_pixclk->hw), if_pixclk->rate, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (if_dclk) {
|
||||
+ ret = clk_set_rate(if_dclk->hw.clk, if_dclk->rate);
|
||||
+ if (ret < 0)
|
||||
+ DRM_DEV_ERROR(if_dclk->vop2->dev, "set %s to %ld failed %d\n",
|
||||
+ clk_hw_get_name(&if_dclk->hw), if_dclk->rate, ret);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* 4 pixclk/cycle on rk3588
|
||||
* RGB/eDP/HDMI: if_pixclk >= dclk_core
|
||||
@@ -1686,6 +1751,72 @@ static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
|
||||
int K = 1;
|
||||
|
||||
if (vop2_output_if_is_hdmi(id)) {
|
||||
+ if (vop2->data->soc_id == 3588 && id == ROCKCHIP_VOP2_EP_HDMI0 &&
|
||||
+ vop2->hdmi0_phy_pll) {
|
||||
+ const char *clk_src_name = "hdmi_edp0_clk_src";
|
||||
+ const char *clk_parent_name = "dclk";
|
||||
+ const char *pixclk_name = "hdmi_edp0_pixclk";
|
||||
+ const char *dclk_name = "hdmi_edp0_dclk";
|
||||
+ struct vop2_clk *if_clk_src, *if_clk_parent, *if_pixclk, *if_dclk, *dclk, *dclk_core, *dclk_out;
|
||||
+ char clk_name[32];
|
||||
+ int ret;
|
||||
+
|
||||
+ if_clk_src = vop2_clk_get(vop2, clk_src_name);
|
||||
+ snprintf(clk_name, sizeof(clk_name), "%s%d", clk_parent_name, vp->id);
|
||||
+ if_clk_parent = vop2_clk_get(vop2, clk_name);
|
||||
+ if_pixclk = vop2_clk_get(vop2, pixclk_name);
|
||||
+ if_dclk = vop2_clk_get(vop2, dclk_name);
|
||||
+ if (!if_pixclk || !if_clk_parent) {
|
||||
+ DRM_DEV_ERROR(vop2->dev, "failed to get connector interface clk\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_set_parent(if_clk_src->hw.clk, if_clk_parent->hw.clk);
|
||||
+ if (ret < 0) {
|
||||
+ DRM_DEV_ERROR(vop2->dev, "failed to set parent(%s) for %s: %d\n",
|
||||
+ __clk_get_name(if_clk_parent->hw.clk),
|
||||
+ __clk_get_name(if_clk_src->hw.clk), ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
|
||||
+ K = 2;
|
||||
+
|
||||
+ if_pixclk->rate = (dclk_core_rate << 1) / K;
|
||||
+ if_dclk->rate = dclk_core_rate / K;
|
||||
+
|
||||
+ snprintf(clk_name, sizeof(clk_name), "dclk_core%d", vp->id);
|
||||
+ dclk_core = vop2_clk_get(vop2, clk_name);
|
||||
+
|
||||
+ snprintf(clk_name, sizeof(clk_name), "dclk_out%d", vp->id);
|
||||
+ dclk_out = vop2_clk_get(vop2, clk_name);
|
||||
+
|
||||
+ snprintf(clk_name, sizeof(clk_name), "dclk%d", vp->id);
|
||||
+ dclk = vop2_clk_get(vop2, clk_name);
|
||||
+ if (v_pixclk <= (VOP2_MAX_DCLK_RATE * 1000)) {
|
||||
+ if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
|
||||
+ v_pixclk = v_pixclk >> 1;
|
||||
+ } else {
|
||||
+ v_pixclk = v_pixclk >> 2;
|
||||
+ }
|
||||
+ clk_set_rate(dclk->hw.clk, v_pixclk);
|
||||
+
|
||||
+ if (dclk_core_rate > if_pixclk->rate) {
|
||||
+ clk_set_rate(dclk_core->hw.clk, dclk_core_rate);
|
||||
+ ret = vop2_cru_set_rate(if_pixclk, if_dclk);
|
||||
+ } else {
|
||||
+ ret = vop2_cru_set_rate(if_pixclk, if_dclk);
|
||||
+ clk_set_rate(dclk_core->hw.clk, dclk_core_rate);
|
||||
+ }
|
||||
+
|
||||
+ *dclk_core_div = dclk_core->div_val;
|
||||
+ *dclk_out_div = dclk_out->div_val;
|
||||
+ *if_pixclk_div = if_pixclk->div_val;
|
||||
+ *if_dclk_div = if_dclk->div_val;
|
||||
+
|
||||
+ return dclk->rate;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
|
||||
* K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
|
||||
@@ -1917,6 +2048,22 @@ static int us_to_vertical_line(struct drm_display_mode *mode, int us)
|
||||
return us * mode->clock / mode->htotal / 1000;
|
||||
}
|
||||
|
||||
+// [CC:] rework virtual clock
|
||||
+static struct vop2_clk *vop2_clk_get(struct vop2 *vop2, const char *name)
|
||||
+{
|
||||
+ struct vop2_clk *clk, *n;
|
||||
+
|
||||
+ if (!name)
|
||||
+ return NULL;
|
||||
+
|
||||
+ list_for_each_entry_safe(clk, n, &vop2->clk_list_head, list) {
|
||||
+ if (!strcmp(clk_hw_get_name(&clk->hw), name))
|
||||
+ return clk;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
@@ -1944,6 +2091,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
u32 val, polflags;
|
||||
int ret;
|
||||
struct drm_encoder *encoder;
|
||||
+ char clk_name[32];
|
||||
+ struct vop2_clk *dclk;
|
||||
|
||||
drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n",
|
||||
hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
|
||||
@@ -2044,11 +2193,38 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
|
||||
dsp_ctrl |= RK3568_VP_DSP_CTRL__CORE_DCLK_DIV;
|
||||
- clock *= 2;
|
||||
+ // [CC:] done via mode_fixup
|
||||
+ // clock *= 2;
|
||||
}
|
||||
|
||||
vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
|
||||
|
||||
+ snprintf(clk_name, sizeof(clk_name), "dclk%d", vp->id);
|
||||
+ dclk = vop2_clk_get(vop2, clk_name);
|
||||
+ if (dclk) {
|
||||
+ /*
|
||||
+ * use HDMI_PHY_PLL as dclk source under 4K@60 if it is available,
|
||||
+ * otherwise use system cru as dclk source.
|
||||
+ */
|
||||
+ drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
|
||||
+ struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
|
||||
+
|
||||
+ // [CC:] Using PHY PLL to handle all display modes
|
||||
+ if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
|
||||
+ clk_get_rate(vop2->hdmi0_phy_pll);
|
||||
+
|
||||
+ if (mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
|
||||
+ ret = clk_set_parent(vp->dclk, vop2->hdmi0_phy_pll);
|
||||
+ if (ret < 0)
|
||||
+ DRM_WARN("failed to set clock parent for %s\n",
|
||||
+ __clk_get_name(vp->dclk));
|
||||
+ }
|
||||
+
|
||||
+ clock = dclk->rate;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
clk_set_rate(vp->dclk, clock);
|
||||
|
||||
vop2_post_config(crtc);
|
||||
@@ -2504,7 +2680,43 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
spin_unlock_irq(&crtc->dev->event_lock);
|
||||
}
|
||||
|
||||
+static enum drm_mode_status
|
||||
+vop2_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
|
||||
+{
|
||||
+ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
|
||||
+ struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
+ struct vop2 *vop2 = vp->vop2;
|
||||
+ const struct vop2_data *vop2_data = vop2->data;
|
||||
+ const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
|
||||
+ int request_clock = mode->clock;
|
||||
+ int clock;
|
||||
+
|
||||
+ if (mode->hdisplay > vp_data->max_output.width)
|
||||
+ return MODE_BAD_HVALUE;
|
||||
+
|
||||
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
+ request_clock *= 2;
|
||||
+
|
||||
+ if (request_clock <= VOP2_MAX_DCLK_RATE) {
|
||||
+ clock = request_clock;
|
||||
+ } else {
|
||||
+ request_clock = request_clock >> 2;
|
||||
+ clock = clk_round_rate(vp->dclk, request_clock * 1000) / 1000;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Hdmi or DisplayPort request a Accurate clock.
|
||||
+ */
|
||||
+ if (vcstate->output_type == DRM_MODE_CONNECTOR_HDMIA ||
|
||||
+ vcstate->output_type == DRM_MODE_CONNECTOR_DisplayPort)
|
||||
+ if (clock != request_clock)
|
||||
+ return MODE_CLOCK_RANGE;
|
||||
+
|
||||
+ return MODE_OK;
|
||||
+}
|
||||
+
|
||||
static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
|
||||
+ .mode_valid = vop2_crtc_mode_valid,
|
||||
.mode_fixup = vop2_crtc_mode_fixup,
|
||||
.atomic_check = vop2_crtc_atomic_check,
|
||||
.atomic_begin = vop2_crtc_atomic_begin,
|
||||
@@ -3074,6 +3286,336 @@ static const struct regmap_config vop2_regmap_config = {
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * BEGIN virtual clock
|
||||
+ */
|
||||
+#define PLL_RATE_MIN 30000000
|
||||
+
|
||||
+#define cru_dbg(format, ...) do { \
|
||||
+ if (cru_debug) \
|
||||
+ pr_info("%s: " format, __func__, ## __VA_ARGS__); \
|
||||
+ } while (0)
|
||||
+
|
||||
+#define PNAME(x) static const char *const x[]
|
||||
+
|
||||
+enum vop_clk_branch_type {
|
||||
+ branch_mux,
|
||||
+ branch_divider,
|
||||
+ branch_factor,
|
||||
+ branch_virtual,
|
||||
+};
|
||||
+
|
||||
+#define VIR(cname) \
|
||||
+ { \
|
||||
+ .branch_type = branch_virtual, \
|
||||
+ .name = cname, \
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+#define MUX(cname, pnames, f) \
|
||||
+ { \
|
||||
+ .branch_type = branch_mux, \
|
||||
+ .name = cname, \
|
||||
+ .parent_names = pnames, \
|
||||
+ .num_parents = ARRAY_SIZE(pnames), \
|
||||
+ .flags = f, \
|
||||
+ }
|
||||
+
|
||||
+#define FACTOR(cname, pname, f) \
|
||||
+ { \
|
||||
+ .branch_type = branch_factor, \
|
||||
+ .name = cname, \
|
||||
+ .parent_names = (const char *[]){ pname }, \
|
||||
+ .num_parents = 1, \
|
||||
+ .flags = f, \
|
||||
+ }
|
||||
+
|
||||
+#define DIV(cname, pname, f, w) \
|
||||
+ { \
|
||||
+ .branch_type = branch_divider, \
|
||||
+ .name = cname, \
|
||||
+ .parent_names = (const char *[]){ pname }, \
|
||||
+ .num_parents = 1, \
|
||||
+ .flags = f, \
|
||||
+ .div_width = w, \
|
||||
+ }
|
||||
+
|
||||
+struct vop2_clk_branch {
|
||||
+ enum vop_clk_branch_type branch_type;
|
||||
+ const char *name;
|
||||
+ const char *const *parent_names;
|
||||
+ u8 num_parents;
|
||||
+ unsigned long flags;
|
||||
+ u8 div_shift;
|
||||
+ u8 div_width;
|
||||
+ u8 div_flags;
|
||||
+};
|
||||
+
|
||||
+PNAME(mux_port0_dclk_src_p) = { "dclk0", "dclk1" };
|
||||
+PNAME(mux_port2_dclk_src_p) = { "dclk2", "dclk1" };
|
||||
+PNAME(mux_dp_pixclk_p) = { "dclk_out0", "dclk_out1", "dclk_out2" };
|
||||
+PNAME(mux_hdmi_edp_clk_src_p) = { "dclk0", "dclk1", "dclk2" };
|
||||
+PNAME(mux_mipi_clk_src_p) = { "dclk_out1", "dclk_out2", "dclk_out3" };
|
||||
+PNAME(mux_dsc_8k_clk_src_p) = { "dclk0", "dclk1", "dclk2", "dclk3" };
|
||||
+PNAME(mux_dsc_4k_clk_src_p) = { "dclk0", "dclk1", "dclk2", "dclk3" };
|
||||
+
|
||||
+/*
|
||||
+ * We only use this clk driver calculate the div
|
||||
+ * of dclk_core/dclk_out/if_pixclk/if_dclk and
|
||||
+ * the rate of the dclk from the soc.
|
||||
+ *
|
||||
+ * We don't touch the cru in the vop here, as
|
||||
+ * these registers has special read andy write
|
||||
+ * limits.
|
||||
+ */
|
||||
+static struct vop2_clk_branch rk3588_vop_clk_branches[] = {
|
||||
+ VIR("dclk0"),
|
||||
+ VIR("dclk1"),
|
||||
+ VIR("dclk2"),
|
||||
+ VIR("dclk3"),
|
||||
+
|
||||
+ MUX("port0_dclk_src", mux_port0_dclk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ DIV("dclk_core0", "port0_dclk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+ DIV("dclk_out0", "port0_dclk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+
|
||||
+ FACTOR("port1_dclk_src", "dclk1", CLK_SET_RATE_PARENT),
|
||||
+ DIV("dclk_core1", "port1_dclk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+ DIV("dclk_out1", "port1_dclk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+
|
||||
+ MUX("port2_dclk_src", mux_port2_dclk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ DIV("dclk_core2", "port2_dclk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+ DIV("dclk_out2", "port2_dclk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+
|
||||
+ FACTOR("port3_dclk_src", "dclk3", CLK_SET_RATE_PARENT),
|
||||
+ DIV("dclk_core3", "port3_dclk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+ DIV("dclk_out3", "port3_dclk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+
|
||||
+ MUX("dp0_pixclk", mux_dp_pixclk_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ MUX("dp1_pixclk", mux_dp_pixclk_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+
|
||||
+ MUX("hdmi_edp0_clk_src", mux_hdmi_edp_clk_src_p,
|
||||
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ DIV("hdmi_edp0_dclk", "hdmi_edp0_clk_src", 0, 2),
|
||||
+ DIV("hdmi_edp0_pixclk", "hdmi_edp0_clk_src", CLK_SET_RATE_PARENT, 1),
|
||||
+
|
||||
+ MUX("hdmi_edp1_clk_src", mux_hdmi_edp_clk_src_p,
|
||||
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ DIV("hdmi_edp1_dclk", "hdmi_edp1_clk_src", 0, 2),
|
||||
+ DIV("hdmi_edp1_pixclk", "hdmi_edp1_clk_src", CLK_SET_RATE_PARENT, 1),
|
||||
+
|
||||
+ MUX("mipi0_clk_src", mux_mipi_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ DIV("mipi0_pixclk", "mipi0_clk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+
|
||||
+ MUX("mipi1_clk_src", mux_mipi_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ DIV("mipi1_pixclk", "mipi1_clk_src", CLK_SET_RATE_PARENT, 2),
|
||||
+
|
||||
+ FACTOR("rgb_pixclk", "port3_dclk_src", CLK_SET_RATE_PARENT),
|
||||
+
|
||||
+ MUX("dsc_8k_txp_clk_src", mux_dsc_8k_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ DIV("dsc_8k_txp_clk", "dsc_8k_txp_clk_src", 0, 2),
|
||||
+ DIV("dsc_8k_pxl_clk", "dsc_8k_txp_clk_src", 0, 2),
|
||||
+ DIV("dsc_8k_cds_clk", "dsc_8k_txp_clk_src", 0, 2),
|
||||
+
|
||||
+ MUX("dsc_4k_txp_clk_src", mux_dsc_4k_clk_src_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
|
||||
+ DIV("dsc_4k_txp_clk", "dsc_4k_txp_clk_src", 0, 2),
|
||||
+ DIV("dsc_4k_pxl_clk", "dsc_4k_txp_clk_src", 0, 2),
|
||||
+ DIV("dsc_4k_cds_clk", "dsc_4k_txp_clk_src", 0, 2),
|
||||
+};
|
||||
+
|
||||
+static unsigned long clk_virtual_recalc_rate(struct clk_hw *hw,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct vop2_clk *vop2_clk = to_vop2_clk(hw);
|
||||
+
|
||||
+ return (unsigned long)vop2_clk->rate;
|
||||
+}
|
||||
+
|
||||
+static long clk_virtual_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long *prate)
|
||||
+{
|
||||
+ struct vop2_clk *vop2_clk = to_vop2_clk(hw);
|
||||
+
|
||||
+ vop2_clk->rate = rate;
|
||||
+
|
||||
+ return rate;
|
||||
+}
|
||||
+
|
||||
+static int clk_virtual_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+const struct clk_ops clk_virtual_ops = {
|
||||
+ .round_rate = clk_virtual_round_rate,
|
||||
+ .set_rate = clk_virtual_set_rate,
|
||||
+ .recalc_rate = clk_virtual_recalc_rate,
|
||||
+};
|
||||
+
|
||||
+static u8 vop2_mux_get_parent(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct vop2_clk *vop2_clk = to_vop2_clk(hw);
|
||||
+
|
||||
+ // cru_dbg("%s index: %d\n", clk_hw_get_name(hw), vop2_clk->parent_index);
|
||||
+ return vop2_clk->parent_index;
|
||||
+}
|
||||
+
|
||||
+static int vop2_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
+{
|
||||
+ struct vop2_clk *vop2_clk = to_vop2_clk(hw);
|
||||
+
|
||||
+ vop2_clk->parent_index = index;
|
||||
+
|
||||
+ // cru_dbg("%s index: %d\n", clk_hw_get_name(hw), index);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int vop2_clk_mux_determine_rate(struct clk_hw *hw,
|
||||
+ struct clk_rate_request *req)
|
||||
+{
|
||||
+ // cru_dbg("%s %ld(min: %ld max: %ld)\n",
|
||||
+ // clk_hw_get_name(hw), req->rate, req->min_rate, req->max_rate);
|
||||
+ return __clk_mux_determine_rate(hw, req);
|
||||
+}
|
||||
+
|
||||
+static const struct clk_ops vop2_mux_clk_ops = {
|
||||
+ .get_parent = vop2_mux_get_parent,
|
||||
+ .set_parent = vop2_mux_set_parent,
|
||||
+ .determine_rate = vop2_clk_mux_determine_rate,
|
||||
+};
|
||||
+
|
||||
+#define div_mask(width) ((1 << (width)) - 1)
|
||||
+
|
||||
+static int vop2_div_get_val(unsigned long rate, unsigned long parent_rate)
|
||||
+{
|
||||
+ unsigned int div, value;
|
||||
+
|
||||
+ div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
|
||||
+
|
||||
+ value = ilog2(div);
|
||||
+
|
||||
+ return value;
|
||||
+}
|
||||
+
|
||||
+static unsigned long vop2_clk_div_recalc_rate(struct clk_hw *hw,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct vop2_clk *vop2_clk = to_vop2_clk(hw);
|
||||
+ unsigned long rate;
|
||||
+ unsigned int div;
|
||||
+
|
||||
+ div = 1 << vop2_clk->div_val;
|
||||
+ rate = parent_rate / div;
|
||||
+
|
||||
+ // cru_dbg("%s rate: %ld(prate: %ld)\n", clk_hw_get_name(hw), rate, parent_rate);
|
||||
+ return rate;
|
||||
+}
|
||||
+
|
||||
+static long vop2_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long *prate)
|
||||
+{
|
||||
+ struct vop2_clk *vop2_clk = to_vop2_clk(hw);
|
||||
+
|
||||
+ if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
|
||||
+ if (*prate < rate)
|
||||
+ *prate = rate;
|
||||
+ if ((*prate >> vop2_clk->div.width) > rate)
|
||||
+ *prate = rate;
|
||||
+
|
||||
+ if ((*prate % rate))
|
||||
+ *prate = rate;
|
||||
+
|
||||
+ /* SOC PLL can't output a too low pll freq */
|
||||
+ if (*prate < PLL_RATE_MIN)
|
||||
+ *prate = rate << vop2_clk->div.width;
|
||||
+ }
|
||||
+
|
||||
+ // cru_dbg("%s rate: %ld(prate: %ld)\n", clk_hw_get_name(hw), rate, *prate);
|
||||
+ return rate;
|
||||
+}
|
||||
+
|
||||
+static int vop2_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
|
||||
+{
|
||||
+ struct vop2_clk *vop2_clk = to_vop2_clk(hw);
|
||||
+ int div_val;
|
||||
+
|
||||
+ div_val = vop2_div_get_val(rate, parent_rate);
|
||||
+ vop2_clk->div_val = div_val;
|
||||
+
|
||||
+ // cru_dbg("%s prate: %ld rate: %ld div_val: %d\n",
|
||||
+ // clk_hw_get_name(hw), parent_rate, rate, div_val);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct clk_ops vop2_div_clk_ops = {
|
||||
+ .recalc_rate = vop2_clk_div_recalc_rate,
|
||||
+ .round_rate = vop2_clk_div_round_rate,
|
||||
+ .set_rate = vop2_clk_div_set_rate,
|
||||
+};
|
||||
+
|
||||
+static struct clk *vop2_clk_register(struct vop2 *vop2, struct vop2_clk_branch *branch)
|
||||
+{
|
||||
+ struct clk_init_data init = {};
|
||||
+ struct vop2_clk *vop2_clk;
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ vop2_clk = devm_kzalloc(vop2->dev, sizeof(*vop2_clk), GFP_KERNEL);
|
||||
+ if (!vop2_clk)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ vop2_clk->vop2 = vop2;
|
||||
+ vop2_clk->hw.init = &init;
|
||||
+ vop2_clk->div.shift = branch->div_shift;
|
||||
+ vop2_clk->div.width = branch->div_width;
|
||||
+
|
||||
+ init.name = branch->name;
|
||||
+ init.flags = branch->flags;
|
||||
+ init.num_parents = branch->num_parents;
|
||||
+ init.parent_names = branch->parent_names;
|
||||
+ if (branch->branch_type == branch_divider) {
|
||||
+ init.ops = &vop2_div_clk_ops;
|
||||
+ } else if (branch->branch_type == branch_virtual) {
|
||||
+ init.ops = &clk_virtual_ops;
|
||||
+ init.num_parents = 0;
|
||||
+ init.parent_names = NULL;
|
||||
+ } else {
|
||||
+ init.ops = &vop2_mux_clk_ops;
|
||||
+ }
|
||||
+
|
||||
+ clk = devm_clk_register(vop2->dev, &vop2_clk->hw);
|
||||
+ if (!IS_ERR(clk))
|
||||
+ list_add_tail(&vop2_clk->list, &vop2->clk_list_head);
|
||||
+ else
|
||||
+ DRM_DEV_ERROR(vop2->dev, "Register %s failed\n", branch->name);
|
||||
+
|
||||
+ return clk;
|
||||
+}
|
||||
+
|
||||
+static int vop2_clk_init(struct vop2 *vop2)
|
||||
+{
|
||||
+ struct vop2_clk_branch *branch = rk3588_vop_clk_branches;
|
||||
+ unsigned int nr_clk = ARRAY_SIZE(rk3588_vop_clk_branches);
|
||||
+ unsigned int idx;
|
||||
+ struct vop2_clk *clk, *n;
|
||||
+
|
||||
+ INIT_LIST_HEAD(&vop2->clk_list_head);
|
||||
+
|
||||
+ if (vop2->data->soc_id < 3588 || vop2->hdmi0_phy_pll == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ list_for_each_entry_safe(clk, n, &vop2->clk_list_head, list) {
|
||||
+ list_del(&clk->list);
|
||||
+ }
|
||||
+
|
||||
+ for (idx = 0; idx < nr_clk; idx++, branch++)
|
||||
+ vop2_clk_register(vop2, branch);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+/*
|
||||
+ * END virtual clock
|
||||
+ */
|
||||
+
|
||||
static int vop2_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
@@ -3167,6 +3709,12 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
|
||||
return PTR_ERR(vop2->pclk);
|
||||
}
|
||||
|
||||
+ vop2->hdmi0_phy_pll = devm_clk_get_optional(vop2->drm->dev, "hdmi0_phy_pll");
|
||||
+ if (IS_ERR(vop2->hdmi0_phy_pll)) {
|
||||
+ DRM_DEV_ERROR(vop2->dev, "failed to get hdmi0_phy_pll source\n");
|
||||
+ return PTR_ERR(vop2->hdmi0_phy_pll);
|
||||
+ }
|
||||
+
|
||||
vop2->irq = platform_get_irq(pdev, 0);
|
||||
if (vop2->irq < 0) {
|
||||
drm_err(vop2->drm, "cannot find irq for vop2\n");
|
||||
@@ -3183,6 +3731,9 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ // [CC:] rework virtual clock
|
||||
+ vop2_clk_init(vop2);
|
||||
+
|
||||
ret = vop2_find_rgb_encoder(vop2);
|
||||
if (ret >= 0) {
|
||||
vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Mon, 13 May 2024 20:29:49 +0300
|
||||
Subject: arm64: dts: rockchip: rk3588: add VDPU and RGA2 nodes
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 11 ++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -726,6 +726,17 @@ mmu600_php: iommu@fcb00000 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ rga: rga@fdb80000 {
|
||||
+ compatible = "rockchip,rk3568-rga", "rockchip,rk3288-rga";
|
||||
+ reg = <0x0 0xfdb80000 0x0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
+ clocks = <&cru ACLK_RGA2>, <&cru HCLK_RGA2>, <&cru CLK_RGA2_CORE>;
|
||||
+ clock-names = "aclk", "hclk", "sclk";
|
||||
+ resets = <&cru SRST_RGA2_CORE>, <&cru SRST_A_RGA2>, <&cru SRST_H_RGA2>;
|
||||
+ reset-names = "core", "axi", "ahb";
|
||||
+ power-domains = <&power RK3588_PD_VDPU>;
|
||||
+ };
|
||||
+
|
||||
pmu1grf: syscon@fd58a000 {
|
||||
compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
|
||||
reg = <0x0 0xfd58a000 0x0 0x10000>;
|
||||
--
|
||||
Armbian
|
||||
|
6616
kernel.patches/0161-drm-bridge-synopsys-Add-initial-support-for-DW-HDMI-Controller.patch
Normal file
6616
kernel.patches/0161-drm-bridge-synopsys-Add-initial-support-for-DW-HDMI-Controller.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ColorfulRhino <unknown-email@domain.tld>
|
||||
Date: Wed, 12 Jun 2024 12:17:18 +0200
|
||||
Subject: Fix HDMI controller patch at
|
||||
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
|
||||
|
||||
---
|
||||
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
|
||||
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
|
||||
@@ -5,6 +5,7 @@
|
||||
* Algea Cao <algea.cao@rock-chips.com>
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
+#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/err.h>
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,190 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Detlev Casanova <detlev.casanova@collabora.com>
|
||||
Date: Fri, 3 May 2024 14:27:39 -0400
|
||||
Subject: vop2: Add clock resets support
|
||||
|
||||
At the end of initialization, each VP clock needs to be reset before
|
||||
they can be used.
|
||||
|
||||
Failing to do so can put the VOP in an undefined state where the
|
||||
generated HDMI signal is either lost or not matching the selected mode.
|
||||
|
||||
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
|
||||
---
|
||||
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 30 ++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
|
||||
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
#include <linux/swab.h>
|
||||
|
||||
#include <drm/drm.h>
|
||||
@@ -159,6 +160,7 @@ struct vop2_win {
|
||||
struct vop2_video_port {
|
||||
struct drm_crtc crtc;
|
||||
struct vop2 *vop2;
|
||||
+ struct reset_control *dclk_rst;
|
||||
struct clk *dclk;
|
||||
unsigned int id;
|
||||
const struct vop2_video_port_data *data;
|
||||
@@ -2064,6 +2066,26 @@ static struct vop2_clk *vop2_clk_get(struct vop2 *vop2, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static int vop2_clk_reset(struct vop2_video_port *vp)
|
||||
+{
|
||||
+ struct reset_control *rstc = vp->dclk_rst;
|
||||
+ struct vop2 *vop2 = vp->vop2;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!rstc)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = reset_control_assert(rstc);
|
||||
+ if (ret < 0)
|
||||
+ drm_warn(vop2->drm, "failed to assert reset\n");
|
||||
+ udelay(10);
|
||||
+ ret = reset_control_deassert(rstc);
|
||||
+ if (ret < 0)
|
||||
+ drm_warn(vop2->drm, "failed to deassert reset\n");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
@@ -2233,6 +2255,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
|
||||
vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
|
||||
|
||||
+ vop2_clk_reset(vp);
|
||||
+
|
||||
drm_crtc_vblank_on(crtc);
|
||||
|
||||
vop2_unlock(vop2);
|
||||
@@ -2920,6 +2944,12 @@ static int vop2_create_crtcs(struct vop2 *vop2)
|
||||
vp->data = vp_data;
|
||||
|
||||
snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id);
|
||||
+ vp->dclk_rst = devm_reset_control_get_optional(vop2->dev, dclk_name);
|
||||
+ if (IS_ERR(vp->dclk_rst)) {
|
||||
+ drm_err(vop2->drm, "failed to get %s reset\n", dclk_name);
|
||||
+ return PTR_ERR(vp->dclk_rst);
|
||||
+ }
|
||||
+
|
||||
vp->dclk = devm_clk_get(vop2->dev, dclk_name);
|
||||
if (IS_ERR(vp->dclk)) {
|
||||
drm_err(vop2->drm, "failed to get %s\n", dclk_name);
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Detlev Casanova <detlev.casanova@collabora.com>
|
||||
Date: Fri, 3 May 2024 14:28:12 -0400
|
||||
Subject: arm64: dts: rockchip: Add VOP clock resets for rk3588s
|
||||
|
||||
This adds the needed clock resets for all rk3588(s) based SOCs.
|
||||
|
||||
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
||||
@@ -1429,6 +1429,14 @@ vop: vop@fdd90000 {
|
||||
"pclk_vop";
|
||||
iommus = <&vop_mmu>;
|
||||
power-domains = <&power RK3588_PD_VOP>;
|
||||
+ resets = <&cru SRST_D_VOP0>,
|
||||
+ <&cru SRST_D_VOP1>,
|
||||
+ <&cru SRST_D_VOP2>,
|
||||
+ <&cru SRST_D_VOP3>;
|
||||
+ reset-names = "dclk_vp0",
|
||||
+ "dclk_vp1",
|
||||
+ "dclk_vp2",
|
||||
+ "dclk_vp3";
|
||||
rockchip,grf = <&sys_grf>;
|
||||
rockchip,vop-grf = <&vop_grf>;
|
||||
rockchip,vo1-grf = <&vo1_grf>;
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Detlev Casanova <detlev.casanova@collabora.com>
|
||||
Date: Mon, 6 May 2024 13:54:01 -0400
|
||||
Subject: dt-bindings: display: vop2: Add VP clock resets
|
||||
|
||||
Add the documentation for VOP2 video ports reset clocks.
|
||||
One reset can be set per video port.
|
||||
|
||||
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml | 27 ++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
|
||||
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
|
||||
@@ -65,6 +65,22 @@ properties:
|
||||
- const: dclk_vp3
|
||||
- const: pclk_vop
|
||||
|
||||
+ resets:
|
||||
+ minItems: 3
|
||||
+ items:
|
||||
+ - description: Pixel clock reset for video port 0.
|
||||
+ - description: Pixel clock reset for video port 1.
|
||||
+ - description: Pixel clock reset for video port 2.
|
||||
+ - description: Pixel clock reset for video port 3.
|
||||
+
|
||||
+ reset-names:
|
||||
+ minItems: 3
|
||||
+ items:
|
||||
+ - const: dclk_vp0
|
||||
+ - const: dclk_vp1
|
||||
+ - const: dclk_vp2
|
||||
+ - const: dclk_vp3
|
||||
+
|
||||
rockchip,grf:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
@@ -128,6 +144,11 @@ allOf:
|
||||
clock-names:
|
||||
minItems: 7
|
||||
|
||||
+ resets:
|
||||
+ minItems: 4
|
||||
+ reset-names:
|
||||
+ minItems: 4
|
||||
+
|
||||
ports:
|
||||
required:
|
||||
- port@0
|
||||
@@ -183,6 +204,12 @@ examples:
|
||||
"dclk_vp0",
|
||||
"dclk_vp1",
|
||||
"dclk_vp2";
|
||||
+ resets = <&cru SRST_VOP0>,
|
||||
+ <&cru SRST_VOP1>,
|
||||
+ <&cru SRST_VOP2>;
|
||||
+ reset-names = "dclk_vp0",
|
||||
+ "dclk_vp1",
|
||||
+ "dclk_vp2";
|
||||
power-domains = <&power RK3568_PD_VO>;
|
||||
iommus = <&vop_mmu>;
|
||||
vop_out: ports {
|
||||
--
|
||||
Armbian
|
||||
|
74
kernel.patches/0801-wireless-add-bcm43752.patch
Normal file
74
kernel.patches/0801-wireless-add-bcm43752.patch
Normal file
@ -0,0 +1,74 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <unknown-email@domain.tld>
|
||||
Date: Wed, 28 Feb 2024 20:59:15 +0100
|
||||
Subject: net: wireless: brcmfmac: Add support for AP6275P
|
||||
|
||||
This module features BCM43752A2 chipset. The firmware requires
|
||||
randomness seeding, so enabled it.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megi@xff.cz>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 5 ++++-
|
||||
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -70,6 +70,7 @@ BRCMF_FW_CLM_DEF(4377B3, "brcmfmac4377b3-pcie");
|
||||
BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie");
|
||||
BRCMF_FW_CLM_DEF(4378B3, "brcmfmac4378b3-pcie");
|
||||
BRCMF_FW_CLM_DEF(4387C2, "brcmfmac4387c2-pcie");
|
||||
+BRCMF_FW_CLM_DEF(43752, "brcmfmac43752-pcie");
|
||||
|
||||
/* firmware config files */
|
||||
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
|
||||
@@ -104,6 +105,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
|
||||
+ BRCMF_FW_ENTRY(BRCM_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377B3), /* revision ID 4 */
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0x0000000F, 4378B1), /* revision ID 3 */
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFE0, 4378B3), /* revision ID 5 */
|
||||
@@ -1720,7 +1722,7 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
|
||||
memcpy_toio(devinfo->tcm + address, nvram, nvram_len);
|
||||
brcmf_fw_nvram_free(nvram);
|
||||
|
||||
- if (devinfo->otp.valid) {
|
||||
+ if (devinfo->otp.valid || devinfo->ci->chip == BRCM_CC_43752_CHIP_ID) {
|
||||
size_t rand_len = BRCMF_RANDOM_SEED_LENGTH;
|
||||
struct brcmf_random_seed_footer footer = {
|
||||
.length = cpu_to_le32(rand_len),
|
||||
@@ -2700,6 +2702,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID, BCA),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID, WCC),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_43596_DEVICE_ID, CYW),
|
||||
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43752_DEVICE_ID, WCC),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC),
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
|
||||
@@ -52,6 +52,7 @@
|
||||
#define BRCM_CC_43664_CHIP_ID 43664
|
||||
#define BRCM_CC_43666_CHIP_ID 43666
|
||||
#define BRCM_CC_4371_CHIP_ID 0x4371
|
||||
+#define BRCM_CC_43752_CHIP_ID 43752
|
||||
#define BRCM_CC_4377_CHIP_ID 0x4377
|
||||
#define BRCM_CC_4378_CHIP_ID 0x4378
|
||||
#define BRCM_CC_4387_CHIP_ID 0x4387
|
||||
@@ -94,6 +95,7 @@
|
||||
#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
|
||||
#define BRCM_PCIE_4371_DEVICE_ID 0x440d
|
||||
#define BRCM_PCIE_43596_DEVICE_ID 0x4415
|
||||
+#define BRCM_PCIE_43752_DEVICE_ID 0x449d
|
||||
#define BRCM_PCIE_4377_DEVICE_ID 0x4488
|
||||
#define BRCM_PCIE_4378_DEVICE_ID 0x4425
|
||||
#define BRCM_PCIE_4387_DEVICE_ID 0x4433
|
||||
--
|
||||
Armbian
|
||||
|
51
kernel.patches/0802-wireless-add-clk-property.patch
Normal file
51
kernel.patches/0802-wireless-add-clk-property.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <unknown-email@domain.tld>
|
||||
Date: Wed, 28 Feb 2024 21:09:51 +0100
|
||||
Subject: net: wireless: brcmfmac: Add optional 32k clock enable support
|
||||
|
||||
WiFi modules often require 32kHz clock to function. Add support to
|
||||
enable the clock to pcie driver.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megi@xff.cz>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright (c) 2014 Broadcom Corporation
|
||||
*/
|
||||
|
||||
+#include <linux/clk.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/firmware.h>
|
||||
@@ -2413,6 +2414,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
struct brcmf_pciedev *pcie_bus_dev;
|
||||
struct brcmf_core *core;
|
||||
struct brcmf_bus *bus;
|
||||
+ struct clk *clk;
|
||||
|
||||
if (!id) {
|
||||
id = pci_match_id(brcmf_pcie_devid_table, pdev);
|
||||
@@ -2424,6 +2426,14 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
|
||||
|
||||
+ clk = devm_clk_get_optional_enabled(&pdev->dev, "32k");
|
||||
+ if (IS_ERR(clk))
|
||||
+ return PTR_ERR(clk);
|
||||
+ if (clk) {
|
||||
+ dev_info(&pdev->dev, "enabling 32kHz clock\n");
|
||||
+ clk_set_rate(clk, 32768);
|
||||
+ }
|
||||
+
|
||||
ret = -ENOMEM;
|
||||
devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
|
||||
if (devinfo == NULL)
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: amazingfate <liujianfeng1994@gmail.com>
|
||||
Date: Wed, 27 Dec 2023 15:03:57 +0800
|
||||
Subject: arm64: dts: rock-5b: Slow down emmc to hs200 and add tsadc node
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
@@ -371,8 +371,7 @@ &sdhci {
|
||||
no-sdio;
|
||||
no-sd;
|
||||
non-removable;
|
||||
- mmc-hs400-1_8v;
|
||||
- mmc-hs400-enhanced-strobe;
|
||||
+ mmc-hs200-1_8v;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -412,6 +411,10 @@ &sdio {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&tsadc {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&uart6 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: lanefu <lane@lane-fu.com>
|
||||
Date: Sat, 20 Jan 2024 17:16:20 +0000
|
||||
Subject: rock-5b enable SPI flash in device tree
|
||||
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
|
||||
Signed-off-by: lanefu <lane@lane-fu.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 27 ++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
@@ -421,6 +421,33 @@ &uart6 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&sfc {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ spi_flash: spi-flash@0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "jedec,spi-nor";
|
||||
+ reg = <0x0>;
|
||||
+ spi-max-frequency = <50000000>;
|
||||
+ spi-tx-bus-width = <1>;
|
||||
+ spi-rx-bus-width = <4>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ partitions {
|
||||
+ compatible = "fixed-partitions";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ loader@0 {
|
||||
+ label = "loader";
|
||||
+ reg = <0x0 0x1000000>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+};
|
||||
+
|
||||
&spi2 {
|
||||
status = "okay";
|
||||
assigned-clocks = <&cru CLK_SPI2>;
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,67 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Mon, 15 Jan 2024 22:51:17 +0200
|
||||
Subject: arm64: dts: rockchip: Enable HDMI0 on rock-5b
|
||||
|
||||
Add the necessary DT changes to enable HDMI0 on Rock 5B.
|
||||
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 30 ++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
+#include <dt-bindings/soc/rockchip,vop2.h>
|
||||
#include "rk3588.dtsi"
|
||||
|
||||
/ {
|
||||
@@ -185,6 +186,20 @@ &gpu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi0_in {
|
||||
+ hdmi0_in_vp0: endpoint {
|
||||
+ remote-endpoint = <&vp0_out_hdmi0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&hdptxphy_hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&i2c0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c0m2_xfer>;
|
||||
@@ -837,3 +852,18 @@ &usb_host1_xhci {
|
||||
&usb_host2_xhci {
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&vop_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vop {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vp0 {
|
||||
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
||||
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
||||
+ remote-endpoint = <&hdmi0_in_vp0>;
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Fri, 3 Nov 2023 20:05:05 +0200
|
||||
Subject: arm64: dts: rockchip: Make use of HDMI0 PHY PLL on rock-5b
|
||||
|
||||
The initial vop2 support for rk3588 in mainline is not able to handle
|
||||
all display modes supported by connected displays, e.g.
|
||||
2560x1440-75.00Hz, 2048x1152-60.00Hz, 1024x768-60.00Hz.
|
||||
|
||||
Additionally, it doesn't cope with non-integer refresh rates like 59.94,
|
||||
29.97, 23.98, etc.
|
||||
|
||||
Make use of the HDMI0 PHY PLL to support the additional display modes.
|
||||
|
||||
Note this requires commit "drm/rockchip: vop2: Improve display modes
|
||||
handling on rk3588", which needs a rework to be upstreamable.
|
||||
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
@@ -186,6 +186,11 @@ &gpu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&display_subsystem {
|
||||
+ clocks = <&hdptxphy_hdmi0>;
|
||||
+ clock-names = "hdmi0_phy_pll";
|
||||
+};
|
||||
+
|
||||
&hdmi0 {
|
||||
status = "okay";
|
||||
};
|
||||
--
|
||||
Armbian
|
||||
|
68
kernel.patches/1015-board-rock5b-automatic-fan-control.patch
Normal file
68
kernel.patches/1015-board-rock5b-automatic-fan-control.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Charkov <alchark@gmail.com>
|
||||
Date: Mon, 6 May 2024 13:36:35 +0400
|
||||
Subject: arm64: dts: rockchip: enable automatic fan control on Rock 5B
|
||||
|
||||
This links the PWM fan on Radxa Rock 5B as an active cooling device
|
||||
managed automatically by the thermal subsystem, with a target SoC
|
||||
temperature of 65C and a minimum-spin interval from 55C to 65C to
|
||||
ensure airflow when the system gets warm
|
||||
|
||||
Helped-by: Dragan Simic <dsimic@manjaro.org>
|
||||
Reviewed-by: Dragan Simic <dsimic@manjaro.org>
|
||||
Signed-off-by: Alexey Charkov <alchark@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 30 +++++++++-
|
||||
1 file changed, 29 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
|
||||
@@ -53,7 +53,7 @@ led_rgb_b {
|
||||
|
||||
fan: pwm-fan {
|
||||
compatible = "pwm-fan";
|
||||
- cooling-levels = <0 95 145 195 255>;
|
||||
+ cooling-levels = <0 120 150 180 210 240 255>;
|
||||
fan-supply = <&vcc5v0_sys>;
|
||||
pwms = <&pwm1 0 50000 0>;
|
||||
#cooling-cells = <2>;
|
||||
@@ -299,6 +299,34 @@ i2s0_8ch_p0_0: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
+&package_thermal {
|
||||
+ polling-delay = <1000>;
|
||||
+
|
||||
+ trips {
|
||||
+ package_fan0: package-fan0 {
|
||||
+ temperature = <55000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "active";
|
||||
+ };
|
||||
+ package_fan1: package-fan1 {
|
||||
+ temperature = <65000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "active";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cooling-maps {
|
||||
+ map1 {
|
||||
+ trip = <&package_fan0>;
|
||||
+ cooling-device = <&fan THERMAL_NO_LIMIT 1>;
|
||||
+ };
|
||||
+ map2 {
|
||||
+ trip = <&package_fan1>;
|
||||
+ cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&pcie2x1l0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pcie2_0_rst>;
|
||||
--
|
||||
Armbian
|
||||
|
57
kernel.patches/1020-Add-HDMI-and-VOP2-to-Rock-5A.patch
Normal file
57
kernel.patches/1020-Add-HDMI-and-VOP2-to-Rock-5A.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Tue, 27 Feb 2024 16:04:42 +0300
|
||||
Subject: Add HDMI and VOP2 to Rock 5A
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 30 ++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
+#include <dt-bindings/soc/rockchip,vop2.h>
|
||||
#include "rk3588s.dtsi"
|
||||
|
||||
/ {
|
||||
@@ -765,3 +766,32 @@ &usb_host1_ohci {
|
||||
&usb_host2_xhci {
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdptxphy_hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vop_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi0_in {
|
||||
+ hdmi0_in_vp0: endpoint {
|
||||
+ remote-endpoint = <&vp0_out_hdmi0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&vop {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vp0 {
|
||||
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
||||
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
||||
+ remote-endpoint = <&hdmi0_in_vp0>;
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: amazingfate <liujianfeng1994@gmail.com>
|
||||
Date: Thu, 28 Mar 2024 00:41:34 +0800
|
||||
Subject: arch: arm64: dts: enable gpu node for rock-5a
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
@@ -281,6 +281,11 @@ &gmac1_rgmii_clk
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&gpu {
|
||||
+ mali-supply = <&vdd_gpu_s0>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&mdio1 {
|
||||
rgmii_phy1: ethernet-phy@1 {
|
||||
/* RTL8211F */
|
||||
@@ -434,6 +439,7 @@ rk806_dvs3_null: dvs3-null-pins {
|
||||
regulators {
|
||||
vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
|
||||
regulator-name = "vdd_gpu_s0";
|
||||
+ regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,265 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Thu, 16 Nov 2023 18:15:09 +0300
|
||||
Subject: arm64: dts: Add missing nodes to Orange Pi 5 Plus
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 182 +++++++++-
|
||||
1 file changed, 181 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
#include <dt-bindings/usb/pd.h>
|
||||
+#include <dt-bindings/soc/rockchip,vop2.h>
|
||||
#include "rk3588.dtsi"
|
||||
|
||||
/ {
|
||||
@@ -158,6 +159,20 @@ daicodec: simple-audio-card,codec {
|
||||
};
|
||||
};
|
||||
|
||||
+ wlan-rfkill {
|
||||
+ compatible = "rfkill-gpio";
|
||||
+ label = "rfkill-wlan";
|
||||
+ radio-type = "wlan";
|
||||
+ shutdown-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ bluetooth-rfkill {
|
||||
+ compatible = "rfkill-gpio";
|
||||
+ label = "rfkill-bluetooth";
|
||||
+ radio-type = "bluetooth";
|
||||
+ shutdown-gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
vcc3v3_pcie30: vcc3v3-pcie30-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
enable-active-high;
|
||||
@@ -199,6 +214,18 @@ vcc5v0_sys: vcc5v0-sys-regulator {
|
||||
regulator-max-microvolt = <5000000>;
|
||||
};
|
||||
|
||||
+ vbus5v0_typec: vbus5v0-typec-regulator {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ enable-active-high;
|
||||
+ gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
|
||||
+ regulator-name = "vbus5v0_typec";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&typec5v_pwren>;
|
||||
+ vin-supply = <&vcc5v0_sys>;
|
||||
+ };
|
||||
+
|
||||
vcc5v0_usb20: vcc5v0-usb20-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
enable-active-high;
|
||||
@@ -311,6 +338,53 @@ hym8563: rtc@51 {
|
||||
pinctrl-0 = <&hym8563_int>;
|
||||
wakeup-source;
|
||||
};
|
||||
+
|
||||
+ usbc0: usb-typec@22 {
|
||||
+ compatible = "fcs,fusb302";
|
||||
+ reg = <0x22>;
|
||||
+ interrupt-parent = <&gpio0>;
|
||||
+ interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&usbc0_int>;
|
||||
+ vbus-supply = <&vbus5v0_typec>;
|
||||
+
|
||||
+ usb_con: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C";
|
||||
+ data-role = "dual";
|
||||
+ power-role = "dual";
|
||||
+ try-power-role = "source";
|
||||
+ op-sink-microwatt = <1000000>;
|
||||
+ sink-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
|
||||
+ source-pdos = <PDO_FIXED(5000, 1500, PDO_FIXED_USB_COMM)>;
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ usbc0_hs: endpoint {
|
||||
+ remote-endpoint = <&usb_host0_xhci_drd_sw>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@1 {
|
||||
+ reg = <1>;
|
||||
+ usbc0_ss: endpoint {
|
||||
+ remote-endpoint = <&usbdp_phy0_typec_ss>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@2 {
|
||||
+ reg = <2>;
|
||||
+ usbc0_sbu: endpoint {
|
||||
+ remote-endpoint = <&usbdp_phy0_typec_sbu>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&i2c7 {
|
||||
@@ -385,7 +459,7 @@ &pcie3x4 {
|
||||
&pinctrl {
|
||||
hym8563 {
|
||||
hym8563_int: hym8563-int {
|
||||
- rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -408,6 +482,14 @@ hp_detect: hp-detect {
|
||||
};
|
||||
|
||||
usb {
|
||||
+ typec5v_pwren: typec5v-pwren {
|
||||
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
+ };
|
||||
+
|
||||
+ usbc0_int: usbc0-int {
|
||||
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
+ };
|
||||
+
|
||||
vcc5v0_usb20_en: vcc5v0-usb20-en {
|
||||
rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
};
|
||||
@@ -803,6 +885,22 @@ &tsadc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&u2phy0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&u2phy0_otg {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&u2phy1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&u2phy1_otg {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&u2phy2 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -831,6 +929,35 @@ &uart9 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&usbdp_phy0 {
|
||||
+ orientation-switch;
|
||||
+ mode-switch;
|
||||
+ sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
|
||||
+ sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
|
||||
+ status = "okay";
|
||||
+ svid = <0xff01>;
|
||||
+
|
||||
+ port {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ usbdp_phy0_typec_ss: endpoint@0 {
|
||||
+ reg = <0>;
|
||||
+ remote-endpoint = <&usbc0_ss>;
|
||||
+ };
|
||||
+
|
||||
+ usbdp_phy0_typec_sbu: endpoint@1 {
|
||||
+ reg = <1>;
|
||||
+ remote-endpoint = <&usbc0_sbu>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&usbdp_phy1 {
|
||||
+ rockchip,dp-lane-mux = <2 3>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&usb_host0_ehci {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -839,6 +966,20 @@ &usb_host0_ohci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&usb_host0_xhci {
|
||||
+ dr_mode = "otg";
|
||||
+ usb-role-switch;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ port {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ usb_host0_xhci_drd_sw: endpoint {
|
||||
+ remote-endpoint = <&usbc0_hs>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&usb_host1_ehci {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -846,3 +987,42 @@ &usb_host1_ehci {
|
||||
&usb_host1_ohci {
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&usb_host1_xhci {
|
||||
+ dr_mode = "host";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&gpu {
|
||||
+ mali-supply = <&vdd_gpu_s0>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdptxphy_hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vop_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi0_in {
|
||||
+ hdmi0_in_vp0: endpoint {
|
||||
+ remote-endpoint = <&vp0_out_hdmi0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&vop {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vp0 {
|
||||
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
||||
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
||||
+ remote-endpoint = <&hdmi0_in_vp0>;
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: amazingfate <liujianfeng1994@gmail.com>
|
||||
Date: Thu, 28 Mar 2024 16:07:18 +0800
|
||||
Subject: arm64: dts: rockchip: add PCIe for M.2 E-Key to rock-5a
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
|
||||
@@ -115,6 +115,10 @@ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
|
||||
};
|
||||
};
|
||||
|
||||
+&combphy0_ps {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&combphy2_psu {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -299,6 +303,11 @@ rgmii_phy1: ethernet-phy@1 {
|
||||
};
|
||||
};
|
||||
|
||||
+&pcie2x1l2 {
|
||||
+ status = "okay";
|
||||
+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
|
||||
+};
|
||||
+
|
||||
&pinctrl {
|
||||
leds {
|
||||
io_led: io-led {
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,64 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jianfeng Liu <liujianfeng1994@gmail.com>
|
||||
Date: Thu, 6 Jun 2024 23:28:01 +0800
|
||||
Subject: arm64: dts: rockchip: Add HDMI support to ArmSoM Sige7
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts | 30 ++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
+#include <dt-bindings/soc/rockchip,vop2.h>
|
||||
#include "rk3588.dtsi"
|
||||
|
||||
/ {
|
||||
@@ -164,6 +165,20 @@ &gpu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi0_in {
|
||||
+ hdmi0_in_vp0: endpoint {
|
||||
+ remote-endpoint = <&vp0_out_hdmi0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&hdptxphy_hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&i2c0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c0m2_xfer>;
|
||||
@@ -723,3 +738,18 @@ &usb_host1_xhci {
|
||||
dr_mode = "host";
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&vop {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vop_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vp0 {
|
||||
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
||||
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
||||
+ remote-endpoint = <&hdmi0_in_vp0>;
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jianfeng Liu <liujianfeng1994@gmail.com>
|
||||
Date: Thu, 6 Jun 2024 23:29:39 +0800
|
||||
Subject: arm64: dts: rockchip: Add ap6275p wireless support to ArmSoM Sige7
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts | 16 ++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
|
||||
@@ -283,6 +283,22 @@ &pcie2x1l0 {
|
||||
&pcie2x1l1 {
|
||||
reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
+
|
||||
+ pcie@0,0 {
|
||||
+ reg = <0x300000 0 0 0 0>;
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+ device_type = "pci";
|
||||
+ bus-range = <0x30 0x3f>;
|
||||
+
|
||||
+ wifi: wifi@0,0 {
|
||||
+ compatible = "pci14e4,449d";
|
||||
+ reg = <0x310000 0 0 0 0>;
|
||||
+ clocks = <&hym8563>;
|
||||
+ clock-names = "32k";
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
/* phy0 - left ethernet port */
|
||||
--
|
||||
Armbian
|
||||
|
325
kernel.patches/1040-board-khadas-edge2-add-nodes.patch
Normal file
325
kernel.patches/1040-board-khadas-edge2-add-nodes.patch
Normal file
@ -0,0 +1,325 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Mon, 12 Feb 2024 17:35:13 +0300
|
||||
Subject: arm64: dts: rockchip: Add USB-C to Khadas Edge 2
|
||||
|
||||
Khadas Edge 2 has 2x Type-C port. One just supports PD and
|
||||
controlled by MCU. The other one supports PD, DP Alt mode and DRD. This
|
||||
commit adds support for DRD.
|
||||
|
||||
Signed-off-by: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts | 120 ++++++++++
|
||||
1 file changed, 120 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
+#include <dt-bindings/usb/pd.h>
|
||||
#include "rk3588s.dtsi"
|
||||
|
||||
/ {
|
||||
@@ -76,6 +77,18 @@ blue_led: led-2 {
|
||||
};
|
||||
};
|
||||
|
||||
+ vbus5v0_typec: vbus5v0-typec-regulator {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "vbus5v0_typec";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ enable-active-high;
|
||||
+ gpio = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>;
|
||||
+ vin-supply = <&vcc5v0_sys>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&typec5v_pwren>;
|
||||
+ };
|
||||
+
|
||||
vcc3v3_pcie_wl: vcc3v3-pcie-wl-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
enable-active-high;
|
||||
@@ -224,6 +237,56 @@ regulator-state-mem {
|
||||
&i2c2 {
|
||||
status = "okay";
|
||||
|
||||
+ usbc0: usb-typec@22 {
|
||||
+ compatible = "fcs,fusb302";
|
||||
+ reg = <0x22>;
|
||||
+ interrupt-parent = <&gpio1>;
|
||||
+ interrupts = <RK_PB5 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&usbc0_int>;
|
||||
+ vbus-supply = <&vbus5v0_typec>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ usb_con: connector {
|
||||
+ compatible = "usb-c-connector";
|
||||
+ label = "USB-C";
|
||||
+ data-role = "dual";
|
||||
+ power-role = "dual";
|
||||
+ try-power-role = "source";
|
||||
+ op-sink-microwatt = <1000000>;
|
||||
+ sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
|
||||
+ PDO_FIXED(9000, 3000, PDO_FIXED_USB_COMM)
|
||||
+ PDO_FIXED(12000, 3000, PDO_FIXED_USB_COMM)>;
|
||||
+ source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ usbc0_orien_sw: endpoint {
|
||||
+ remote-endpoint = <&usbdp_phy0_orientation_switch>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@1 {
|
||||
+ reg = <1>;
|
||||
+ usbc0_role_sw: endpoint {
|
||||
+ remote-endpoint = <&dwc3_0_role_switch>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@2 {
|
||||
+ reg = <2>;
|
||||
+ dp_altmode_mux: endpoint {
|
||||
+ remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
hym8563: rtc@51 {
|
||||
compatible = "haoyu,hym8563";
|
||||
reg = <0x51>;
|
||||
@@ -256,6 +319,16 @@ vcc5v0_host_en: vcc5v0-host-en {
|
||||
};
|
||||
};
|
||||
|
||||
+ usb-typec {
|
||||
+ usbc0_int: usbc0-int {
|
||||
+ rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
+ };
|
||||
+
|
||||
+ typec5v_pwren: typec5v-pwren {
|
||||
+ rockchip,pins = <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
ir-receiver {
|
||||
ir_receiver_pin: ir-receiver-pin {
|
||||
rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
@@ -681,6 +754,15 @@ &uart9 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&u2phy0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&u2phy0_otg {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+
|
||||
&u2phy2 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -707,6 +789,44 @@ &usb_host0_ohci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&usbdp_phy0 {
|
||||
+ orientation-switch;
|
||||
+ mode-switch;
|
||||
+ svid = <0xff01>;
|
||||
+ sbu1-dc-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>;
|
||||
+ sbu2-dc-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ port {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ usbdp_phy0_orientation_switch: endpoint@0 {
|
||||
+ reg = <0>;
|
||||
+ remote-endpoint = <&usbc0_orien_sw>;
|
||||
+ };
|
||||
+
|
||||
+ usbdp_phy0_dp_altmode_mux: endpoint@1 {
|
||||
+ reg = <1>;
|
||||
+ remote-endpoint = <&dp_altmode_mux>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&usb_host0_xhci {
|
||||
+ usb-role-switch;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ port {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ dwc3_0_role_switch: endpoint@0 {
|
||||
+ reg = <0>;
|
||||
+ remote-endpoint = <&usbc0_role_sw>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&usb_host1_ehci {
|
||||
status = "okay";
|
||||
};
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Mon, 12 Feb 2024 17:35:13 +0300
|
||||
Subject: arm64: dts: rockchip: Add bluetooth rfkill to Khadas Edge 2
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
@@ -116,6 +116,15 @@ vcc5v0_host: vcc5v0-host-regulator {
|
||||
vin-supply = <&vcc5v0_sys>;
|
||||
};
|
||||
|
||||
+ bluetooth-rfkill {
|
||||
+ compatible = "rfkill-gpio";
|
||||
+ label = "rfkill-bluetooth";
|
||||
+ radio-type = "bluetooth";
|
||||
+ shutdown-gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_LOW>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&bt_reset_pin>;
|
||||
+ };
|
||||
+
|
||||
vcc5v0_sys: vcc5v0-sys-regulator {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc5v0_sys";
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Mon, 19 Feb 2024 23:32:11 +0300
|
||||
Subject: arm64: dts: rockchip: Add HDMI & VOP2 to Khadas Edge 2
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts | 36 ++++++++++
|
||||
1 file changed, 36 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/usb/pd.h>
|
||||
+#include <dt-bindings/soc/rockchip,vop2.h>
|
||||
#include "rk3588s.dtsi"
|
||||
|
||||
/ {
|
||||
@@ -823,6 +824,7 @@ usbdp_phy0_dp_altmode_mux: endpoint@1 {
|
||||
};
|
||||
|
||||
&usb_host0_xhci {
|
||||
+ dr-mode = "otg";
|
||||
usb-role-switch;
|
||||
status = "okay";
|
||||
|
||||
@@ -847,3 +849,37 @@ &usb_host1_ohci {
|
||||
&usb_host2_xhci {
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdptxphy_hdmi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&display_subsystem {
|
||||
+ clocks = <&hdptxphy_hdmi0>;
|
||||
+ clock-names = "hdmi0_phy_pll";
|
||||
+};
|
||||
+
|
||||
+&vop_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi0_in {
|
||||
+ hdmi0_in_vp0: endpoint {
|
||||
+ remote-endpoint = <&vp0_out_hdmi0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&vop {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vp0 {
|
||||
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
|
||||
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
|
||||
+ remote-endpoint = <&hdmi0_in_vp0>;
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Sat, 2 Mar 2024 19:13:59 +0300
|
||||
Subject: arm64: dts: rockchip: Add AP6275P wireless support to Khadas Edge 2
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts | 17 ++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
@@ -366,6 +366,23 @@ &pcie2x1l2 {
|
||||
reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
|
||||
vpcie3v3-supply = <&vcc3v3_pcie_wl>;
|
||||
status = "okay";
|
||||
+
|
||||
+ pcie@0,0 {
|
||||
+ reg = <0x400000 0 0 0 0>;
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+ device_type = "pci";
|
||||
+ bus-range = <0x40 0x4f>;
|
||||
+
|
||||
+ wifi: wifi@0,0 {
|
||||
+ compatible = "pci14e4,449d";
|
||||
+ reg = <0x410000 0 0 0 0>;
|
||||
+ clocks = <&hym8563>;
|
||||
+ clock-names = "32k";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
};
|
||||
|
||||
&pwm11 {
|
||||
--
|
||||
Armbian
|
||||
|
441
kernel.patches/1041-board-khadas-edge2-mcu.patch
Normal file
441
kernel.patches/1041-board-khadas-edge2-mcu.patch
Normal file
@ -0,0 +1,441 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Wed, 6 Mar 2024 00:09:25 +0300
|
||||
Subject: mfd: khadas-mcu: add Edge2 registers
|
||||
|
||||
---
|
||||
drivers/mfd/khadas-mcu.c | 8 +++-
|
||||
include/linux/mfd/khadas-mcu.h | 24 ++++++++++
|
||||
2 files changed, 30 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/mfd/khadas-mcu.c
|
||||
+++ b/drivers/mfd/khadas-mcu.c
|
||||
@@ -26,6 +26,10 @@ static bool khadas_mcu_reg_volatile(struct device *dev, unsigned int reg)
|
||||
case KHADAS_MCU_CHECK_USER_PASSWD_REG:
|
||||
case KHADAS_MCU_WOL_INIT_START_REG:
|
||||
case KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG:
|
||||
+ case KHADAS_MCU_LED_ON_RAM_REG:
|
||||
+ case KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG_V2:
|
||||
+ case KHADAS_MCU_WDT_EN_REG:
|
||||
+ case KHADAS_MCU_SYS_RST_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -69,14 +73,14 @@ static const struct regmap_config khadas_mcu_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.reg_stride = 1,
|
||||
.val_bits = 8,
|
||||
- .max_register = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
|
||||
+ .max_register = KHADAS_MCU_SYS_RST_REG,
|
||||
.volatile_reg = khadas_mcu_reg_volatile,
|
||||
.writeable_reg = khadas_mcu_reg_writeable,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static struct mfd_cell khadas_mcu_fan_cells[] = {
|
||||
- /* VIM1/2 Rev13+ and VIM3 only */
|
||||
+ /* VIM1/2 Rev13+, VIM3 and Edge2 only */
|
||||
{ .name = "khadas-mcu-fan-ctrl", },
|
||||
};
|
||||
|
||||
diff --git a/include/linux/mfd/khadas-mcu.h b/include/linux/mfd/khadas-mcu.h
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/include/linux/mfd/khadas-mcu.h
|
||||
+++ b/include/linux/mfd/khadas-mcu.h
|
||||
@@ -35,26 +35,45 @@
|
||||
#define KHADAS_MCU_FACTORY_TEST_REG 0x16 /* R */
|
||||
#define KHADAS_MCU_BOOT_MODE_REG 0x20 /* RW */
|
||||
#define KHADAS_MCU_BOOT_EN_WOL_REG 0x21 /* RW */
|
||||
+#define KHADAS_MCU_BOOT_EN_DCIN_REG_V2 0x21 /* RW */
|
||||
#define KHADAS_MCU_BOOT_EN_RTC_REG 0x22 /* RW */
|
||||
#define KHADAS_MCU_BOOT_EN_EXP_REG 0x23 /* RW */
|
||||
+#define KHADAS_MCU_LED_MODE_ON_REG_V2 0x23 /* RW */
|
||||
+#define KHADAS_MCU_LED_MODE_OFF_REG_V2 0x24 /* RW */
|
||||
#define KHADAS_MCU_BOOT_EN_IR_REG 0x24 /* RW */
|
||||
#define KHADAS_MCU_BOOT_EN_DCIN_REG 0x25 /* RW */
|
||||
+#define KHADAS_MCU_RGB_ON_R_REG 0x25 /* RW */
|
||||
+#define KHADAS_MCU_RGB_ON_G_REG 0x26 /* RW */
|
||||
#define KHADAS_MCU_BOOT_EN_KEY_REG 0x26 /* RW */
|
||||
+#define KHADAS_MCU_RGB_ON_B_REG 0x27 /* RW */
|
||||
#define KHADAS_MCU_KEY_MODE_REG 0x27 /* RW */
|
||||
+#define KHADAS_MCU_RGB_OFF_R_REG 0x28 /* RW */
|
||||
#define KHADAS_MCU_LED_MODE_ON_REG 0x28 /* RW */
|
||||
+#define KHADAS_MCU_RGB_OFF_G_REG 0x29 /* RW */
|
||||
#define KHADAS_MCU_LED_MODE_OFF_REG 0x29 /* RW */
|
||||
+#define KHADAS_MCU_RGB_OFF_B_REG 0x2a /* RW */
|
||||
#define KHADAS_MCU_SHUTDOWN_NORMAL_REG 0x2c /* RW */
|
||||
#define KHADAS_MCU_MAC_SWITCH_REG 0x2d /* RW */
|
||||
+#define KHADAS_MCU_REST_CONF_REG 0x2e /* RW */
|
||||
#define KHADAS_MCU_MCU_SLEEP_MODE_REG 0x2e /* RW */
|
||||
+#define KHADAS_MCU_BOOT_EN_IR_REG_V2 0x2f /* RW */
|
||||
#define KHADAS_MCU_IR_CODE1_0_REG 0x2f /* RW */
|
||||
#define KHADAS_MCU_IR_CODE1_1_REG 0x30 /* RW */
|
||||
+#define KHADAS_MCU_IR1_CUST1_REG 0x30 /* RW */
|
||||
#define KHADAS_MCU_IR_CODE1_2_REG 0x31 /* RW */
|
||||
+#define KHADAS_MCU_IR1_CUST2_REG 0x31 /* RW */
|
||||
#define KHADAS_MCU_IR_CODE1_3_REG 0x32 /* RW */
|
||||
+#define KHADAS_MCU_IR1_ORDER1_REG 0x32 /* RW */
|
||||
#define KHADAS_MCU_USB_PCIE_SWITCH_REG 0x33 /* RW */
|
||||
+#define KHADAS_MCU_IR1_ORDER2_REG 0x33 /* RW */
|
||||
+#define KHADAS_MCU_IR2_CUST1_REG 0x34 /* RW */
|
||||
#define KHADAS_MCU_IR_CODE2_0_REG 0x34 /* RW */
|
||||
#define KHADAS_MCU_IR_CODE2_1_REG 0x35 /* RW */
|
||||
+#define KHADAS_MCU_IR2_CUST2_REG 0x35 /* RW */
|
||||
#define KHADAS_MCU_IR_CODE2_2_REG 0x36 /* RW */
|
||||
+#define KHADAS_MCU_IR2_ORDER1_REG 0x36 /* RW */
|
||||
#define KHADAS_MCU_IR_CODE2_3_REG 0x37 /* RW */
|
||||
+#define KHADAS_MCU_IR2_ORDER2_REG 0x36 /* RW */
|
||||
#define KHADAS_MCU_PASSWD_USER_0_REG 0x40 /* RW */
|
||||
#define KHADAS_MCU_PASSWD_USER_1_REG 0x41 /* RW */
|
||||
#define KHADAS_MCU_PASSWD_USER_2_REG 0x42 /* RW */
|
||||
@@ -69,6 +88,10 @@
|
||||
#define KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG 0x86 /* RO */
|
||||
#define KHADAS_MCU_WOL_INIT_START_REG 0x87 /* WO */
|
||||
#define KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG 0x88 /* WO */
|
||||
+#define KHADAS_MCU_LED_ON_RAM_REG 0x89 /* WO */
|
||||
+#define KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG_V2 0x8A /* WO */
|
||||
+#define KHADAS_MCU_WDT_EN_REG 0x8B /* WO */
|
||||
+#define KHADAS_MCU_SYS_RST_REG 0x91 /* WO */
|
||||
|
||||
enum {
|
||||
KHADAS_BOARD_VIM1 = 0x1,
|
||||
@@ -76,6 +99,7 @@ enum {
|
||||
KHADAS_BOARD_VIM3,
|
||||
KHADAS_BOARD_EDGE = 0x11,
|
||||
KHADAS_BOARD_EDGE_V,
|
||||
+ KHADAS_BOARD_EDGE2,
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Wed, 6 Mar 2024 00:09:58 +0300
|
||||
Subject: mfd: khadas-mcu: drop unused code
|
||||
|
||||
---
|
||||
drivers/mfd/khadas-mcu.c | 11 ----------
|
||||
1 file changed, 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/mfd/khadas-mcu.c
|
||||
+++ b/drivers/mfd/khadas-mcu.c
|
||||
@@ -84,10 +84,6 @@ static struct mfd_cell khadas_mcu_fan_cells[] = {
|
||||
{ .name = "khadas-mcu-fan-ctrl", },
|
||||
};
|
||||
|
||||
-static struct mfd_cell khadas_mcu_cells[] = {
|
||||
- { .name = "khadas-mcu-user-mem", },
|
||||
-};
|
||||
-
|
||||
static int khadas_mcu_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
@@ -109,13 +105,6 @@ static int khadas_mcu_probe(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
|
||||
- khadas_mcu_cells,
|
||||
- ARRAY_SIZE(khadas_mcu_cells),
|
||||
- NULL, 0, NULL);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
if (of_property_present(dev->of_node, "#cooling-cells"))
|
||||
return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
|
||||
khadas_mcu_fan_cells,
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Wed, 6 Mar 2024 00:13:10 +0300
|
||||
Subject: thermal: khadas_mcu_fan: add support for Khadas Edge 2
|
||||
|
||||
---
|
||||
drivers/thermal/khadas_mcu_fan.c | 77 +++++++++-
|
||||
1 file changed, 73 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/khadas_mcu_fan.c b/drivers/thermal/khadas_mcu_fan.c
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/drivers/thermal/khadas_mcu_fan.c
|
||||
+++ b/drivers/thermal/khadas_mcu_fan.c
|
||||
@@ -15,10 +15,16 @@
|
||||
#include <linux/thermal.h>
|
||||
|
||||
#define MAX_LEVEL 3
|
||||
+#define MAX_SPEED 0x64
|
||||
|
||||
struct khadas_mcu_fan_ctx {
|
||||
struct khadas_mcu *mcu;
|
||||
unsigned int level;
|
||||
+
|
||||
+ unsigned int fan_max_level;
|
||||
+ unsigned int fan_register;
|
||||
+ unsigned int *fan_cooling_levels;
|
||||
+
|
||||
struct thermal_cooling_device *cdev;
|
||||
};
|
||||
|
||||
@@ -26,9 +32,21 @@ static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
|
||||
unsigned int level)
|
||||
{
|
||||
int ret;
|
||||
+ unsigned int write_level = level;
|
||||
+
|
||||
+ if (level > ctx->fan_max_level)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (ctx->fan_cooling_levels != NULL) {
|
||||
+ write_level = ctx->fan_cooling_levels[level];
|
||||
+
|
||||
+ if (write_level > MAX_SPEED)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = regmap_write(ctx->mcu->regmap, ctx->fan_register,
|
||||
+ write_level);
|
||||
|
||||
- ret = regmap_write(ctx->mcu->regmap, KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
|
||||
- level);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -40,7 +58,9 @@ static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
|
||||
static int khadas_mcu_fan_get_max_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
- *state = MAX_LEVEL;
|
||||
+ struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
|
||||
+
|
||||
+ *state = ctx->fan_max_level;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -61,7 +81,7 @@ khadas_mcu_fan_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
{
|
||||
struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
|
||||
|
||||
- if (state > MAX_LEVEL)
|
||||
+ if (state > ctx->fan_max_level)
|
||||
return -EINVAL;
|
||||
|
||||
if (state == ctx->level)
|
||||
@@ -76,6 +96,48 @@ static const struct thermal_cooling_device_ops khadas_mcu_fan_cooling_ops = {
|
||||
.set_cur_state = khadas_mcu_fan_set_cur_state,
|
||||
};
|
||||
|
||||
+// Khadas Edge 2 sets fan level by passing fan speed(0-100). So we need different logic here like pwm-fan cooling-levels.
|
||||
+// This is optional and just necessary for Edge 2.
|
||||
+static int khadas_mcu_fan_get_cooling_data_edge2(struct khadas_mcu_fan_ctx *ctx, struct device *dev) {
|
||||
+ struct device_node *np = ctx->mcu->dev->of_node;
|
||||
+ int num, i, ret;
|
||||
+
|
||||
+ if (!of_property_present(np, "cooling-levels"))
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = of_property_count_u32_elems(np, "cooling-levels");
|
||||
+ if (ret <= 0) {
|
||||
+ dev_err(dev, "Wrong data!\n");
|
||||
+ return ret ? : -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ num = ret;
|
||||
+ ctx->fan_cooling_levels = devm_kcalloc(dev, num, sizeof(u32),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ctx->fan_cooling_levels)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = of_property_read_u32_array(np, "cooling-levels",
|
||||
+ ctx->fan_cooling_levels, num);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Property 'cooling-levels' cannot be read!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ if (ctx->fan_cooling_levels[i] > MAX_SPEED) {
|
||||
+ dev_err(dev, "PWM fan state[%d]:%d > %d\n", i,
|
||||
+ ctx->fan_cooling_levels[i], MAX_SPEED);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ctx->fan_max_level = num - 1;
|
||||
+ ctx->fan_register = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG_V2;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int khadas_mcu_fan_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct khadas_mcu *mcu = dev_get_drvdata(pdev->dev.parent);
|
||||
@@ -90,6 +152,13 @@ static int khadas_mcu_fan_probe(struct platform_device *pdev)
|
||||
ctx->mcu = mcu;
|
||||
platform_set_drvdata(pdev, ctx);
|
||||
|
||||
+ ctx->fan_max_level = MAX_LEVEL;
|
||||
+ ctx->fan_register = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG;
|
||||
+
|
||||
+ ret = khadas_mcu_fan_get_cooling_data_edge2(ctx, dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
cdev = devm_thermal_of_cooling_device_register(dev->parent,
|
||||
dev->parent->of_node, "khadas-mcu-fan", ctx,
|
||||
&khadas_mcu_fan_cooling_ops);
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Wed, 6 Mar 2024 00:14:58 +0300
|
||||
Subject: dt-bindings: mfd: khadas-mcu: add cooling-levels property
|
||||
|
||||
---
|
||||
Documentation/devicetree/bindings/mfd/khadas,mcu.yaml | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/mfd/khadas,mcu.yaml b/Documentation/devicetree/bindings/mfd/khadas,mcu.yaml
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/Documentation/devicetree/bindings/mfd/khadas,mcu.yaml
|
||||
+++ b/Documentation/devicetree/bindings/mfd/khadas,mcu.yaml
|
||||
@@ -11,7 +11,7 @@ maintainers:
|
||||
|
||||
description: |
|
||||
Khadas embeds a microcontroller on their VIM and Edge boards adding some
|
||||
- system feature as PWM Fan control (for VIM2 rev14 or VIM3), User memory
|
||||
+ system feature as PWM Fan control (for VIM2 rev14, VIM3, Edge2), User memory
|
||||
storage, IR/Key resume control, system power LED control and more.
|
||||
|
||||
properties:
|
||||
@@ -22,6 +22,11 @@ properties:
|
||||
"#cooling-cells": # Only needed for boards having FAN control feature
|
||||
const: 2
|
||||
|
||||
+ cooling-levels:
|
||||
+ description: Max speed of PWM fan. This property is necessary for Khadas Edge 2.
|
||||
+ items:
|
||||
+ maximum: 100
|
||||
+
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Wed, 6 Mar 2024 00:17:58 +0300
|
||||
Subject: arm64: dts: rockchip: Add MCU to Khadas Edge 2
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
@@ -304,6 +304,13 @@ hym8563: rtc@51 {
|
||||
clock-output-names = "hym8563";
|
||||
wakeup-source;
|
||||
};
|
||||
+
|
||||
+ khadas_mcu: system-controller@18 {
|
||||
+ compatible = "khadas,mcu";
|
||||
+ reg = <0x18>;
|
||||
+ cooling-levels = <0 50 72 100>;
|
||||
+ #cooling-cells = <2>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
--
|
||||
Armbian
|
||||
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Muhammed Efe Cetin <efectn@protonmail.com>
|
||||
Date: Mon, 25 Mar 2024 22:41:26 +0300
|
||||
Subject: arm64: dts: rockchip: Add automatic fan control to Khadas Edge 2
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts | 56 ++++++++++
|
||||
1 file changed, 56 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
|
||||
@@ -313,6 +313,62 @@ khadas_mcu: system-controller@18 {
|
||||
};
|
||||
};
|
||||
|
||||
+&package_thermal {
|
||||
+ polling-delay = <1000>;
|
||||
+
|
||||
+ trips {
|
||||
+ package_fan0: package-fan0 {
|
||||
+ temperature = <45000>;
|
||||
+ hysteresis = <5000>;
|
||||
+ type = "active";
|
||||
+ };
|
||||
+
|
||||
+ package_fan1: package-fan1 {
|
||||
+ temperature = <55000>;
|
||||
+ hysteresis = <5000>;
|
||||
+ type = "active";
|
||||
+ };
|
||||
+
|
||||
+ package_fan2: package-fan2 {
|
||||
+ temperature = <60000>;
|
||||
+ hysteresis = <5000>;
|
||||
+ type = "active";
|
||||
+ };
|
||||
+
|
||||
+ package_fan3: package-fan3 {
|
||||
+ temperature = <70000>;
|
||||
+ hysteresis = <5000>;
|
||||
+ type = "active";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cooling-maps {
|
||||
+ map0 {
|
||||
+ trip = <&package_fan0>;
|
||||
+ cooling-device = <&khadas_mcu 0 1>;
|
||||
+ contribution = <1024>;
|
||||
+ };
|
||||
+
|
||||
+ map1 {
|
||||
+ trip = <&package_fan1>;
|
||||
+ cooling-device = <&khadas_mcu 1 2>;
|
||||
+ contribution = <1024>;
|
||||
+ };
|
||||
+
|
||||
+ map2 {
|
||||
+ trip = <&package_fan2>;
|
||||
+ cooling-device = <&khadas_mcu 2 3>;
|
||||
+ contribution = <1024>;
|
||||
+ };
|
||||
+
|
||||
+ map3 {
|
||||
+ trip = <&package_fan3>;
|
||||
+ cooling-device = <&khadas_mcu 3 THERMAL_NO_LIMIT>;
|
||||
+ contribution = <1024>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&pinctrl {
|
||||
vdd_sd {
|
||||
vdd_sd_en: vdd-sd-en {
|
||||
--
|
||||
Armbian
|
||||
|
@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ricardo Pardini <ricardo@pardini.net>
|
||||
Date: Thu, 6 Jun 2024 23:00:05 +0200
|
||||
Subject: arm64: dts: rockchip: Add NanoPC T6 SPI Flash
|
||||
|
||||
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
|
||||
---
|
||||
arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 14 ++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
|
||||
index 111111111111..222222222222 100644
|
||||
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
|
||||
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
|
||||
@@ -576,6 +576,20 @@ &sdmmc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&sfc {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&fspim1_pins>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ flash@0 {
|
||||
+ compatible = "jedec,spi-nor";
|
||||
+ reg = <0x0>;
|
||||
+ spi-max-frequency = <50000000>;
|
||||
+ spi-rx-bus-width = <4>;
|
||||
+ spi-tx-bus-width = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&spi2 {
|
||||
status = "okay";
|
||||
assigned-clocks = <&cru CLK_SPI2>;
|
||||
--
|
||||
Armbian
|
||||
|
Binary file not shown.
BIN
rk3588-friendlyelec-cm3588-nas.dtb
Normal file
BIN
rk3588-friendlyelec-cm3588-nas.dtb
Normal file
Binary file not shown.
Binary file not shown.
@ -16,7 +16,7 @@ setexpr.s bootargs *${ramdisk_addr_r}
|
||||
echo "Boot args: ${bootargs}"
|
||||
|
||||
# Load dtb
|
||||
setenv fdtfile rk3328-rock64.dtb
|
||||
setenv fdtfile rk3588-friendlyelec-cm3588-nas.dtb
|
||||
load ${devtype} ${devnum}:${bootpart} ${fdt_addr_r} ${fdtfile}
|
||||
# ... and set fdt addr to it.
|
||||
fdt addr ${fdt_addr_r}
|
BIN
uboot.patches/rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.16.bin
Normal file
BIN
uboot.patches/rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.16.bin
Normal file
Binary file not shown.
BIN
vmlinuz
BIN
vmlinuz
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user