mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-06-06 02:40:18 +00:00
arm-bsp/tc0: Add kernel patches
Add patches for SCMI, MHUv2 and DRM. Also update the kernel config to enable boot to Android home screen instead of just console. Change-Id: Ic2af15441667b967ef360d8410de94e83eb73de4 Signed-off-by: Anders Dellien <anders.dellien@arm.com> Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
committed by
Jon Mason
parent
82ffc86baf
commit
785f8bf4c1
@@ -73,7 +73,18 @@ KCONFIG_MODE_sgi575 = "--alldefconfig"
|
||||
#
|
||||
# Total Compute KMACHINE
|
||||
#
|
||||
SRC_URI_append_tc0 = " file://defconfig"
|
||||
COMPATIBLE_MACHINE_tc0 = "tc0"
|
||||
KMACHINE_tc0 = "tc0"
|
||||
KCONFIG_MODE_tc0 = "--alldefconfig"
|
||||
SRC_URI_append_tc0 = " \
|
||||
file://defconfig \
|
||||
file://0001-drm-Add-component-aware-simple-encoder.patch \
|
||||
file://0002-drm-arm-komeda-add-RENDER-capability-to-the-device-n.patch \
|
||||
file://0003-mailbox-arm_mhuv2-add-device-tree-binding-documentat.patch \
|
||||
file://0004-mailbox-arm_mhuv2-add-arm-mhuv2-driver.patch \
|
||||
file://0005-mailbox-arm_mhuv2-add-doorbell-transport-protocol-op.patch \
|
||||
file://0006-mailbox-arm_mhuv2-add-multi-word-transport-protocol-.patch \
|
||||
file://0007-firmware-arm_scmi-Add-fast_switch_possible-api.patch \
|
||||
file://0008-cpufreq-arm_scmi-Set-fast_switch_possible-conditiona.patch \
|
||||
"
|
||||
|
||||
|
||||
+364
@@ -0,0 +1,364 @@
|
||||
From 7863ac1515009547bae3a66e0808e72b3bdcf8c8 Mon Sep 17 00:00:00 2001
|
||||
From: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Date: Tue, 16 Jun 2020 12:39:06 +0000
|
||||
Subject: [PATCH 1/9] drm: Add component-aware simple encoder
|
||||
|
||||
This is a simple DRM encoder that gets its connector timings information
|
||||
from a OF subnode in the device tree and exposes that as a "discovered"
|
||||
panel. It can be used together with component-based DRM drivers in an
|
||||
emulated environment where no real encoder or connector hardware exists
|
||||
and the display output is configured outside the kernel.
|
||||
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.linaro.org/landing-teams/working/arm/kernel-release.git/commit/?h=latest-armlt&id=15283f7be4b1e586702551e85b4caf06531ac2fc]
|
||||
---
|
||||
drivers/gpu/drm/Kconfig | 11 +
|
||||
drivers/gpu/drm/Makefile | 2 +
|
||||
drivers/gpu/drm/drm_virtual_encoder.c | 299 ++++++++++++++++++++++++++
|
||||
3 files changed, 312 insertions(+)
|
||||
create mode 100644 drivers/gpu/drm/drm_virtual_encoder.c
|
||||
|
||||
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
|
||||
index e67c194c2aca..c95279cd9341 100644
|
||||
--- a/drivers/gpu/drm/Kconfig
|
||||
+++ b/drivers/gpu/drm/Kconfig
|
||||
@@ -265,6 +265,17 @@ config DRM_VKMS
|
||||
|
||||
If M is selected the module will be called vkms.
|
||||
|
||||
+config DRM_VIRT_ENCODER
|
||||
+ tristate "Virtual OF-based encoder"
|
||||
+ depends on DRM && OF
|
||||
+ select VIDEOMODE_HELPERS
|
||||
+ help
|
||||
+ Choose this option to get a virtual encoder and its associated
|
||||
+ connector that will use the device tree to read the display
|
||||
+ timings information. If M is selected the module will be called
|
||||
+ drm_vencoder.
|
||||
+
|
||||
+
|
||||
config DRM_ATI_PCIGART
|
||||
bool
|
||||
|
||||
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
|
||||
index 82ff826b33cc..d2ab6fc64932 100644
|
||||
--- a/drivers/gpu/drm/Makefile
|
||||
+++ b/drivers/gpu/drm/Makefile
|
||||
@@ -53,6 +53,8 @@ drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
|
||||
|
||||
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
|
||||
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
|
||||
+drm_vencoder-y := drm_virtual_encoder.o
|
||||
+obj-$(CONFIG_DRM_VIRT_ENCODER) += drm_vencoder.o
|
||||
|
||||
obj-$(CONFIG_DRM) += drm.o
|
||||
obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o
|
||||
diff --git a/drivers/gpu/drm/drm_virtual_encoder.c b/drivers/gpu/drm/drm_virtual_encoder.c
|
||||
new file mode 100644
|
||||
index 000000000000..4fd2098df286
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpu/drm/drm_virtual_encoder.c
|
||||
@@ -0,0 +1,299 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2016 ARM Limited
|
||||
+ * Author: Liviu Dudau <Liviu.Dudau@arm.com>
|
||||
+ *
|
||||
+ * Dummy encoder and connector that use the OF to "discover" the attached
|
||||
+ * display timings. Can be used in situations where the encoder and connector's
|
||||
+ * functionality are emulated and no setup steps are needed, or to describe
|
||||
+ * attached panels for which no driver exists but can be used without
|
||||
+ * additional hardware setup.
|
||||
+ *
|
||||
+ * The encoder also uses the component framework so that it can be a quick
|
||||
+ * replacement for existing drivers when testing in an emulated environment.
|
||||
+ *
|
||||
+ * This file is subject to the terms and conditions of the GNU General Public
|
||||
+ * License. See the file COPYING in the main directory of this archive
|
||||
+ * for more details.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <drm/drm_crtc.h>
|
||||
+#include <drm/drm_atomic_helper.h>
|
||||
+#include <drm/drm_crtc_helper.h>
|
||||
+#include <drm/drm_probe_helper.h>
|
||||
+#include <drm/drm_print.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <drm/drm_of.h>
|
||||
+#include <linux/component.h>
|
||||
+#include <video/display_timing.h>
|
||||
+#include <video/of_display_timing.h>
|
||||
+#include <video/videomode.h>
|
||||
+
|
||||
+struct drm_virt_priv {
|
||||
+ struct drm_connector connector;
|
||||
+ struct drm_encoder encoder;
|
||||
+ struct display_timings *timings;
|
||||
+};
|
||||
+
|
||||
+#define connector_to_drm_virt_priv(x) \
|
||||
+ container_of(x, struct drm_virt_priv, connector)
|
||||
+
|
||||
+#define encoder_to_drm_virt_priv(x) \
|
||||
+ container_of(x, struct drm_virt_priv, encoder)
|
||||
+
|
||||
+static void drm_virtcon_destroy(struct drm_connector *connector)
|
||||
+{
|
||||
+ struct drm_virt_priv *conn = connector_to_drm_virt_priv(connector);
|
||||
+
|
||||
+ drm_connector_cleanup(connector);
|
||||
+ display_timings_release(conn->timings);
|
||||
+}
|
||||
+
|
||||
+static enum drm_connector_status
|
||||
+drm_virtcon_detect(struct drm_connector *connector, bool force)
|
||||
+{
|
||||
+ return connector_status_connected;
|
||||
+}
|
||||
+
|
||||
+static const struct drm_connector_funcs drm_virtcon_funcs = {
|
||||
+ .reset = drm_atomic_helper_connector_reset,
|
||||
+ .detect = drm_virtcon_detect,
|
||||
+ .fill_modes = drm_helper_probe_single_connector_modes,
|
||||
+ .destroy = drm_virtcon_destroy,
|
||||
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
+};
|
||||
+
|
||||
+static int drm_virtcon_get_modes(struct drm_connector *connector)
|
||||
+{
|
||||
+ struct drm_virt_priv *conn = connector_to_drm_virt_priv(connector);
|
||||
+ struct display_timings *timings = conn->timings;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < timings->num_timings; i++) {
|
||||
+ struct drm_display_mode *mode = drm_mode_create(connector->dev);
|
||||
+ struct videomode vm;
|
||||
+
|
||||
+ if (videomode_from_timings(timings, &vm, i))
|
||||
+ break;
|
||||
+
|
||||
+ drm_display_mode_from_videomode(&vm, mode);
|
||||
+ mode->type = DRM_MODE_TYPE_DRIVER;
|
||||
+ if (timings->native_mode == i)
|
||||
+ mode->type = DRM_MODE_TYPE_PREFERRED;
|
||||
+
|
||||
+ drm_mode_set_name(mode);
|
||||
+ drm_mode_probed_add(connector, mode);
|
||||
+ }
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
+static int drm_virtcon_mode_valid(struct drm_connector *connector,
|
||||
+ struct drm_display_mode *mode)
|
||||
+{
|
||||
+ return MODE_OK;
|
||||
+}
|
||||
+
|
||||
+struct drm_encoder *drm_virtcon_best_encoder(struct drm_connector *connector)
|
||||
+{
|
||||
+ struct drm_virt_priv *priv = connector_to_drm_virt_priv(connector);
|
||||
+
|
||||
+ return &priv->encoder;
|
||||
+}
|
||||
+
|
||||
+struct drm_encoder *
|
||||
+drm_virtcon_atomic_best_encoder(struct drm_connector *connector,
|
||||
+ struct drm_connector_state *connector_state)
|
||||
+{
|
||||
+ struct drm_virt_priv *priv = connector_to_drm_virt_priv(connector);
|
||||
+
|
||||
+ return &priv->encoder;
|
||||
+}
|
||||
+
|
||||
+static const struct drm_connector_helper_funcs drm_virtcon_helper_funcs = {
|
||||
+ .get_modes = drm_virtcon_get_modes,
|
||||
+ .mode_valid = drm_virtcon_mode_valid,
|
||||
+ .best_encoder = drm_virtcon_best_encoder,
|
||||
+ .atomic_best_encoder = drm_virtcon_atomic_best_encoder,
|
||||
+};
|
||||
+
|
||||
+static void drm_vencoder_destroy(struct drm_encoder *encoder)
|
||||
+{
|
||||
+ drm_encoder_cleanup(encoder);
|
||||
+}
|
||||
+
|
||||
+static const struct drm_encoder_funcs drm_vencoder_funcs = {
|
||||
+ .destroy = drm_vencoder_destroy,
|
||||
+};
|
||||
+
|
||||
+static void drm_vencoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
+{
|
||||
+ /* nothing needed */
|
||||
+}
|
||||
+
|
||||
+static bool drm_vencoder_mode_fixup(struct drm_encoder *encoder,
|
||||
+ const struct drm_display_mode *mode,
|
||||
+ struct drm_display_mode *adjusted_mode)
|
||||
+{
|
||||
+ /* nothing needed */
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static void drm_vencoder_prepare(struct drm_encoder *encoder)
|
||||
+{
|
||||
+ drm_vencoder_dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||
+}
|
||||
+
|
||||
+static void drm_vencoder_commit(struct drm_encoder *encoder)
|
||||
+{
|
||||
+ drm_vencoder_dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
+}
|
||||
+
|
||||
+static void drm_vencoder_mode_set(struct drm_encoder *encoder,
|
||||
+ struct drm_display_mode *mode,
|
||||
+ struct drm_display_mode *adjusted_mode)
|
||||
+{
|
||||
+ /* nothing needed */
|
||||
+}
|
||||
+
|
||||
+static const struct drm_encoder_helper_funcs drm_vencoder_helper_funcs = {
|
||||
+ .dpms = drm_vencoder_dpms,
|
||||
+ .mode_fixup = drm_vencoder_mode_fixup,
|
||||
+ .prepare = drm_vencoder_prepare,
|
||||
+ .commit = drm_vencoder_commit,
|
||||
+ .mode_set = drm_vencoder_mode_set,
|
||||
+};
|
||||
+
|
||||
+static int drm_vencoder_bind(struct device *dev, struct device *master,
|
||||
+ void *data)
|
||||
+{
|
||||
+ struct drm_encoder *encoder;
|
||||
+ struct drm_virt_priv *con;
|
||||
+ struct drm_connector *connector;
|
||||
+ struct drm_device *drm = data;
|
||||
+ u32 crtcs = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ con = devm_kzalloc(dev, sizeof(*con), GFP_KERNEL);
|
||||
+ if (!con)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ dev_set_drvdata(dev, con);
|
||||
+ connector = &con->connector;
|
||||
+ encoder = &con->encoder;
|
||||
+
|
||||
+ if (dev->of_node) {
|
||||
+ struct drm_bridge *bridge;
|
||||
+ crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
|
||||
+ bridge = of_drm_find_bridge(dev->of_node);
|
||||
+ if (bridge) {
|
||||
+ ret = drm_bridge_attach(encoder, bridge, NULL);
|
||||
+ if (ret) {
|
||||
+ DRM_ERROR("Failed to initialize bridge\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ con->timings = of_get_display_timings(dev->of_node);
|
||||
+ if (!con->timings) {
|
||||
+ dev_err(dev, "failed to get display panel timings\n");
|
||||
+ return ENXIO;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* If no CRTCs were found, fall back to the old encoder's behaviour */
|
||||
+ if (crtcs == 0) {
|
||||
+ dev_warn(dev, "Falling back to first CRTC\n");
|
||||
+ crtcs = 1 << 0;
|
||||
+ }
|
||||
+
|
||||
+ encoder->possible_crtcs = crtcs ? crtcs : 1;
|
||||
+ encoder->possible_clones = 0;
|
||||
+
|
||||
+ ret = drm_encoder_init(drm, encoder, &drm_vencoder_funcs,
|
||||
+ DRM_MODE_ENCODER_VIRTUAL, NULL);
|
||||
+ if (ret)
|
||||
+ goto encoder_init_err;
|
||||
+
|
||||
+ drm_encoder_helper_add(encoder, &drm_vencoder_helper_funcs);
|
||||
+
|
||||
+ /* bogus values, pretend we're a 24" screen for DPI calculations */
|
||||
+ connector->display_info.width_mm = 519;
|
||||
+ connector->display_info.height_mm = 324;
|
||||
+ connector->interlace_allowed = false;
|
||||
+ connector->doublescan_allowed = false;
|
||||
+ connector->polled = 0;
|
||||
+
|
||||
+ ret = drm_connector_init(drm, connector, &drm_virtcon_funcs,
|
||||
+ DRM_MODE_CONNECTOR_VIRTUAL);
|
||||
+ if (ret)
|
||||
+ goto connector_init_err;
|
||||
+
|
||||
+ drm_connector_helper_add(connector, &drm_virtcon_helper_funcs);
|
||||
+
|
||||
+ drm_connector_register(connector);
|
||||
+
|
||||
+ ret = drm_connector_attach_encoder(connector, encoder);
|
||||
+ if (ret)
|
||||
+ goto attach_err;
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+attach_err:
|
||||
+ drm_connector_unregister(connector);
|
||||
+ drm_connector_cleanup(connector);
|
||||
+connector_init_err:
|
||||
+ drm_encoder_cleanup(encoder);
|
||||
+encoder_init_err:
|
||||
+ display_timings_release(con->timings);
|
||||
+
|
||||
+ return ret;
|
||||
+};
|
||||
+
|
||||
+static void drm_vencoder_unbind(struct device *dev, struct device *master,
|
||||
+ void *data)
|
||||
+{
|
||||
+ struct drm_virt_priv *con = dev_get_drvdata(dev);
|
||||
+
|
||||
+ drm_connector_unregister(&con->connector);
|
||||
+ drm_connector_cleanup(&con->connector);
|
||||
+ drm_encoder_cleanup(&con->encoder);
|
||||
+ display_timings_release(con->timings);
|
||||
+}
|
||||
+
|
||||
+static const struct component_ops drm_vencoder_ops = {
|
||||
+ .bind = drm_vencoder_bind,
|
||||
+ .unbind = drm_vencoder_unbind,
|
||||
+};
|
||||
+
|
||||
+static int drm_vencoder_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ return component_add(&pdev->dev, &drm_vencoder_ops);
|
||||
+}
|
||||
+
|
||||
+static int drm_vencoder_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ component_del(&pdev->dev, &drm_vencoder_ops);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id drm_vencoder_of_match[] = {
|
||||
+ { .compatible = "drm,virtual-encoder", },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, drm_vencoder_of_match);
|
||||
+
|
||||
+static struct platform_driver drm_vencoder_driver = {
|
||||
+ .probe = drm_vencoder_probe,
|
||||
+ .remove = drm_vencoder_remove,
|
||||
+ .driver = {
|
||||
+ .name = "drm_vencoder",
|
||||
+ .of_match_table = drm_vencoder_of_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(drm_vencoder_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Liviu Dudau");
|
||||
+MODULE_DESCRIPTION("Virtual DRM Encoder");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
From 190c6354a0d80c31214550553cfbee25571e1942 Mon Sep 17 00:00:00 2001
|
||||
From: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Date: Wed, 17 Jun 2020 10:49:26 +0000
|
||||
Subject: [PATCH 2/9] drm: arm: komeda: add RENDER capability to the device
|
||||
node
|
||||
|
||||
this is required to make this driver work with android framework
|
||||
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
|
||||
Upstream-Status: Inappropriate [Product specific configuration]
|
||||
---
|
||||
drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
|
||||
index ae274902ff92..238bd8466206 100644
|
||||
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
|
||||
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
|
||||
@@ -56,7 +56,7 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data)
|
||||
}
|
||||
|
||||
static struct drm_driver komeda_kms_driver = {
|
||||
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
|
||||
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_RENDER,
|
||||
.lastclose = drm_fb_helper_lastclose,
|
||||
.gem_free_object_unlocked = drm_gem_cma_free_object,
|
||||
.gem_vm_ops = &drm_gem_cma_vm_ops,
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
From bca81c4c54765565651634b6de5edb6a191577a3 Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Thu, 27 Jun 2019 11:16:22 +0100
|
||||
Subject: [PATCH 3/9] mailbox: arm_mhuv2: add device tree binding documentation
|
||||
|
||||
This patch adds device tree binding for Message Handling Unit
|
||||
controller version 2 from Arm.
|
||||
|
||||
Change-Id: I8c46dd7cd1a48450020c33721ea7cce9f8b8e64f
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Cc: robh+dt@kernel.org
|
||||
Cc: mark.rutland@arm.com
|
||||
Cc: devicetree@vger.kernel.org
|
||||
Cc: jassisinghbrar@gmail.com
|
||||
|
||||
Upstream-Status: Denied [https://lkml.org/lkml/2019/7/17/615]
|
||||
---
|
||||
.../devicetree/bindings/mailbox/arm,mhuv2.txt | 101 ++++++++++++++++++
|
||||
1 file changed, 101 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/mailbox/arm,mhuv2.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/mailbox/arm,mhuv2.txt b/Documentation/devicetree/bindings/mailbox/arm,mhuv2.txt
|
||||
new file mode 100644
|
||||
index 000000000000..5b8a2ab21ae0
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/mailbox/arm,mhuv2.txt
|
||||
@@ -0,0 +1,101 @@
|
||||
+Arm MHUv2 Mailbox Driver
|
||||
+========================
|
||||
+
|
||||
+The Arm Message-Handling-Unit (MHU) Version 2 is a mailbox controller that has
|
||||
+between 1 and 124 channel windows to provide unidirectional communication with
|
||||
+remote processor(s).
|
||||
+
|
||||
+Given the unidirectional nature of the device, an MHUv2 mailbox may only be
|
||||
+written to or read from. If a pair of MHU devices is implemented between two
|
||||
+processing elements to provide bidirectional communication, these must be
|
||||
+specified as two separate mailboxes.
|
||||
+
|
||||
+If the interrupts property is present in device tree node, then its treated
|
||||
+as a receiver frame, otherwise a sender frame.
|
||||
+
|
||||
+An MHU device must be specified with a transport protocol. The transport
|
||||
+protocol of an MHU device determines the method of data transmission as well as
|
||||
+the number of provided mailboxes.
|
||||
+Following are the possible transport protocol types:
|
||||
+- Single-word: An MHU device implements as many mailboxes as it
|
||||
+ provides channel windows. Data is transmitted through
|
||||
+ the MHU registers.
|
||||
+- Multi-word: An MHU device implements a single mailbox. All channel windows
|
||||
+ will be used during transmission. Data is transmitted through
|
||||
+ the MHU registers.
|
||||
+- Doorbell: An MHU device implements as many mailboxes as there are flag
|
||||
+ bits available in its channel windows. Optionally, data may
|
||||
+ be transmitted through a shared memory region, wherein the MHU
|
||||
+ is used strictly as an interrupt generation mechanism.
|
||||
+
|
||||
+Mailbox Device Node:
|
||||
+====================
|
||||
+
|
||||
+Required properties:
|
||||
+--------------------
|
||||
+- compatible: Shall be "arm,mhuv2" & "arm,primecell"
|
||||
+- reg: Contains the mailbox register address range (base
|
||||
+ address and length)
|
||||
+- #mbox-cells Shall be 1 - the index of the channel needed.
|
||||
+- mhu-protocol Transport protocol of the device. Shall be one of the
|
||||
+ following: "single-word", "multi-word", "doorbell"
|
||||
+
|
||||
+Required properties (receiver frame):
|
||||
+-------------------------------------
|
||||
+- interrupts: Contains the interrupt information for the receiver frame
|
||||
+
|
||||
+Example:
|
||||
+--------
|
||||
+
|
||||
+ mbox_mw_tx: mhu@10000000 {
|
||||
+ compatible = "arm,mhuv2","arm,primecell";
|
||||
+ reg = <0x10000000 0x1000>;
|
||||
+ clocks = <&refclk100mhz>;
|
||||
+ clock-names = "apb_pclk";
|
||||
+ #mbox-cells = <1>;
|
||||
+ mhu-protocol = "multi-word";
|
||||
+ };
|
||||
+
|
||||
+ mbox_sw_tx: mhu@10000000 {
|
||||
+ compatible = "arm,mhuv2","arm,primecell";
|
||||
+ reg = <0x11000000 0x1000>;
|
||||
+ clocks = <&refclk100mhz>;
|
||||
+ clock-names = "apb_pclk";
|
||||
+ #mbox-cells = <1>;
|
||||
+ mhu-protocol = "single-word";
|
||||
+ };
|
||||
+
|
||||
+ mbox_db_rx: mhu@10000000 {
|
||||
+ compatible = "arm,mhuv2","arm,primecell";
|
||||
+ reg = <0x12000000 0x1000>;
|
||||
+ clocks = <&refclk100mhz>;
|
||||
+ clock-names = "apb_pclk";
|
||||
+ #mbox-cells = <1>;
|
||||
+ interrupts = <0 45 4>;
|
||||
+ interrupt-names = "mhu_rx";
|
||||
+ mhu-protocol = "doorbell";
|
||||
+ };
|
||||
+
|
||||
+ mhu_client: scb@2e000000 {
|
||||
+ compatible = "fujitsu,mb86s70-scb-1.0";
|
||||
+ reg = <0 0x2e000000 0x4000>;
|
||||
+ mboxes =
|
||||
+ // For multi-word frames, client may only instantiate a single
|
||||
+ // mailbox for a mailbox controller
|
||||
+ <&mbox_mw_tx 0>,
|
||||
+
|
||||
+ // For single-word frames, client may instantiate as many
|
||||
+ // mailboxes as there are channel windows in the MHU
|
||||
+ <&mbox_sw_tx 0>,
|
||||
+ <&mbox_sw_tx 1>,
|
||||
+ <&mbox_sw_tx 2>,
|
||||
+ <&mbox_sw_tx 3>,
|
||||
+
|
||||
+ // For doorbell frames, client may instantiate as many mailboxes
|
||||
+ // as there are bits available in the combined number of channel
|
||||
+ // windows ((channel windows * 32) mailboxes)
|
||||
+ <mbox_db_rx 0>,
|
||||
+ <mbox_db_rx 1>,
|
||||
+ ...
|
||||
+ <mbox_db_rx 17>;
|
||||
+ };
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+822
@@ -0,0 +1,822 @@
|
||||
From 364539028799290814a35aa10d32d850486f0b4a Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Thu, 27 Jun 2019 11:17:14 +0100
|
||||
Subject: [PATCH 4/9] mailbox: arm_mhuv2: add arm mhuv2 driver
|
||||
|
||||
This commit adds a driver for the ARM MHUv2 (Message Handling Unit).
|
||||
The driver registers itself as a mailbox controller within the common
|
||||
mailbox framework.
|
||||
|
||||
This commit implements the single-word transport protocol;
|
||||
In single-word mode, the mailbox controller will provide a mailbox for each
|
||||
channel window available in the MHU device.
|
||||
Transmitting and receiving data through the mailbox framework in
|
||||
single-word mode is done through a struct arm_mbox_msg.
|
||||
|
||||
Change-Id: I718253ceb902a2d53f7199a746063a36129b0fa6
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Cc: jassisinghbrar@gmail.com
|
||||
Cc: devicetree@vger.kernel.org
|
||||
|
||||
Upstream-Status: Denied [https://lkml.org/lkml/2019/7/17/615]
|
||||
---
|
||||
drivers/mailbox/Kconfig | 7 +
|
||||
drivers/mailbox/Makefile | 2 +
|
||||
drivers/mailbox/arm_mhu_v2.c | 707 +++++++++++++++++++++++
|
||||
include/linux/mailbox/arm-mbox-message.h | 37 ++
|
||||
4 files changed, 753 insertions(+)
|
||||
create mode 100644 drivers/mailbox/arm_mhu_v2.c
|
||||
create mode 100644 include/linux/mailbox/arm-mbox-message.h
|
||||
|
||||
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
|
||||
index ab4eb750bbdd..0a0dce01098c 100644
|
||||
--- a/drivers/mailbox/Kconfig
|
||||
+++ b/drivers/mailbox/Kconfig
|
||||
@@ -22,6 +22,13 @@ config IMX_MBOX
|
||||
help
|
||||
Mailbox implementation for i.MX Messaging Unit (MU).
|
||||
|
||||
+config ARM_MHU_V2
|
||||
+ tristate "ARM MHUv2 Mailbox"
|
||||
+ depends on ARM_AMBA
|
||||
+ help
|
||||
+ Say Y here if you want to build the ARM MHUv2 controller driver,
|
||||
+ which provides unidirectional mailboxes between processing elements.
|
||||
+
|
||||
config PLATFORM_MHU
|
||||
tristate "Platform MHU Mailbox"
|
||||
depends on OF
|
||||
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
|
||||
index c22fad6f696b..78377f459421 100644
|
||||
--- a/drivers/mailbox/Makefile
|
||||
+++ b/drivers/mailbox/Makefile
|
||||
@@ -11,6 +11,8 @@ obj-$(CONFIG_IMX_MBOX) += imx-mailbox.o
|
||||
|
||||
obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX) += armada-37xx-rwtm-mailbox.o
|
||||
|
||||
+obj-$(CONFIG_ARM_MHU_V2) += arm_mhu_v2.o
|
||||
+
|
||||
obj-$(CONFIG_PLATFORM_MHU) += platform_mhu.o
|
||||
|
||||
obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
|
||||
diff --git a/drivers/mailbox/arm_mhu_v2.c b/drivers/mailbox/arm_mhu_v2.c
|
||||
new file mode 100644
|
||||
index 000000000000..d809076eb47b
|
||||
--- /dev/null
|
||||
+++ b/drivers/mailbox/arm_mhu_v2.c
|
||||
@@ -0,0 +1,707 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Arm Message Handling Unit Version 2 (MHUv2) driver
|
||||
+ *
|
||||
+ * An MHU device may function in one of three transport protocol modes
|
||||
+ * (single-word, multi-word and doorbell).
|
||||
+ * This transport protocol should be specified in the device tree entry for the
|
||||
+ * device. The transport protocol determines how the underlying hardware
|
||||
+ * resources of the device are utilized when transmitting data.
|
||||
+ *
|
||||
+ * The arm MHUv2 driver registers as a mailbox controller with the common
|
||||
+ * mailbox framework. Each mailbox channel represents a separate virtual
|
||||
+ * communication channel through the MHU device.
|
||||
+ * The number of registered mailbox channels is dependent on both the
|
||||
+ * underlying hardware - mainly the number of channel windows within each MHU
|
||||
+ * frame, as well as the selected transport protocol.
|
||||
+ *
|
||||
+ * Copyright (C) 2019 Arm Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/amba/bus.h>
|
||||
+#include <linux/mailbox_controller.h>
|
||||
+#include <linux/mailbox/arm-mbox-message.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+
|
||||
+/* Maximum number of channel windows */
|
||||
+#define MHUV2_CHANNEL_MAX 124
|
||||
+/* Number of combined interrupt status registers */
|
||||
+#define MHUV2_CMB_INT_ST_REG_CNT 4
|
||||
+#define MHUV2_CH_UNKNOWN -1
|
||||
+
|
||||
+/* Channel window status register type */
|
||||
+typedef u32 mhuv2_stat_reg_t;
|
||||
+#define MHUV2_STAT_BYTES sizeof(mhuv2_stat_reg_t)
|
||||
+#define MHUV2_STAT_BITS (MHUV2_STAT_BYTES * __CHAR_BIT__)
|
||||
+
|
||||
+#define LSB_MASK(n) ((1 << (n)) - 1)
|
||||
+
|
||||
+#ifndef PAD
|
||||
+#define _PADLINE(line) pad##line
|
||||
+#define _XSTR(line) _PADLINE(line)
|
||||
+#define PAD _XSTR(__LINE__)
|
||||
+#endif
|
||||
+
|
||||
+/* ====== Arm MHUv2 register defines ====== */
|
||||
+
|
||||
+/* Register Message Handling Unit Configuration fields */
|
||||
+struct MHU_CFG_t {
|
||||
+ u32 NUM_CH : 7;
|
||||
+ u32 PAD : 25;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Register Implementer Identification fields */
|
||||
+struct IIDR_t {
|
||||
+ u32 IMPLEMENTER : 12;
|
||||
+ u32 REVISION : 4;
|
||||
+ u32 VARIANT : 4;
|
||||
+ u32 PRODUCT_ID : 12;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Register Architecture Identification Register fields */
|
||||
+struct AIDR_t {
|
||||
+ u32 ARCH_MINOR_REV : 4;
|
||||
+ u32 ARCH_MAJOR_REV : 4;
|
||||
+ u32 PAD : 24;
|
||||
+} __packed;
|
||||
+
|
||||
+/* register Interrupt Status fields */
|
||||
+struct INT_ST_t {
|
||||
+ u32 NR2R : 1;
|
||||
+ u32 R2NR : 1;
|
||||
+ u32 PAD : 30;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Register Interrupt Clear fields */
|
||||
+struct INT_CLR_t {
|
||||
+ u32 NR2R : 1;
|
||||
+ u32 R2NR : 1;
|
||||
+ u32 PAD : 30;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Register Interrupt Enable fields */
|
||||
+struct INT_EN_t {
|
||||
+ u32 R2NR : 1;
|
||||
+ u32 NR2R : 1;
|
||||
+ u32 CHCOMB : 1;
|
||||
+ u32 PAD : 29;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Sender Channel Window fields */
|
||||
+struct mhu2_send_channel_reg {
|
||||
+ mhuv2_stat_reg_t STAT;
|
||||
+ u8 PAD[0xC - 0x4];
|
||||
+ mhuv2_stat_reg_t STAT_SET;
|
||||
+ u8 PAD[0x20 - 0x10];
|
||||
+} __packed;
|
||||
+
|
||||
+/* Sender frame register fields */
|
||||
+struct mhu2_send_frame_reg {
|
||||
+ struct mhu2_send_channel_reg channel[MHUV2_CHANNEL_MAX];
|
||||
+ struct MHU_CFG_t MHU_CFG;
|
||||
+ u32 RESP_CFG;
|
||||
+ u32 ACCESS_REQUEST;
|
||||
+ u32 ACCESS_READY;
|
||||
+ struct INT_ST_t INT_ST;
|
||||
+ struct INT_CLR_t INT_CLR;
|
||||
+ struct INT_EN_t INT_EN;
|
||||
+ u32 RESERVED0;
|
||||
+ u32 CHCOMB_INT_ST[MHUV2_CMB_INT_ST_REG_CNT];
|
||||
+ u8 PAD[0xFC8 - 0xFB0];
|
||||
+ struct IIDR_t IIDR;
|
||||
+ struct AIDR_t AIDR;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Receiver Channel Window fields */
|
||||
+struct mhu2_recv_channel_reg {
|
||||
+ mhuv2_stat_reg_t STAT;
|
||||
+ mhuv2_stat_reg_t STAT_PEND;
|
||||
+ mhuv2_stat_reg_t STAT_CLEAR;
|
||||
+ u8 RESERVED0[0x10 - 0x0C];
|
||||
+ mhuv2_stat_reg_t MASK;
|
||||
+ mhuv2_stat_reg_t MASK_SET;
|
||||
+ mhuv2_stat_reg_t MASK_CLEAR;
|
||||
+ u8 PAD[0x20 - 0x1C];
|
||||
+} __packed;
|
||||
+
|
||||
+/* Receiver frame register fields */
|
||||
+struct mhu2_recv_frame_reg {
|
||||
+ struct mhu2_recv_channel_reg channel[MHUV2_CHANNEL_MAX];
|
||||
+ struct MHU_CFG_t MHU_CFG;
|
||||
+ u8 RESERVED0[0xF90 - 0xF84];
|
||||
+ struct INT_ST_t INT_ST;
|
||||
+ struct INT_CLR_t INT_CLR;
|
||||
+ struct INT_EN_t INT_EN;
|
||||
+ u32 PAD;
|
||||
+ mhuv2_stat_reg_t CHCOMB_INT_ST[MHUV2_CMB_INT_ST_REG_CNT];
|
||||
+ u8 RESERVED2[0xFC8 - 0xFB0];
|
||||
+ struct IIDR_t IIDR;
|
||||
+ struct AIDR_t AIDR;
|
||||
+} __packed;
|
||||
+
|
||||
+/* ====== Arm MHUv2 device tree property identifiers ====== */
|
||||
+
|
||||
+static const char *const mhuv2_protocol_dt_identifiers[] = { "single-word",
|
||||
+ "multi-word",
|
||||
+ "doorbell" };
|
||||
+
|
||||
+static const char *const mhuv2_frame_dt_identifiers[] = { "receiver",
|
||||
+ "sender" };
|
||||
+
|
||||
+/* ====== Arm MHUv2 data structures ====== */
|
||||
+
|
||||
+enum mhuv2_transport_protocol { SINGLE_WORD, MULTI_WORD, DOORBELL };
|
||||
+
|
||||
+enum mhuv2_frame { RECEIVER_FRAME, SENDER_FRAME };
|
||||
+
|
||||
+/**
|
||||
+ * Arm MHUv2 operations
|
||||
+ *
|
||||
+ * Each transport protocol must provide an implementation of the operations
|
||||
+ * presented in this structure.
|
||||
+ * Most operations present a struct mbox_chan* as argument. This channel will
|
||||
+ * correspond to one of the virtual channels within the MHU device. What
|
||||
+ * constitutes a channel within the MHU device is dependent on the transport
|
||||
+ * protocol.
|
||||
+ */
|
||||
+struct arm_mhuv2;
|
||||
+struct mhuv2_ops {
|
||||
+ int (*read_data)(struct arm_mhuv2 *mhuv2, struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg);
|
||||
+ int (*clear_data)(struct arm_mhuv2 *mhuv2, struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg);
|
||||
+ int (*send_data)(struct arm_mhuv2 *mhuv2, struct mbox_chan *chan,
|
||||
+ const struct arm_mbox_msg *msg);
|
||||
+ int (*setup)(struct arm_mhuv2 *mhuv2);
|
||||
+ int (*last_tx_done)(struct arm_mhuv2 *mhuv2, struct mbox_chan *chan);
|
||||
+ struct mbox_chan *(*get_active_mbox_chan)(struct arm_mhuv2 *mhuv2);
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * Arm MHUv2 mailbox channel information
|
||||
+ *
|
||||
+ * A channel contains a notion of its index within the array of mailbox channels
|
||||
+ * which a mailbox controller allocates.
|
||||
+ */
|
||||
+struct arm_mhuv2_mbox_chan_priv {
|
||||
+ u32 ch_idx;
|
||||
+};
|
||||
+
|
||||
+#define mhuv2_chan_idx(_chanptr) \
|
||||
+ (((struct arm_mhuv2_mbox_chan_priv *)(_chanptr)->con_priv)->ch_idx)
|
||||
+
|
||||
+/**
|
||||
+ * Arm MHUv2 mailbox controller data
|
||||
+ *
|
||||
+ * @reg: Base address of the register mapping region
|
||||
+ * @protocol: Transport protocol, derived from device tree
|
||||
+ * @frame: Frame type, derived from device tree
|
||||
+ * @irq: Interrupt, only valid for receiver frames
|
||||
+ * @mbox: Mailbox controller belonging to the MHU frame
|
||||
+ * @ops: Pointer to transport-protocol specific operations
|
||||
+ * @dev: Device to which it is attached
|
||||
+ */
|
||||
+struct arm_mhuv2 {
|
||||
+ union {
|
||||
+ struct mhu2_send_frame_reg __iomem *send;
|
||||
+ struct mhu2_recv_frame_reg __iomem *recv;
|
||||
+ } reg;
|
||||
+ enum mhuv2_frame frame;
|
||||
+ unsigned int irq;
|
||||
+ struct mbox_controller mbox;
|
||||
+ struct mhuv2_ops *ops;
|
||||
+ struct device *dev;
|
||||
+};
|
||||
+
|
||||
+#define mhu2_from_mbox_ctrl(_mbox) container_of(_mbox, struct arm_mhuv2, mbox)
|
||||
+#define mhu2_from_mbox_chan(_chan) mhu2_from_mbox_ctrl(_chan->mbox)
|
||||
+
|
||||
+/* Macro for reading a bitfield within a physically mapped packed struct */
|
||||
+#define readl_relaxed_bitfield(_regptr, _field) \
|
||||
+ ({ \
|
||||
+ mhuv2_stat_reg_t _regval; \
|
||||
+ BUILD_BUG_ON(sizeof(*(_regptr)) > sizeof(typeof(_regval))); \
|
||||
+ _regval = readl_relaxed((_regptr)); \
|
||||
+ (*(typeof((_regptr)))(&_regval))._field; \
|
||||
+ })
|
||||
+
|
||||
+/* Macro for writing a bitfield within a physically mapped packed struct */
|
||||
+#define writel_relaxed_bitfield(_value, _regptr, _field) \
|
||||
+ ({ \
|
||||
+ mhuv2_stat_reg_t _regval; \
|
||||
+ BUILD_BUG_ON(sizeof(*_regptr) > sizeof(typeof(_regval))); \
|
||||
+ _regval = readl_relaxed(_regptr); \
|
||||
+ (*(typeof(_regptr))(&_regval))._field = _value; \
|
||||
+ writel_relaxed(_regval, _regptr); \
|
||||
+ })
|
||||
+
|
||||
+static inline int __find_set_bit(uint32_t val)
|
||||
+{
|
||||
+ const uint32_t trailing_zeros = __builtin_ctz(val);
|
||||
+ return trailing_zeros == 32 ? -1 : trailing_zeros;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Get index of a set bit within the combined interrupt status registers
|
||||
+ *
|
||||
+ * The function will calculate the index being the offset from the LSB of the
|
||||
+ * first combined interrupt status register.
|
||||
+ *
|
||||
+ */
|
||||
+static inline int mhuv2_combint_idx(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ int ch_idx = 0;
|
||||
+ int set_bit_index, reg_idx;
|
||||
+
|
||||
+ for (reg_idx = 0; reg_idx < MHUV2_CMB_INT_ST_REG_CNT; reg_idx++) {
|
||||
+ mhuv2_stat_reg_t stat_reg;
|
||||
+
|
||||
+ stat_reg =
|
||||
+ readl_relaxed(&mhuv2->reg.recv->CHCOMB_INT_ST[reg_idx]);
|
||||
+ set_bit_index = __find_set_bit(stat_reg);
|
||||
+ if (set_bit_index == -1) {
|
||||
+ ch_idx += MHUV2_STAT_BITS;
|
||||
+ } else {
|
||||
+ ch_idx += set_bit_index;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return (ch_idx >= (MHUV2_CMB_INT_ST_REG_CNT * MHUV2_STAT_BITS) ?
|
||||
+ MHUV2_CH_UNKNOWN :
|
||||
+ ch_idx);
|
||||
+}
|
||||
+
|
||||
+/* ================ Single word transport protocol operations =============== */
|
||||
+static inline int mhuv20_get_non_zero_ch_idx(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ /* Locate a channel window with a non-zero STAT register */
|
||||
+ int ch_idx;
|
||||
+ int ch = MHUV2_CH_UNKNOWN;
|
||||
+
|
||||
+ for (ch_idx = 0;
|
||||
+ ch_idx < readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH);
|
||||
+ ch_idx++) {
|
||||
+ if (readl_relaxed(&mhuv2->reg.recv->channel[ch_idx].STAT)) {
|
||||
+ ch = ch_idx;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return ch;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_get_non_zero_ch_idx(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ /* Identify index of channel window containing non-zero data */
|
||||
+ switch (readl_relaxed_bitfield(&mhuv2->reg.recv->AIDR,
|
||||
+ ARCH_MINOR_REV)) {
|
||||
+ case 1:
|
||||
+ return mhuv2_combint_idx(mhuv2);
|
||||
+ default:
|
||||
+ return mhuv20_get_non_zero_ch_idx(mhuv2);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_read_data_single_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_chan_idx(chan);
|
||||
+
|
||||
+ msg->data = kzalloc(MHUV2_STAT_BYTES, GFP_KERNEL);
|
||||
+ if (!msg->data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ *(mhuv2_stat_reg_t *)msg->data =
|
||||
+ readl_relaxed(&mhuv2->reg.recv->channel[ch_idx].STAT);
|
||||
+ msg->len = MHUV2_STAT_BYTES;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_clear_data_single_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_chan_idx(chan);
|
||||
+
|
||||
+ writel_relaxed(readl_relaxed(&mhuv2->reg.recv->channel[ch_idx].STAT),
|
||||
+ &mhuv2->reg.recv->channel[ch_idx].STAT_CLEAR);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_send_data_single_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ const struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_chan_idx(chan);
|
||||
+ int bytes_left = msg->len;
|
||||
+ char *data = msg->data;
|
||||
+
|
||||
+ if (ch_idx >= readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ while (bytes_left > 0) {
|
||||
+ mhuv2_stat_reg_t word = *(mhuv2_stat_reg_t *)(data);
|
||||
+
|
||||
+ if (bytes_left < MHUV2_STAT_BYTES)
|
||||
+ word &= LSB_MASK(bytes_left * __CHAR_BIT__);
|
||||
+
|
||||
+ if (!word) {
|
||||
+ dev_err(mhuv2->dev,
|
||||
+ "Data transmitted in single-word mode must be non-zero\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ writel_relaxed(word,
|
||||
+ &mhuv2->reg.send->channel[ch_idx].STAT_SET);
|
||||
+ while (readl_relaxed(&mhuv2->reg.send->channel[ch_idx].STAT))
|
||||
+ continue;
|
||||
+ bytes_left -= MHUV2_STAT_BYTES;
|
||||
+ data += MHUV2_STAT_BYTES;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_last_tx_done_single_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_chan_idx(chan);
|
||||
+
|
||||
+ return readl_relaxed(&mhuv2->reg.send->channel[ch_idx].STAT) == 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_setup_single_word(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ int i;
|
||||
+ const u32 channel_windows =
|
||||
+ readl_relaxed_bitfield(mhuv2->frame == RECEIVER_FRAME ?
|
||||
+ &mhuv2->reg.recv->MHU_CFG :
|
||||
+ &mhuv2->reg.send->MHU_CFG,
|
||||
+ NUM_CH);
|
||||
+
|
||||
+ mhuv2->mbox.num_chans = channel_windows;
|
||||
+ mhuv2->mbox.chans =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ mhuv2->mbox.num_chans * sizeof(struct mbox_chan),
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ for (i = 0; i < mhuv2->mbox.num_chans; i++) {
|
||||
+ mhuv2->mbox.chans[i].con_priv =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ sizeof(struct arm_mhuv2_mbox_chan_priv),
|
||||
+ GFP_KERNEL);
|
||||
+ mhuv2_chan_idx(&mhuv2->mbox.chans[i]) = i;
|
||||
+ }
|
||||
+
|
||||
+ if (mhuv2->frame == RECEIVER_FRAME) {
|
||||
+ /* Ensure all status registers are unmasked */
|
||||
+ for (i = 0; i < channel_windows; i++) {
|
||||
+ writel_relaxed(0x0,
|
||||
+ &mhuv2->reg.recv->channel[i].MASK_SET);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline struct mbox_chan *
|
||||
+ mhuv2_get_active_mbox_chan_single_word(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_get_non_zero_ch_idx(mhuv2);
|
||||
+
|
||||
+ if (ch_idx >= mhuv2->mbox.num_chans) {
|
||||
+ dev_err(mhuv2->dev,
|
||||
+ "Invalid active channel in single word mode\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+ return &mhuv2->mbox.chans[ch_idx];
|
||||
+}
|
||||
+
|
||||
+static const struct mhuv2_ops mhuv2_single_word_ops = {
|
||||
+ .read_data = mhuv2_read_data_single_word,
|
||||
+ .clear_data = mhuv2_clear_data_single_word,
|
||||
+ .send_data = mhuv2_send_data_single_word,
|
||||
+ .setup = mhuv2_setup_single_word,
|
||||
+ .last_tx_done = mhuv2_last_tx_done_single_word,
|
||||
+ .get_active_mbox_chan = mhuv2_get_active_mbox_chan_single_word,
|
||||
+};
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
+/*
|
||||
+ * MHUv2 receiver interrupt service routine
|
||||
+ *
|
||||
+ * This routine will be called whenever a reception interrupt is raised on the
|
||||
+ * MHU device. Given that an MHU device may manage multiple mailboxes, it is
|
||||
+ * up to the protocol-specific operations to determine:
|
||||
+ * - What is the active mailbox channel
|
||||
+ * - Read the data within the MHU corresponding to the channel
|
||||
+ * - Clear the data within the MHU corresponding to the channel
|
||||
+ *
|
||||
+ * These operations must also ensure to not overwrite any data which may belong
|
||||
+ * to a different mailbox channel. For instance, if data is received in two
|
||||
+ * channel windows in single-word mode, the ISR will read and clear the data
|
||||
+ * from one of these channel windows within a pass. This will result in a status
|
||||
+ * register being non-zero upon returning from this routine, which in turn
|
||||
+ * will keep the interrupt asserted for a second round.
|
||||
+ */
|
||||
+static irqreturn_t mhuv2_rx_interrupt(int irq, void *data)
|
||||
+{
|
||||
+ struct arm_mbox_msg msg;
|
||||
+ int status;
|
||||
+ struct arm_mhuv2 *mhuv2 = data;
|
||||
+ struct mbox_chan *chan = mhuv2->ops->get_active_mbox_chan(mhuv2);
|
||||
+
|
||||
+ msg.data = NULL;
|
||||
+ msg.len = 0;
|
||||
+
|
||||
+ status = mhuv2->ops->read_data(mhuv2, chan, &msg);
|
||||
+ if (status != 0)
|
||||
+ goto rx_exit;
|
||||
+
|
||||
+ if (!chan->cl) {
|
||||
+ dev_warn(
|
||||
+ mhuv2->dev,
|
||||
+ "Warning: Received data on channel not currently attached to "
|
||||
+ "a mailbox client\n");
|
||||
+ } else {
|
||||
+ mbox_chan_received_data(chan, (void *)&msg);
|
||||
+ }
|
||||
+
|
||||
+ status = mhuv2->ops->clear_data(mhuv2, chan, &msg);
|
||||
+
|
||||
+rx_exit:
|
||||
+ kfree(msg.data);
|
||||
+
|
||||
+ return status == 0 ? IRQ_HANDLED : IRQ_NONE;
|
||||
+}
|
||||
+
|
||||
+static bool mhuv2_last_tx_done(struct mbox_chan *chan)
|
||||
+{
|
||||
+ struct arm_mhuv2 *mhuv2 = mhu2_from_mbox_chan(chan);
|
||||
+
|
||||
+ return mhuv2->ops->last_tx_done(mhuv2, chan);
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_send_data(struct mbox_chan *chan, void *data)
|
||||
+{
|
||||
+ struct arm_mhuv2 *mhuv2 = mhu2_from_mbox_chan(chan);
|
||||
+ struct arm_mbox_msg *msg = data;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!mhuv2->ops->last_tx_done(mhuv2, chan))
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ ret = mhuv2->ops->send_data(mhuv2, chan, msg);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_startup(struct mbox_chan *chan)
|
||||
+{
|
||||
+ struct arm_mhuv2 *mhuv2 = mhu2_from_mbox_ctrl(chan->mbox);
|
||||
+
|
||||
+ writel_relaxed(0x1, &mhuv2->reg.send->ACCESS_REQUEST);
|
||||
+ while (!readl_relaxed(&mhuv2->reg.send->ACCESS_READY))
|
||||
+ continue;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mhuv2_shutdown(struct mbox_chan *chan)
|
||||
+{
|
||||
+ struct arm_mhuv2 *mhuv2 = mhu2_from_mbox_ctrl(chan->mbox);
|
||||
+
|
||||
+ writel_relaxed(0x0, &mhuv2->reg.send->ACCESS_REQUEST);
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_recv_startup(struct mbox_chan *chan)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mhuv2_recv_shutdown(struct mbox_chan *chan)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_recv_send_data(struct mbox_chan *chan, void *data)
|
||||
+{
|
||||
+ dev_err(chan->mbox->dev,
|
||||
+ "Trying to transmit on a receiver MHU frame\n");
|
||||
+ return -EIO;
|
||||
+}
|
||||
+
|
||||
+static bool mhuv2_recv_last_tx_done(struct mbox_chan *chan)
|
||||
+{
|
||||
+ dev_err(chan->mbox->dev, "Trying to Tx poll on a receiver MHU frame\n");
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static const struct mbox_chan_ops mhuv2_receiver_ops = {
|
||||
+ .send_data = mhuv2_recv_send_data,
|
||||
+ .startup = mhuv2_recv_startup,
|
||||
+ .shutdown = mhuv2_recv_shutdown,
|
||||
+ .last_tx_done = mhuv2_recv_last_tx_done,
|
||||
+};
|
||||
+
|
||||
+static const struct mbox_chan_ops mhuv2_sender_ops = {
|
||||
+ .send_data = mhuv2_send_data,
|
||||
+ .startup = mhuv2_startup,
|
||||
+ .shutdown = mhuv2_shutdown,
|
||||
+ .last_tx_done = mhuv2_last_tx_done,
|
||||
+};
|
||||
+
|
||||
+static struct mbox_chan *mhuv2_mbox_of_xlate(struct mbox_controller *ctrl,
|
||||
+ const struct of_phandle_args *pa)
|
||||
+{
|
||||
+ struct mbox_chan *chan;
|
||||
+
|
||||
+ if (pa->args_count != 1)
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+
|
||||
+ if (pa->args[0] >= ctrl->num_chans)
|
||||
+ return ERR_PTR(-ENOENT);
|
||||
+
|
||||
+ chan = &ctrl->chans[pa->args[0]];
|
||||
+ return chan;
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
+{
|
||||
+ int err;
|
||||
+ struct device *dev = &adev->dev;
|
||||
+ const struct device_node *np = dev->of_node;
|
||||
+ struct arm_mhuv2 *mhuv2;
|
||||
+ const char *mhuv2_protocol_str;
|
||||
+
|
||||
+ /* Allocate memory for device */
|
||||
+ mhuv2 = devm_kzalloc(dev, sizeof(*mhuv2), GFP_KERNEL);
|
||||
+ if (!mhuv2)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mhuv2->dev = dev;
|
||||
+
|
||||
+ /* Assign transport protocol-specific operations */
|
||||
+ err = of_property_read_string(np, "mhu-protocol", &mhuv2_protocol_str);
|
||||
+
|
||||
+ if (err) {
|
||||
+ dev_err(dev,
|
||||
+ "Probe failed: no transport protocol specified\n");
|
||||
+ return -ENODEV;
|
||||
+ } else if (strcmp(mhuv2_protocol_str,
|
||||
+ mhuv2_protocol_dt_identifiers[SINGLE_WORD]) == 0) {
|
||||
+ mhuv2->ops = &mhuv2_single_word_ops;
|
||||
+ } else {
|
||||
+ dev_err(dev,
|
||||
+ "Probe failed: '%s' is not a valid transport protocol specifier\n",
|
||||
+ mhuv2_protocol_str);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ /* Get MHU type specific properties from device tree */
|
||||
+ if (adev->irq[0]) {
|
||||
+ mhuv2->frame = RECEIVER_FRAME;
|
||||
+ mhuv2->reg.recv = (struct mhu2_recv_frame_reg *)of_iomap(
|
||||
+ (struct device_node *)np, 0);
|
||||
+ if (!mhuv2->reg.recv)
|
||||
+ goto io_fail;
|
||||
+ mhuv2->irq = adev->irq[0];
|
||||
+ } else {
|
||||
+ mhuv2->frame = SENDER_FRAME;
|
||||
+ mhuv2->reg.send = (struct mhu2_send_frame_reg *)of_iomap(
|
||||
+ (struct device_node *)np, 0);
|
||||
+ if (!mhuv2->reg.send)
|
||||
+ goto io_fail;
|
||||
+ }
|
||||
+
|
||||
+ /* Mailbox controller setup */
|
||||
+ mhuv2->mbox.dev = dev;
|
||||
+ mhuv2->mbox.txdone_irq = false;
|
||||
+ mhuv2->mbox.txdone_poll = true;
|
||||
+ mhuv2->mbox.txpoll_period = 1;
|
||||
+ mhuv2->mbox.of_xlate = mhuv2_mbox_of_xlate;
|
||||
+ mhuv2->mbox.ops = mhuv2->frame == SENDER_FRAME ? &mhuv2_sender_ops :
|
||||
+ &mhuv2_receiver_ops;
|
||||
+ /*
|
||||
+ * Transport protocol specific setup
|
||||
+ * Setup function _must_ allocate mailbox channels according to the
|
||||
+ * number of channels provided in the given transport protocol mode.
|
||||
+ */
|
||||
+ err = mhuv2->ops->setup(mhuv2);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ /* Request an interrupt if this is a receiver frame */
|
||||
+ if (mhuv2->frame == RECEIVER_FRAME) {
|
||||
+ err = devm_request_threaded_irq(dev, adev->irq[0], NULL,
|
||||
+ mhuv2_rx_interrupt, IRQF_ONESHOT, "mhuv2_link", mhuv2);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "unable to acquire IRQ %d\n", mhuv2->irq);
|
||||
+ return err;
|
||||
+ }
|
||||
+ /*
|
||||
+ * For minor version 1 and forward, the combined interrupt of
|
||||
+ * the receiver frame must be explicitly enabled during startup.
|
||||
+ */
|
||||
+ if (readl_relaxed_bitfield(&mhuv2->reg.recv->AIDR,
|
||||
+ ARCH_MINOR_REV) > 0) {
|
||||
+ writel_relaxed_bitfield(1, &mhuv2->reg.recv->INT_EN,
|
||||
+ CHCOMB);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ amba_set_drvdata(adev, mhuv2);
|
||||
+
|
||||
+ err = devm_mbox_controller_register(dev, &mhuv2->mbox);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "failed to register ARM MHUv2 driver %d\n", err);
|
||||
+ iounmap(mhuv2->frame == RECEIVER_FRAME ? mhuv2->reg.recv :
|
||||
+ mhuv2->reg.send);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(dev, "ARM MHUv2 %s frame (%s) Mailbox driver registered\n",
|
||||
+ mhuv2_frame_dt_identifiers[mhuv2->frame],
|
||||
+ mhuv2_protocol_str);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+io_fail:
|
||||
+ dev_err(dev, "Probe failed: failed to map '%s' frame\n",
|
||||
+ mhuv2_frame_dt_identifiers[mhuv2->frame]);
|
||||
+ iounmap(mhuv2->frame == RECEIVER_FRAME ? mhuv2->reg.recv :
|
||||
+ mhuv2->reg.send);
|
||||
+ return -ENOMEM;
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_remove(struct amba_device *adev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct amba_id mhuv2_ids[] = {
|
||||
+ {
|
||||
+ .id = 0x4b0d1,
|
||||
+ .mask = 0xfffff,
|
||||
+ },
|
||||
+ {
|
||||
+ .id = 0xbb0d1,
|
||||
+ .mask = 0xfffff,
|
||||
+ },
|
||||
+ { 0, 0 },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(amba, mhuv2_ids);
|
||||
+
|
||||
+static struct amba_driver arm_mhuv2_driver = {
|
||||
+ .drv = {
|
||||
+ .name = "mhuv2",
|
||||
+ },
|
||||
+ .id_table = mhuv2_ids,
|
||||
+ .probe = mhuv2_probe,
|
||||
+ .remove = mhuv2_remove,
|
||||
+};
|
||||
+module_amba_driver(arm_mhuv2_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_DESCRIPTION("ARM MHUv2 Driver");
|
||||
+MODULE_AUTHOR("Morten Borup Petersen <morten.petersen@arm.com>");
|
||||
diff --git a/include/linux/mailbox/arm-mbox-message.h b/include/linux/mailbox/arm-mbox-message.h
|
||||
new file mode 100644
|
||||
index 000000000000..112b4f927c1a
|
||||
--- /dev/null
|
||||
+++ b/include/linux/mailbox/arm-mbox-message.h
|
||||
@@ -0,0 +1,37 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Arm Mailbox Message
|
||||
+ *
|
||||
+ * The Arm mailbox message structure is used to pass data- and length
|
||||
+ * information between a mailbox client and mailbox controller, through the
|
||||
+ * provided void* of the common mailbox frameworks send- and receive APIs.
|
||||
+ *
|
||||
+ * This will be utilized when a mailbox controller is able to transmit
|
||||
+ * more than a single word within a transmission, allowing the controller
|
||||
+ * to fully utilize its available resources.
|
||||
+ * No message protocol is enforced through this structure - a utilizing mailbox
|
||||
+ * client driver shall implement its own message protocol, which may then be
|
||||
+ * transmitted through an arm_mbox_msg.
|
||||
+ *
|
||||
+ * Given a message protocol of size A and an arm_mbox_msg containing data of
|
||||
+ * length B, a mailbox channel may callback with B < A. In this case, the
|
||||
+ * message protocol driver must implement a state machine which allows for
|
||||
+ * multiple callbacks that provides parts of a full message of size A. This
|
||||
+ * state machine must account for, that the length of the arm_mbox_msg received
|
||||
+ * may vary between callbacks based on the underlying hardware as well as the
|
||||
+ * transmitted data.
|
||||
+ *
|
||||
+ * Copyright (C) 2019 Arm Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LINUX_ARM_MBOX_MESSAGE_H_
|
||||
+#define _LINUX_ARM_MBOX_MESSAGE_H_
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+struct arm_mbox_msg {
|
||||
+ void *data;
|
||||
+ size_t len;
|
||||
+};
|
||||
+
|
||||
+#endif /* _LINUX_ARM_MBOX_MESSAGE_H_ */
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
From 515a936531a25a0c48a97efe3828962ed8d781dd Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Wed, 19 Jun 2019 16:55:20 +0100
|
||||
Subject: [PATCH 5/9] mailbox: arm_mhuv2: add doorbell transport protocol
|
||||
operations
|
||||
|
||||
In doorbell mode, the mailbox controller will provide a mailbox for each
|
||||
flag bit available in the combined number of channel windows available
|
||||
within the MHU device.
|
||||
|
||||
When in doorbell mode, the MHU should be used solely as an interrupt
|
||||
generating mechanism. If data is to be transmitted, this must be done
|
||||
out-band, ie. through shared memory, by a driving utilizing the mailbox
|
||||
for interrupt generation.
|
||||
|
||||
Change-Id: I8410b21471743c0b624c873388f9629ea0863789
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Cc:Jassi Brar <jassisinghbrar@gmail.com
|
||||
Cc: devicetree@vger.kernel.org
|
||||
|
||||
Upstream-Status: Denied [https://lkml.org/lkml/2019/7/17/615]
|
||||
---
|
||||
drivers/mailbox/arm_mhu_v2.c | 108 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 108 insertions(+)
|
||||
|
||||
diff --git a/drivers/mailbox/arm_mhu_v2.c b/drivers/mailbox/arm_mhu_v2.c
|
||||
index d809076eb47b..efde7a71a3f7 100644
|
||||
--- a/drivers/mailbox/arm_mhu_v2.c
|
||||
+++ b/drivers/mailbox/arm_mhu_v2.c
|
||||
@@ -429,6 +429,111 @@ static const struct mhuv2_ops mhuv2_single_word_ops = {
|
||||
};
|
||||
/* ========================================================================== */
|
||||
|
||||
+/* =================== Doorbell transport protocol operations =============== */
|
||||
+
|
||||
+static inline int mhuv2_read_data_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_clear_data_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
|
||||
+ const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
|
||||
+ const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
|
||||
+
|
||||
+ writel_relaxed(BIT(ch_window_reg_idx),
|
||||
+ &mhuv2->reg.recv->channel[ch_window_idx].STAT_CLEAR);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_send_data_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ const struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
|
||||
+ const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
|
||||
+ const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
|
||||
+
|
||||
+ writel_relaxed(
|
||||
+ readl_relaxed(&mhuv2->reg.send->channel[ch_window_idx].STAT) |
|
||||
+ BIT(ch_window_reg_idx),
|
||||
+ &mhuv2->reg.send->channel[ch_window_idx].STAT_SET);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_last_tx_done_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan)
|
||||
+{
|
||||
+ const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
|
||||
+ const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
|
||||
+ const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
|
||||
+
|
||||
+ return (readl_relaxed(&mhuv2->reg.send->channel[ch_window_idx].STAT) &
|
||||
+ BIT(ch_window_reg_idx)) == 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_setup_doorbell(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ int i;
|
||||
+ const u32 channel_windows =
|
||||
+ readl_relaxed_bitfield(mhuv2->frame == RECEIVER_FRAME ?
|
||||
+ &mhuv2->reg.recv->MHU_CFG :
|
||||
+ &mhuv2->reg.send->MHU_CFG,
|
||||
+ NUM_CH);
|
||||
+
|
||||
+ mhuv2->mbox.num_chans = MHUV2_STAT_BITS * channel_windows;
|
||||
+ mhuv2->mbox.chans =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ mhuv2->mbox.num_chans * sizeof(struct mbox_chan),
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ for (i = 0; i < mhuv2->mbox.num_chans; i++) {
|
||||
+ mhuv2->mbox.chans[i].con_priv =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ sizeof(struct arm_mhuv2_mbox_chan_priv),
|
||||
+ GFP_KERNEL);
|
||||
+ mhuv2_chan_idx(&mhuv2->mbox.chans[i]) = i;
|
||||
+ }
|
||||
+
|
||||
+ if (mhuv2->frame == RECEIVER_FRAME) {
|
||||
+ /* Ensure all status registers are unmasked */
|
||||
+ for (i = 0; i < channel_windows; i++) {
|
||||
+ writel_relaxed(0x0,
|
||||
+ &mhuv2->reg.recv->channel[i].MASK_SET);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline struct mbox_chan *
|
||||
+ mhuv2_get_active_mbox_chan_doorbell(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ const u32 ch_window_idx = mhuv2_get_non_zero_ch_idx(mhuv2);
|
||||
+ const u32 ch_window_reg_idx = __find_set_bit(
|
||||
+ readl_relaxed(&mhuv2->reg.recv->channel[ch_window_idx].STAT));
|
||||
+ if (ch_window_reg_idx == -1)
|
||||
+ return ERR_PTR(-EIO);
|
||||
+
|
||||
+ return &mhuv2->mbox.chans[ch_window_reg_idx +
|
||||
+ ch_window_idx * MHUV2_STAT_BITS];
|
||||
+}
|
||||
+
|
||||
+static const struct mhuv2_ops mhuv2_doorbell_ops = {
|
||||
+ .read_data = mhuv2_read_data_doorbell,
|
||||
+ .clear_data = mhuv2_clear_data_doorbell,
|
||||
+ .send_data = mhuv2_send_data_doorbell,
|
||||
+ .setup = mhuv2_setup_doorbell,
|
||||
+ .last_tx_done = mhuv2_last_tx_done_doorbell,
|
||||
+ .get_active_mbox_chan = mhuv2_get_active_mbox_chan_doorbell,
|
||||
+};
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
/*
|
||||
* MHUv2 receiver interrupt service routine
|
||||
*
|
||||
@@ -591,6 +696,9 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
} else if (strcmp(mhuv2_protocol_str,
|
||||
mhuv2_protocol_dt_identifiers[SINGLE_WORD]) == 0) {
|
||||
mhuv2->ops = &mhuv2_single_word_ops;
|
||||
+ } else if (strcmp(mhuv2_protocol_str,
|
||||
+ mhuv2_protocol_dt_identifiers[DOORBELL]) == 0) {
|
||||
+ mhuv2->ops = &mhuv2_doorbell_ops;
|
||||
} else {
|
||||
dev_err(dev,
|
||||
"Probe failed: '%s' is not a valid transport protocol specifier\n",
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
From 31140984e2ead5d56b072d0fed0b5f18a1e7e825 Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Wed, 19 Jun 2019 17:00:31 +0100
|
||||
Subject: [PATCH 6/9] mailbox: arm_mhuv2: add multi word transport protocol
|
||||
operations
|
||||
|
||||
When in multi-word mode, the mailbox controller will provide a single
|
||||
mailbox. It is required that the MHU device has at least 2 channel windows
|
||||
available for the MHU to function in multi-word mode.
|
||||
|
||||
Transmitting and receiving data through the mailbox framework in
|
||||
multi-word mode is done through a struct arm_mbox_msg.
|
||||
|
||||
Change-Id: Ibcf352d19ae3908093b20350853b16cf6a7933a2
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Cc: jassisinghbrar@gmail.com
|
||||
Cc: devicetree@vger.kernel.org
|
||||
|
||||
Upstream-Status: Denied [https://lkml.org/lkml/2019/7/17/615]
|
||||
---
|
||||
drivers/mailbox/arm_mhu_v2.c | 225 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 225 insertions(+)
|
||||
|
||||
diff --git a/drivers/mailbox/arm_mhu_v2.c b/drivers/mailbox/arm_mhu_v2.c
|
||||
index efde7a71a3f7..e73e829d4f1e 100644
|
||||
--- a/drivers/mailbox/arm_mhu_v2.c
|
||||
+++ b/drivers/mailbox/arm_mhu_v2.c
|
||||
@@ -429,6 +429,228 @@ static const struct mhuv2_ops mhuv2_single_word_ops = {
|
||||
};
|
||||
/* ========================================================================== */
|
||||
|
||||
+/* ================ Multi word transport protocol operations ================ */
|
||||
+static inline int mhuv2_read_data_multi_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ int ch;
|
||||
+ const int channels =
|
||||
+ readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH);
|
||||
+
|
||||
+ msg->data = kzalloc(MHUV2_STAT_BYTES * channels, GFP_KERNEL);
|
||||
+
|
||||
+ for (ch = 0; ch < channels; ch++) {
|
||||
+ /*
|
||||
+ * Messages are expected to be received in order of most
|
||||
+ * significant word to least significant word.
|
||||
+ * (see mhuv2_send_data_multi_word)
|
||||
+ */
|
||||
+ const mhuv2_stat_reg_t word =
|
||||
+ readl_relaxed(&mhuv2->reg.recv->channel[ch].STAT);
|
||||
+ ((mhuv2_stat_reg_t *)msg->data)[channels - 1 - ch] = word;
|
||||
+ }
|
||||
+
|
||||
+ msg->len = channels * MHUV2_STAT_BYTES;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_clear_data_multi_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ int ch;
|
||||
+ const int channels =
|
||||
+ readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH);
|
||||
+
|
||||
+ for (ch = 0; ch < channels; ch++) {
|
||||
+ /*
|
||||
+ * Last channel window must be cleared as the final operation.
|
||||
+ * Upon clearing the last channel window register, which is
|
||||
+ * unmasked in multi-word mode, the interrupt is deasserted.
|
||||
+ */
|
||||
+ writel_relaxed(
|
||||
+ readl_relaxed(&mhuv2->reg.recv->channel[ch].STAT),
|
||||
+ &mhuv2->reg.recv->channel[ch].STAT_CLEAR);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int __mhuv2_mw_bytes_to_send(const int bytes_in_round,
|
||||
+ const int bytes_left)
|
||||
+{
|
||||
+ /*
|
||||
+ * Bytes to send on the current channel will always be MHUV2_STAT_BYTES
|
||||
+ * unless in the last round and
|
||||
+ * msg->len % MHUV2_STAT_BYTES != 0
|
||||
+ */
|
||||
+ if (bytes_in_round % MHUV2_STAT_BYTES != 0) {
|
||||
+ const int bts = bytes_left % MHUV2_STAT_BYTES;
|
||||
+ return bts == 0 ? MHUV2_STAT_BYTES : bts;
|
||||
+ } else {
|
||||
+ return MHUV2_STAT_BYTES;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_send_data_multi_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ const struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ /*
|
||||
+ * Message will be transmitted from most significant to least
|
||||
+ * significant word. This is to allow for messages shorter than
|
||||
+ * $channels to still trigger the receiver interrupt which gets
|
||||
+ * activated when the last STAT register is written. As an example, a
|
||||
+ * 6-word message is to be written on a 4-channel MHU connection:
|
||||
+ * Registers marked with '*' are masked, and will not generate an
|
||||
+ * interrupt on the receiver side once written.
|
||||
+ *
|
||||
+ * uint32_t *data = [0x00000001],[0x00000002],[0x00000003],[0x00000004],
|
||||
+ * [0x00000005], [0x00000006]
|
||||
+ *
|
||||
+ * ROUND 1:
|
||||
+ * STAT reg To write Write sequence
|
||||
+ * [ STAT 3 ] <- [0x00000001] 4 <- triggers interrupt on receiver
|
||||
+ * *[ STAT 2 ] <- [0x00000002] 3
|
||||
+ * *[ STAT 1 ] <- [0x00000003] 2
|
||||
+ * *[ STAT 0 ] <- [0x00000004] 1
|
||||
+ *
|
||||
+ * data += 4 // Increment data pointer by number of STAT regs
|
||||
+ *
|
||||
+ * ROUND 2:
|
||||
+ * STAT reg To write Write sequence
|
||||
+ * [ STAT 3 ] <- [0x00000005] 2 <- triggers interrupt on receiver
|
||||
+ * *[ STAT 2 ] <- [0x00000006] 1
|
||||
+ * *[ STAT 1 ] <- [0x00000000]
|
||||
+ * *[ STAT 0 ] <- [0x00000000]
|
||||
+ */
|
||||
+ int bytes_left, bytes_to_send, i, ch_idx;
|
||||
+ const int ch_windows =
|
||||
+ readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH);
|
||||
+ const size_t round_capacity = ch_windows * MHUV2_STAT_BYTES;
|
||||
+
|
||||
+ bytes_left = msg->len;
|
||||
+ mhuv2_stat_reg_t *data = msg->data;
|
||||
+
|
||||
+ while (bytes_left > 0) {
|
||||
+ /* Note: Each entry of this loop indicates a new ROUND */
|
||||
+ if (*(u32 *)data == 0) {
|
||||
+ dev_err(mhuv2->dev,
|
||||
+ "values in *data aligned on NUM_STAT boundaries must not be zero to ensure that receiver interrupt is triggered\n",
|
||||
+ ch_windows);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ const int bytes_in_round = bytes_left > round_capacity ?
|
||||
+ round_capacity :
|
||||
+ bytes_left;
|
||||
+
|
||||
+ for (i = (ch_windows - 1); i >= 0; i--) {
|
||||
+ ch_idx = ch_windows - 1 - i;
|
||||
+ /*
|
||||
+ * Check whether data should be transmitted in register
|
||||
+ * of index 'ch'.
|
||||
+ */
|
||||
+ if (bytes_in_round > (i * MHUV2_STAT_BYTES)) {
|
||||
+ mhuv2_stat_reg_t word = data[i];
|
||||
+
|
||||
+ bytes_to_send = __mhuv2_mw_bytes_to_send(
|
||||
+ bytes_in_round, bytes_left);
|
||||
+
|
||||
+ if (bytes_to_send != MHUV2_STAT_BYTES) {
|
||||
+ word &= LSB_MASK(bytes_to_send *
|
||||
+ __CHAR_BIT__);
|
||||
+ }
|
||||
+ while (readl_relaxed(
|
||||
+ &mhuv2->reg.send->channel[ch_idx]
|
||||
+ .STAT) != 0)
|
||||
+ continue;
|
||||
+
|
||||
+ writel_relaxed(
|
||||
+ word,
|
||||
+ &mhuv2->reg.send->channel[ch_idx].STAT_SET);
|
||||
+ bytes_left -= bytes_to_send;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ data += ch_windows;
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < ch_windows; ch_idx++) {
|
||||
+ while (readl_relaxed(
|
||||
+ &mhuv2->reg.send->channel[ch_idx].STAT) != 0)
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static inline int mhuv2_last_tx_done_multi_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan)
|
||||
+{
|
||||
+ int ch_idx;
|
||||
+ bool tx_done = true;
|
||||
+
|
||||
+ for (ch_idx = 0;
|
||||
+ ch_idx < readl_relaxed_bitfield(&mhuv2->reg.send->MHU_CFG, NUM_CH);
|
||||
+ ch_idx++) {
|
||||
+ tx_done &= readl_relaxed(
|
||||
+ &mhuv2->reg.send->channel[ch_idx].STAT) == 0;
|
||||
+ }
|
||||
+ return tx_done;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_setup_multi_word(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ int ret, i;
|
||||
+
|
||||
+ const u32 channel_windows =
|
||||
+ readl_relaxed_bitfield(mhuv2->frame == RECEIVER_FRAME ?
|
||||
+ &mhuv2->reg.recv->MHU_CFG :
|
||||
+ &mhuv2->reg.send->MHU_CFG,
|
||||
+ NUM_CH);
|
||||
+ if (channel_windows < 2) {
|
||||
+ dev_err(mhuv2->dev,
|
||||
+ "Error: at least 2 MHU channel windows are required for using the multi-word transfer protocol");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ if (mhuv2->frame == RECEIVER_FRAME) {
|
||||
+ /*
|
||||
+ * The multi-word transport protocol mandates that all but
|
||||
+ * the last status register must be masked.
|
||||
+ */
|
||||
+ for (i = 0; i < (channel_windows - 1); i++) {
|
||||
+ writel_relaxed(-1,
|
||||
+ &mhuv2->reg.recv->channel[i].MASK_SET);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mhuv2->mbox.num_chans = 1;
|
||||
+ mhuv2->mbox.chans =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ mhuv2->mbox.num_chans * sizeof(struct mbox_chan),
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline struct mbox_chan *
|
||||
+ mhuv2_get_active_mbox_chan_multi_word(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ return &mhuv2->mbox.chans[0];
|
||||
+}
|
||||
+
|
||||
+static const struct mhuv2_ops mhuv2_multi_word_ops = {
|
||||
+ .read_data = mhuv2_read_data_multi_word,
|
||||
+ .clear_data = mhuv2_clear_data_multi_word,
|
||||
+ .send_data = mhuv2_send_data_multi_word,
|
||||
+ .setup = mhuv2_setup_multi_word,
|
||||
+ .last_tx_done = mhuv2_last_tx_done_multi_word,
|
||||
+ .get_active_mbox_chan = mhuv2_get_active_mbox_chan_multi_word,
|
||||
+};
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
/* =================== Doorbell transport protocol operations =============== */
|
||||
|
||||
static inline int mhuv2_read_data_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
@@ -696,6 +918,9 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
} else if (strcmp(mhuv2_protocol_str,
|
||||
mhuv2_protocol_dt_identifiers[SINGLE_WORD]) == 0) {
|
||||
mhuv2->ops = &mhuv2_single_word_ops;
|
||||
+ } else if (strcmp(mhuv2_protocol_str,
|
||||
+ mhuv2_protocol_dt_identifiers[MULTI_WORD]) == 0) {
|
||||
+ mhuv2->ops = &mhuv2_multi_word_ops;
|
||||
} else if (strcmp(mhuv2_protocol_str,
|
||||
mhuv2_protocol_dt_identifiers[DOORBELL]) == 0) {
|
||||
mhuv2->ops = &mhuv2_doorbell_ops;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
From 68ce2dfe4c6f3806001fb8d682d6e99a9580dc2a Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Wed, 24 Jun 2020 11:16:01 +0100
|
||||
Subject: [PATCH 7/9] firmware: arm_scmi: Add fast_switch_possible() api
|
||||
|
||||
Add a new fast_switch_possible interface to the existing
|
||||
perf_ops api to export the information of whether or not
|
||||
fast_switch is possible in this driver.
|
||||
|
||||
This can be used by the CPUFreq driver and framework to
|
||||
choose proper mechanism for frequency change.
|
||||
|
||||
Suggested-by: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Signed-off-by: Nicola Mazzucato <nicola.mazzucato@arm.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/firmware/arm_scmi?id=1909872ff20fc378ec6a44ea1a2b2966d834e504]
|
||||
---
|
||||
drivers/firmware/arm_scmi/perf.c | 12 ++++++++++++
|
||||
include/linux/scmi_protocol.h | 2 ++
|
||||
2 files changed, 14 insertions(+)
|
||||
|
||||
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
|
||||
index 601af4edad5e..c9350bb2ba1f 100644
|
||||
--- a/drivers/firmware/arm_scmi/perf.c
|
||||
+++ b/drivers/firmware/arm_scmi/perf.c
|
||||
@@ -691,6 +691,17 @@ static int scmi_dvfs_est_power_get(const struct scmi_handle *handle, u32 domain,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static bool scmi_fast_switch_possible(const struct scmi_handle *handle,
|
||||
+ struct device *dev)
|
||||
+{
|
||||
+ struct perf_dom_info *dom;
|
||||
+ struct scmi_perf_info *pi = handle->perf_priv;
|
||||
+
|
||||
+ dom = pi->dom_info + scmi_dev_domain_id(dev);
|
||||
+
|
||||
+ return (dom->fc_info && dom->fc_info->level_set_addr);
|
||||
+}
|
||||
+
|
||||
static struct scmi_perf_ops perf_ops = {
|
||||
.limits_set = scmi_perf_limits_set,
|
||||
.limits_get = scmi_perf_limits_get,
|
||||
@@ -702,6 +713,7 @@ static struct scmi_perf_ops perf_ops = {
|
||||
.freq_set = scmi_dvfs_freq_set,
|
||||
.freq_get = scmi_dvfs_freq_get,
|
||||
.est_power_get = scmi_dvfs_est_power_get,
|
||||
+ .fast_switch_possible = scmi_fast_switch_possible,
|
||||
};
|
||||
|
||||
static int scmi_perf_protocol_init(struct scmi_handle *handle)
|
||||
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
|
||||
index 881fea47c83d..b1f4a88219c5 100644
|
||||
--- a/include/linux/scmi_protocol.h
|
||||
+++ b/include/linux/scmi_protocol.h
|
||||
@@ -114,6 +114,8 @@ struct scmi_perf_ops {
|
||||
unsigned long *rate, bool poll);
|
||||
int (*est_power_get)(const struct scmi_handle *handle, u32 domain,
|
||||
unsigned long *rate, unsigned long *power);
|
||||
+ bool (*fast_switch_possible)(const struct scmi_handle *handle,
|
||||
+ struct device *dev);
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From 47300d8385801913709eda5fd237d54f51477546 Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Wed, 24 Jun 2020 11:25:02 +0100
|
||||
Subject: [PATCH 8/9] cpufreq: arm_scmi: Set fast_switch_possible conditionally
|
||||
|
||||
Currently the fast_switch_possible flag is set unconditionally
|
||||
to true. Based on this, schedutil does not create a
|
||||
thread for frequency switching and would always use the
|
||||
fast switch path.
|
||||
However, if the platform does not support frequency
|
||||
fast switch, this may cause the governor to attempt an
|
||||
operation that is not supported by the platform.
|
||||
|
||||
Fix this by correctly retrieve the fast_switch capability
|
||||
from the driver which knows if the platform can support
|
||||
this feature.
|
||||
|
||||
Suggested-by: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Signed-off-by: Nicola Mazzucato <nicola.mazzucato@arm.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/cpufreq?id=fb3571276b970cbe7b45ecdc762e92f3f305ad6d]
|
||||
---
|
||||
drivers/cpufreq/scmi-cpufreq.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
|
||||
index e6182c89df79..931fcf0ef221 100644
|
||||
--- a/drivers/cpufreq/scmi-cpufreq.c
|
||||
+++ b/drivers/cpufreq/scmi-cpufreq.c
|
||||
@@ -198,7 +198,8 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
|
||||
policy->cpuinfo.transition_latency = latency;
|
||||
|
||||
- policy->fast_switch_possible = true;
|
||||
+ policy->fast_switch_possible =
|
||||
+ handle->perf_ops->fast_switch_possible(handle, cpu_dev);
|
||||
|
||||
em_register_perf_domain(policy->cpus, nr_opp, &em_cb);
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+307
-137
@@ -6,18 +6,14 @@ CONFIG_PREEMPT=y
|
||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_PSI=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_UCLAMP_TASK=y
|
||||
CONFIG_NUMA_BALANCING=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_UCLAMP_TASK_GROUP=y
|
||||
CONFIG_CGROUP_PIDS=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_HUGETLB=y
|
||||
@@ -26,15 +22,17 @@ CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
CONFIG_CGROUP_BPF=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_FHANDLE is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_ARCH_ACTIONS=y
|
||||
CONFIG_ARCH_AGILEX=y
|
||||
CONFIG_ARCH_SUNXI=y
|
||||
CONFIG_ARCH_ALPINE=y
|
||||
CONFIG_ARCH_BCM2835=y
|
||||
@@ -49,6 +47,8 @@ CONFIG_ARCH_HISI=y
|
||||
CONFIG_ARCH_MEDIATEK=y
|
||||
CONFIG_ARCH_MESON=y
|
||||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_ARCH_MXC=y
|
||||
CONFIG_ARCH_QCOM=y
|
||||
CONFIG_ARCH_RENESAS=y
|
||||
CONFIG_ARCH_ROCKCHIP=y
|
||||
CONFIG_ARCH_SEATTLE=y
|
||||
@@ -72,31 +72,48 @@ CONFIG_CRASH_DUMP=y
|
||||
CONFIG_XEN=y
|
||||
CONFIG_ARM64_SW_TTBR0_PAN=y
|
||||
CONFIG_COMPAT=y
|
||||
CONFIG_ARMV8_DEPRECATED=y
|
||||
CONFIG_SWP_EMULATION=y
|
||||
CONFIG_CP15_BARRIER_EMULATION=y
|
||||
CONFIG_SETEND_EMULATION=y
|
||||
CONFIG_RANDOMIZE_BASE=y
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_PM_AUTOSLEEP=y
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
|
||||
CONFIG_ENERGY_MODEL=y
|
||||
CONFIG_ARM_CPUIDLE=y
|
||||
CONFIG_ARM_PSCI_CPUIDLE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
|
||||
CONFIG_CPUFREQ_DT=y
|
||||
CONFIG_ACPI_CPPC_CPUFREQ=m
|
||||
CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
|
||||
CONFIG_ARM_SCPI_CPUFREQ=y
|
||||
CONFIG_ARM_IMX_CPUFREQ_DT=m
|
||||
CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
|
||||
CONFIG_ARM_QCOM_CPUFREQ_HW=y
|
||||
CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
|
||||
CONFIG_ARM_SCMI_CPUFREQ=y
|
||||
CONFIG_ARM_TEGRA186_CPUFREQ=y
|
||||
CONFIG_ARM_SCMI_PROTOCOL=y
|
||||
CONFIG_ARM_SCPI_PROTOCOL=y
|
||||
CONFIG_RASPBERRYPI_FIRMWARE=y
|
||||
CONFIG_INTEL_STRATIX10_SERVICE=y
|
||||
CONFIG_INTEL_STRATIX10_RSU=m
|
||||
CONFIG_EFI_CAPSULE_LOADER=y
|
||||
CONFIG_IMX_SCU=y
|
||||
CONFIG_IMX_SCU_PD=y
|
||||
CONFIG_ACPI=y
|
||||
CONFIG_ACPI_APEI=y
|
||||
CONFIG_ACPI_APEI_GHES=y
|
||||
CONFIG_ACPI_APEI_PCIEAER=y
|
||||
CONFIG_ACPI_APEI_MEMORY_FAILURE=y
|
||||
CONFIG_ACPI_APEI_EINJ=y
|
||||
CONFIG_VIRTUALIZATION=y
|
||||
CONFIG_KVM=y
|
||||
CONFIG_ARM64_CRYPTO=y
|
||||
@@ -111,21 +128,18 @@ CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
|
||||
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
|
||||
CONFIG_CRYPTO_CHACHA20_NEON=m
|
||||
CONFIG_CRYPTO_AES_ARM64_BS=m
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_KSM=y
|
||||
CONFIG_MEMORY_FAILURE=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_XFRM_INTERFACE=y
|
||||
CONFIG_XFRM_STATISTICS=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
@@ -134,22 +148,19 @@ CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_NET_IPGRE_DEMUX=y
|
||||
CONFIG_NET_IPVTI=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_UDP_DIAG=y
|
||||
CONFIG_INET_DIAG_DESTROY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_ESP=y
|
||||
CONFIG_INET6_IPCOMP=y
|
||||
CONFIG_IPV6_MIP6=y
|
||||
CONFIG_IPV6_VTI=y
|
||||
CONFIG_IPV6_SIT=m
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=y
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=y
|
||||
CONFIG_NF_CONNTRACK_FTP=y
|
||||
@@ -160,22 +171,14 @@ CONFIG_NF_CONNTRACK_PPTP=y
|
||||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CT=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_BPF=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
@@ -187,18 +190,17 @@ CONFIG_NETFILTER_XT_MATCH_LENGTH=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=y
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=y
|
||||
CONFIG_NF_LOG_IPV4=m
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_MATCH_AH=y
|
||||
CONFIG_IP_NF_MATCH_ECN=y
|
||||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
@@ -213,13 +215,15 @@ CONFIG_IP_NF_SECURITY=y
|
||||
CONFIG_IP_NF_ARPTABLES=y
|
||||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_NF_LOG_IPV6=m
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT=y
|
||||
CONFIG_IP6_NF_MANGLE=y
|
||||
CONFIG_IP6_NF_RAW=y
|
||||
CONFIG_L2TP=y
|
||||
CONFIG_IP6_NF_NAT=m
|
||||
CONFIG_IP6_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_BRIDGE_VLAN_FILTERING=y
|
||||
CONFIG_VLAN_8021Q=m
|
||||
@@ -227,30 +231,33 @@ CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_VLAN_8021Q_MVRP=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_SCH_NETEM=y
|
||||
CONFIG_NET_SCH_INGRESS=y
|
||||
CONFIG_NET_CLS_U32=y
|
||||
CONFIG_NET_CLS_BPF=y
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_U32=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_QRTR=m
|
||||
CONFIG_QRTR_SMD=m
|
||||
CONFIG_QRTR_TUN=m
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_BT=m
|
||||
CONFIG_BT_HIDP=m
|
||||
# CONFIG_BT_HS is not set
|
||||
# CONFIG_BT_LE is not set
|
||||
CONFIG_BT_LEDS=y
|
||||
# CONFIG_BT_DEBUGFS is not set
|
||||
CONFIG_BT_HCIBTUSB=m
|
||||
CONFIG_BT_HCIUART=m
|
||||
CONFIG_BT_HCIUART_LL=y
|
||||
CONFIG_BT_HCIUART_BCM=y
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_BT_HCIUART_QCA=y
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_LEDS=y
|
||||
CONFIG_RFKILL=m
|
||||
CONFIG_RFKILL=y
|
||||
CONFIG_NET_9P=y
|
||||
CONFIG_NET_9P_VIRTIO=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCI_IOV=y
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_ACPI=y
|
||||
@@ -259,21 +266,32 @@ CONFIG_PCI_TEGRA=y
|
||||
CONFIG_PCIE_RCAR=y
|
||||
CONFIG_PCI_HOST_GENERIC=y
|
||||
CONFIG_PCI_XGENE=y
|
||||
CONFIG_PCIE_ALTERA=y
|
||||
CONFIG_PCIE_ALTERA_MSI=y
|
||||
CONFIG_PCI_HOST_THUNDER_PEM=y
|
||||
CONFIG_PCI_HOST_THUNDER_ECAM=y
|
||||
CONFIG_PCIE_ROCKCHIP_HOST=m
|
||||
CONFIG_PCI_LAYERSCAPE=y
|
||||
CONFIG_PCI_HISI=y
|
||||
CONFIG_PCIE_QCOM=y
|
||||
CONFIG_PCIE_ARMADA_8K=y
|
||||
CONFIG_PCIE_KIRIN=y
|
||||
CONFIG_PCIE_HISI_STB=y
|
||||
CONFIG_PCIE_TEGRA194=m
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_FW_LOADER_USER_HELPER=y
|
||||
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
|
||||
CONFIG_HISILICON_LPC=y
|
||||
CONFIG_SIMPLE_PM_BUS=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_MTD_NAND_DENALI_DT=y
|
||||
CONFIG_MTD_NAND_MARVELL=y
|
||||
CONFIG_MTD_NAND_QCOM=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_SPI_CADENCE_QUADSPI=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
@@ -281,16 +299,17 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_BLK_DEV_NVME=m
|
||||
CONFIG_SRAM=y
|
||||
CONFIG_UID_SYS_STATS=y
|
||||
CONFIG_EEPROM_AT25=m
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_SCSI_SAS_ATA=y
|
||||
CONFIG_SCSI_HISI_SAS=y
|
||||
CONFIG_SCSI_HISI_SAS_PCI=y
|
||||
CONFIG_SCSI_UFSHCD=m
|
||||
CONFIG_SCSI_UFSHCD_PLATFORM=m
|
||||
CONFIG_SCSI_UFS_HISI=m
|
||||
CONFIG_SCSI_MPT3SAS=m
|
||||
CONFIG_SCSI_UFSHCD=y
|
||||
CONFIG_SCSI_UFSHCD_PLATFORM=y
|
||||
CONFIG_SCSI_UFS_QCOM=m
|
||||
CONFIG_SCSI_UFS_HISI=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_SATA_AHCI=y
|
||||
CONFIG_SATA_AHCI_PLATFORM=y
|
||||
@@ -303,13 +322,14 @@ CONFIG_SATA_RCAR=y
|
||||
CONFIG_PATA_PLATFORM=y
|
||||
CONFIG_PATA_OF_PLATFORM=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=m
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_SNAPSHOT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_ZERO=m
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
|
||||
CONFIG_DM_VERITY_AVB=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_DM_BOW=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_MACVLAN=m
|
||||
CONFIG_MACVTAP=m
|
||||
@@ -319,17 +339,26 @@ CONFIG_VIRTIO_NET=y
|
||||
CONFIG_AMD_XGBE=y
|
||||
CONFIG_NET_XGENE=y
|
||||
CONFIG_ATL1C=m
|
||||
CONFIG_BCMGENET=m
|
||||
CONFIG_BNX2X=m
|
||||
CONFIG_MACB=y
|
||||
CONFIG_THUNDER_NIC_PF=y
|
||||
CONFIG_FEC=y
|
||||
CONFIG_HIX5HD2_GMAC=y
|
||||
CONFIG_HNS_DSAF=y
|
||||
CONFIG_HNS_ENET=y
|
||||
CONFIG_HNS3=y
|
||||
CONFIG_HNS3_HCLGE=y
|
||||
CONFIG_HNS3_ENET=y
|
||||
CONFIG_E1000E=y
|
||||
CONFIG_IGB=y
|
||||
CONFIG_IGBVF=y
|
||||
CONFIG_MVNETA=y
|
||||
CONFIG_MVPP2=y
|
||||
CONFIG_SKY2=y
|
||||
CONFIG_MLX4_EN=m
|
||||
CONFIG_MLX5_CORE=m
|
||||
CONFIG_MLX5_CORE_EN=y
|
||||
CONFIG_QCOM_EMAC=m
|
||||
CONFIG_RAVB=y
|
||||
CONFIG_SMC91X=y
|
||||
@@ -338,7 +367,7 @@ CONFIG_SNI_AVE=y
|
||||
CONFIG_SNI_NETSEC=y
|
||||
CONFIG_STMMAC_ETH=m
|
||||
CONFIG_MDIO_BUS_MUX_MMIOREG=y
|
||||
CONFIG_AT803X_PHY=m
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_MARVELL_PHY=m
|
||||
CONFIG_MARVELL_10G_PHY=m
|
||||
CONFIG_MESON_GXL_PHY=m
|
||||
@@ -349,13 +378,11 @@ CONFIG_PPP=y
|
||||
CONFIG_PPP_BSDCOMP=y
|
||||
CONFIG_PPP_DEFLATE=y
|
||||
CONFIG_PPP_MPPE=y
|
||||
CONFIG_PPTP=y
|
||||
CONFIG_PPPOL2TP=y
|
||||
CONFIG_USB_PEGASUS=m
|
||||
CONFIG_USB_RTL8150=m
|
||||
CONFIG_USB_RTL8152=y
|
||||
CONFIG_USB_RTL8152=m
|
||||
CONFIG_USB_LAN78XX=m
|
||||
CONFIG_USB_USBNET=y
|
||||
CONFIG_USB_USBNET=m
|
||||
CONFIG_USB_NET_DM9601=m
|
||||
CONFIG_USB_NET_SR9800=m
|
||||
CONFIG_USB_NET_SMSC75XX=m
|
||||
@@ -364,41 +391,33 @@ CONFIG_USB_NET_PLUSB=m
|
||||
CONFIG_USB_NET_MCS7830=m
|
||||
CONFIG_ATH10K=m
|
||||
CONFIG_ATH10K_PCI=m
|
||||
CONFIG_ATH10K_SNOC=m
|
||||
CONFIG_BRCMFMAC=m
|
||||
CONFIG_MWIFIEX=m
|
||||
CONFIG_MWIFIEX_PCIE=m
|
||||
CONFIG_WL18XX=m
|
||||
CONFIG_WLCORE_SDIO=m
|
||||
CONFIG_INPUT_JOYDEV=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_KEYBOARD_ADC=m
|
||||
CONFIG_KEYBOARD_GPIO=y
|
||||
CONFIG_KEYBOARD_SNVS_PWRKEY=m
|
||||
CONFIG_KEYBOARD_CROS_EC=y
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
CONFIG_JOYSTICK_XPAD=y
|
||||
CONFIG_JOYSTICK_XPAD_FF=y
|
||||
CONFIG_JOYSTICK_XPAD_LEDS=y
|
||||
CONFIG_INPUT_TABLET=y
|
||||
CONFIG_TABLET_USB_ACECAD=y
|
||||
CONFIG_TABLET_USB_AIPTEK=y
|
||||
CONFIG_TABLET_USB_GTCO=y
|
||||
CONFIG_TABLET_USB_HANWANG=y
|
||||
CONFIG_TABLET_USB_KBTAB=y
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
CONFIG_INPUT_PM8941_PWRKEY=y
|
||||
CONFIG_INPUT_HISI_POWERKEY=y
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
CONFIG_SERIO_AMBAKMI=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVMEM is not set
|
||||
CONFIG_LEGACY_PTY_COUNT=16
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_SHARE_IRQ=y
|
||||
CONFIG_SERIAL_8250_BCM2835AUX=y
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_8250_OMAP=y
|
||||
CONFIG_SERIAL_8250_MT6577=y
|
||||
CONFIG_SERIAL_8250_UNIPHIER=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
@@ -409,42 +428,86 @@ CONFIG_SERIAL_MESON_CONSOLE=y
|
||||
CONFIG_SERIAL_SAMSUNG=y
|
||||
CONFIG_SERIAL_SAMSUNG_CONSOLE=y
|
||||
CONFIG_SERIAL_TEGRA=y
|
||||
CONFIG_SERIAL_TEGRA_TCU=y
|
||||
CONFIG_SERIAL_IMX=y
|
||||
CONFIG_SERIAL_IMX_CONSOLE=y
|
||||
CONFIG_SERIAL_SH_SCI=y
|
||||
CONFIG_SERIAL_MSM=y
|
||||
CONFIG_SERIAL_MSM_CONSOLE=y
|
||||
CONFIG_SERIAL_QCOM_GENI=y
|
||||
CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
|
||||
CONFIG_SERIAL_XILINX_PS_UART=y
|
||||
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
|
||||
CONFIG_SERIAL_FSL_LPUART=y
|
||||
CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
|
||||
CONFIG_SERIAL_FSL_LINFLEXUART=y
|
||||
CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
|
||||
CONFIG_SERIAL_MVEBU_UART=y
|
||||
CONFIG_SERIAL_OWL=y
|
||||
CONFIG_SERIAL_DEV_BUS=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
CONFIG_IPMI_HANDLER=m
|
||||
CONFIG_IPMI_DEVICE_INTERFACE=m
|
||||
CONFIG_IPMI_SI=m
|
||||
CONFIG_TCG_TPM=y
|
||||
CONFIG_TCG_TIS_I2C_INFINEON=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_MUX_PCA954x=y
|
||||
CONFIG_I2C_BCM2835=m
|
||||
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
CONFIG_I2C_GPIO=m
|
||||
CONFIG_I2C_IMX=y
|
||||
CONFIG_I2C_IMX_LPI2C=y
|
||||
CONFIG_I2C_MESON=y
|
||||
CONFIG_I2C_MV64XXX=y
|
||||
CONFIG_I2C_OWL=y
|
||||
CONFIG_I2C_PXA=y
|
||||
CONFIG_I2C_QCOM_GENI=m
|
||||
CONFIG_I2C_QUP=y
|
||||
CONFIG_I2C_RK3X=y
|
||||
CONFIG_I2C_SH_MOBILE=y
|
||||
CONFIG_I2C_TEGRA=y
|
||||
CONFIG_I2C_UNIPHIER_F=y
|
||||
CONFIG_I2C_VERSATILE=y
|
||||
CONFIG_I2C_RCAR=y
|
||||
CONFIG_I2C_CROS_EC_TUNNEL=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_ARMADA_3700=y
|
||||
CONFIG_SPI_BCM2835=m
|
||||
CONFIG_SPI_BCM2835AUX=m
|
||||
CONFIG_SPI_NXP_FLEXSPI=y
|
||||
CONFIG_SPI_IMX=m
|
||||
CONFIG_SPI_MESON_SPICC=m
|
||||
CONFIG_SPI_MESON_SPIFC=m
|
||||
CONFIG_SPI_ORION=y
|
||||
CONFIG_SPI_PL022=y
|
||||
CONFIG_SPI_ROCKCHIP=y
|
||||
CONFIG_SPI_QCOM_QSPI=m
|
||||
CONFIG_SPI_QUP=y
|
||||
CONFIG_SPI_QCOM_GENI=m
|
||||
CONFIG_SPI_S3C64XX=y
|
||||
CONFIG_SPI_SUN6I=y
|
||||
CONFIG_SPI_SPIDEV=m
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_PINCTRL_SINGLE=y
|
||||
CONFIG_PINCTRL_MAX77620=y
|
||||
CONFIG_PINCTRL_OWL=y
|
||||
CONFIG_PINCTRL_S700=y
|
||||
CONFIG_PINCTRL_S900=y
|
||||
CONFIG_PINCTRL_IMX8MM=y
|
||||
CONFIG_PINCTRL_IMX8MN=y
|
||||
CONFIG_PINCTRL_IMX8MQ=y
|
||||
CONFIG_PINCTRL_IMX8QXP=y
|
||||
CONFIG_PINCTRL_IPQ8074=y
|
||||
CONFIG_PINCTRL_MSM8916=y
|
||||
CONFIG_PINCTRL_MSM8994=y
|
||||
CONFIG_PINCTRL_MSM8996=y
|
||||
CONFIG_PINCTRL_MSM8998=y
|
||||
CONFIG_PINCTRL_QCS404=y
|
||||
CONFIG_PINCTRL_QDF2XXX=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_PINCTRL_SDM845=y
|
||||
CONFIG_PINCTRL_SM8150=y
|
||||
CONFIG_GPIO_ALTERA=m
|
||||
CONFIG_GPIO_DWAPB=y
|
||||
CONFIG_GPIO_MB86S7X=y
|
||||
CONFIG_GPIO_PL061=y
|
||||
@@ -452,11 +515,13 @@ CONFIG_GPIO_RCAR=y
|
||||
CONFIG_GPIO_UNIPHIER=y
|
||||
CONFIG_GPIO_XGENE=y
|
||||
CONFIG_GPIO_XGENE_SB=y
|
||||
CONFIG_GPIO_MAX732X=y
|
||||
CONFIG_GPIO_PCA953X=y
|
||||
CONFIG_GPIO_PCA953X_IRQ=y
|
||||
CONFIG_GPIO_MAX77620=y
|
||||
CONFIG_POWER_AVS=y
|
||||
CONFIG_ROCKCHIP_IODOMAIN=y
|
||||
CONFIG_POWER_RESET_MSM=y
|
||||
CONFIG_POWER_RESET_XGENE=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_SYSCON_REBOOT_MODE=y
|
||||
@@ -464,38 +529,73 @@ CONFIG_BATTERY_SBS=m
|
||||
CONFIG_BATTERY_BQ27XXX=y
|
||||
CONFIG_SENSORS_ARM_SCPI=y
|
||||
CONFIG_SENSORS_LM90=m
|
||||
CONFIG_SENSORS_PWM_FAN=m
|
||||
CONFIG_SENSORS_RASPBERRYPI_HWMON=m
|
||||
CONFIG_SENSORS_INA2XX=m
|
||||
CONFIG_SENSORS_INA3221=m
|
||||
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_THERMAL_EMULATION=y
|
||||
CONFIG_QORIQ_THERMAL=m
|
||||
CONFIG_ROCKCHIP_THERMAL=m
|
||||
CONFIG_RCAR_THERMAL=y
|
||||
CONFIG_RCAR_GEN3_THERMAL=y
|
||||
CONFIG_ARMADA_THERMAL=y
|
||||
CONFIG_BCM2835_THERMAL=m
|
||||
CONFIG_BRCMSTB_THERMAL=m
|
||||
CONFIG_EXYNOS_THERMAL=y
|
||||
CONFIG_TEGRA_BPMP_THERMAL=m
|
||||
CONFIG_QCOM_TSENS=y
|
||||
CONFIG_QCOM_SPMI_TEMP_ALARM=m
|
||||
CONFIG_UNIPHIER_THERMAL=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_ARM_SP805_WATCHDOG=y
|
||||
CONFIG_S3C2410_WATCHDOG=y
|
||||
CONFIG_DW_WATCHDOG=y
|
||||
CONFIG_SUNXI_WATCHDOG=m
|
||||
CONFIG_IMX2_WDT=y
|
||||
CONFIG_IMX_SC_WDT=m
|
||||
CONFIG_QCOM_WDT=m
|
||||
CONFIG_MESON_GXBB_WATCHDOG=m
|
||||
CONFIG_MESON_WATCHDOG=m
|
||||
CONFIG_RENESAS_WDT=y
|
||||
CONFIG_UNIPHIER_WATCHDOG=y
|
||||
CONFIG_BCM2835_WDT=y
|
||||
CONFIG_MFD_ALTERA_SYSMGR=y
|
||||
CONFIG_MFD_BD9571MWV=y
|
||||
CONFIG_MFD_AXP20X_I2C=y
|
||||
CONFIG_MFD_AXP20X_RSB=y
|
||||
CONFIG_MFD_EXYNOS_LPASS=m
|
||||
CONFIG_MFD_HI6421_PMIC=y
|
||||
CONFIG_MFD_HI655X_PMIC=y
|
||||
CONFIG_MFD_MAX77620=y
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_MFD_RK808=y
|
||||
CONFIG_MFD_SEC_CORE=y
|
||||
CONFIG_MFD_ROHM_BD718XX=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_AXP20X=y
|
||||
CONFIG_REGULATOR_BD718XX=y
|
||||
CONFIG_REGULATOR_BD9571MWV=y
|
||||
CONFIG_REGULATOR_FAN53555=y
|
||||
CONFIG_REGULATOR_GPIO=y
|
||||
CONFIG_REGULATOR_HI6421V530=y
|
||||
CONFIG_REGULATOR_HI655X=y
|
||||
CONFIG_REGULATOR_MAX77620=y
|
||||
CONFIG_REGULATOR_MAX8973=y
|
||||
CONFIG_REGULATOR_PFUZE100=y
|
||||
CONFIG_REGULATOR_PWM=y
|
||||
CONFIG_REGULATOR_QCOM_RPMH=y
|
||||
CONFIG_REGULATOR_QCOM_SMD_RPM=y
|
||||
CONFIG_REGULATOR_QCOM_SPMI=y
|
||||
CONFIG_REGULATOR_RK808=y
|
||||
CONFIG_REGULATOR_S2MPS11=y
|
||||
CONFIG_REGULATOR_VCTRL=m
|
||||
CONFIG_RC_CORE=m
|
||||
CONFIG_RC_DECODERS=y
|
||||
CONFIG_RC_DEVICES=y
|
||||
CONFIG_IR_MESON=m
|
||||
CONFIG_IR_SUNXI=m
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
|
||||
@@ -505,17 +605,23 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y
|
||||
# CONFIG_DVB_NET is not set
|
||||
CONFIG_MEDIA_USB_SUPPORT=y
|
||||
CONFIG_USB_VIDEO_CLASS=m
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_VIDEO_SUN6I_CSI=m
|
||||
CONFIG_V4L_MEM2MEM_DRIVERS=y
|
||||
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
|
||||
CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
|
||||
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
|
||||
CONFIG_VIDEO_RENESAS_FCP=m
|
||||
CONFIG_VIDEO_RENESAS_VSP1=m
|
||||
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
|
||||
CONFIG_DRM_I2C_NXP_TDA998X=y
|
||||
CONFIG_DRM_I2C_CH7006=m
|
||||
CONFIG_DRM_I2C_SIL164=m
|
||||
CONFIG_DRM_I2C_NXP_TDA998X=m
|
||||
CONFIG_DRM_HDLCD=y
|
||||
CONFIG_DRM_NOUVEAU=m
|
||||
CONFIG_DRM_KOMEDA=y
|
||||
CONFIG_DRM_VIRT_ENCODER=y
|
||||
CONFIG_DRM_EXYNOS=m
|
||||
CONFIG_DRM_EXYNOS5433_DECON=y
|
||||
CONFIG_DRM_EXYNOS7_DECON=y
|
||||
@@ -530,14 +636,26 @@ CONFIG_ROCKCHIP_DW_HDMI=y
|
||||
CONFIG_ROCKCHIP_DW_MIPI_DSI=y
|
||||
CONFIG_ROCKCHIP_INNO_HDMI=y
|
||||
CONFIG_DRM_RCAR_DU=m
|
||||
CONFIG_DRM_SUN4I=m
|
||||
CONFIG_DRM_SUN8I_DW_HDMI=m
|
||||
CONFIG_DRM_SUN8I_MIXER=m
|
||||
CONFIG_DRM_MSM=m
|
||||
CONFIG_DRM_TEGRA=m
|
||||
CONFIG_DRM_PANEL_SIMPLE=m
|
||||
CONFIG_DRM_SII902X=m
|
||||
CONFIG_DRM_TI_SN65DSI86=m
|
||||
CONFIG_DRM_I2C_ADV7511=m
|
||||
CONFIG_DRM_VC4=m
|
||||
CONFIG_DRM_ETNAVIV=m
|
||||
CONFIG_DRM_HISI_HIBMC=m
|
||||
CONFIG_DRM_HISI_KIRIN=m
|
||||
CONFIG_DRM_MESON=m
|
||||
CONFIG_FB_ARMCLCD=y
|
||||
CONFIG_DRM_PL111=m
|
||||
CONFIG_DRM_LIMA=m
|
||||
CONFIG_DRM_PANFROST=m
|
||||
CONFIG_DRM_LEGACY=y
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
CONFIG_FB_EFI=y
|
||||
CONFIG_BACKLIGHT_GENERIC=m
|
||||
CONFIG_BACKLIGHT_PWM=m
|
||||
CONFIG_BACKLIGHT_LP855X=m
|
||||
@@ -547,78 +665,41 @@ CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_VGA16 is not set
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_HDA_TEGRA=m
|
||||
CONFIG_SND_HDA_CODEC_HDMI=m
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_BCM2835_SOC_I2S=m
|
||||
CONFIG_SND_MESON_AXG_SOUND_CARD=m
|
||||
CONFIG_SND_SOC_ROCKCHIP=m
|
||||
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
|
||||
CONFIG_SND_SOC_ROCKCHIP_RT5645=m
|
||||
CONFIG_SND_SOC_RK3399_GRU_SOUND=m
|
||||
CONFIG_SND_SOC_SAMSUNG=y
|
||||
CONFIG_SND_SOC_RCAR=m
|
||||
CONFIG_SND_SUN4I_SPDIF=m
|
||||
CONFIG_SND_SOC_AK4613=m
|
||||
CONFIG_SND_SOC_ES7134=m
|
||||
CONFIG_SND_SOC_ES7241=m
|
||||
CONFIG_SND_SOC_PCM3168A_I2C=m
|
||||
CONFIG_SND_SOC_TAS571X=m
|
||||
CONFIG_SND_SIMPLE_CARD=m
|
||||
CONFIG_SND_AUDIO_GRAPH_CARD=m
|
||||
CONFIG_HIDRAW=y
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_A4TECH=y
|
||||
CONFIG_HID_ACRUX=y
|
||||
CONFIG_HID_ACRUX_FF=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_BELKIN=y
|
||||
CONFIG_HID_CHERRY=y
|
||||
CONFIG_HID_CHICONY=y
|
||||
CONFIG_HID_PRODIKEYS=y
|
||||
CONFIG_HID_CYPRESS=y
|
||||
CONFIG_HID_DRAGONRISE=y
|
||||
CONFIG_DRAGONRISE_FF=y
|
||||
CONFIG_HID_EMS_FF=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
CONFIG_HID_EZKEY=y
|
||||
CONFIG_HID_HOLTEK=y
|
||||
CONFIG_HID_KEYTOUCH=y
|
||||
CONFIG_HID_KYE=y
|
||||
CONFIG_HID_UCLOGIC=y
|
||||
CONFIG_HID_WALTOP=y
|
||||
CONFIG_HID_GYRATION=y
|
||||
CONFIG_HID_TWINHAN=y
|
||||
CONFIG_HID_ITE=y
|
||||
CONFIG_HID_KENSINGTON=y
|
||||
CONFIG_HID_LCPOWER=y
|
||||
CONFIG_HID_LOGITECH=y
|
||||
CONFIG_HID_LOGITECH_DJ=y
|
||||
CONFIG_LOGITECH_FF=y
|
||||
CONFIG_LOGIRUMBLEPAD2_FF=y
|
||||
CONFIG_LOGIG940_FF=y
|
||||
CONFIG_HID_MAGICMOUSE=y
|
||||
CONFIG_HID_REDRAGON=y
|
||||
CONFIG_HID_MICROSOFT=y
|
||||
CONFIG_HID_MONTEREY=y
|
||||
CONFIG_HID_MULTITOUCH=y
|
||||
CONFIG_HID_NTRIG=y
|
||||
CONFIG_HID_ORTEK=y
|
||||
CONFIG_HID_PANTHERLORD=y
|
||||
CONFIG_PANTHERLORD_FF=y
|
||||
CONFIG_HID_PETALYNX=y
|
||||
CONFIG_HID_PICOLCD=y
|
||||
CONFIG_HID_PRIMAX=y
|
||||
CONFIG_HID_ROCCAT=y
|
||||
CONFIG_HID_SAITEK=y
|
||||
CONFIG_HID_SAMSUNG=y
|
||||
CONFIG_HID_SONY=y
|
||||
CONFIG_HID_SPEEDLINK=y
|
||||
CONFIG_HID_SUNPLUS=y
|
||||
CONFIG_HID_GREENASIA=y
|
||||
CONFIG_GREENASIA_FF=y
|
||||
CONFIG_HID_SMARTJOYPLUS=y
|
||||
CONFIG_SMARTJOYPLUS_FF=y
|
||||
CONFIG_HID_TIVO=y
|
||||
CONFIG_HID_TOPSEED=y
|
||||
CONFIG_HID_THRUSTMASTER=y
|
||||
CONFIG_HID_WACOM=y
|
||||
CONFIG_HID_WIIMOTE=y
|
||||
CONFIG_HID_ZEROPLUS=y
|
||||
CONFIG_HID_ZYDACRON=y
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_I2C_HID=m
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_CONN_GPIO=m
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_OTG=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_TEGRA=y
|
||||
@@ -640,16 +721,15 @@ CONFIG_USB_CHIPIDEA_HOST=y
|
||||
CONFIG_USB_ISP1760=y
|
||||
CONFIG_USB_HSIC_USB3503=y
|
||||
CONFIG_NOP_USB_XCEIV=y
|
||||
CONFIG_USB_ULPI=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_RENESAS_USBHS_UDC=m
|
||||
CONFIG_USB_RENESAS_USB3=m
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
CONFIG_USB_CONFIGFS_UEVENT=y
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
CONFIG_USB_CONFIGFS_F_ACC=y
|
||||
CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
|
||||
CONFIG_USB_CONFIGFS_F_MIDI=y
|
||||
CONFIG_TYPEC=m
|
||||
CONFIG_TYPEC_TCPM=m
|
||||
CONFIG_TYPEC_FUSB302=m
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK_MINORS=32
|
||||
CONFIG_MMC_ARMMMCI=y
|
||||
@@ -659,11 +739,14 @@ CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_OF_ARASAN=y
|
||||
CONFIG_MMC_SDHCI_OF_ESDHC=y
|
||||
CONFIG_MMC_SDHCI_CADENCE=y
|
||||
CONFIG_MMC_SDHCI_ESDHC_IMX=y
|
||||
CONFIG_MMC_SDHCI_TEGRA=y
|
||||
CONFIG_MMC_SDHCI_F_SDH30=y
|
||||
CONFIG_MMC_MESON_GX=y
|
||||
CONFIG_MMC_SDHCI_MSM=y
|
||||
CONFIG_MMC_SPI=y
|
||||
CONFIG_MMC_SDHI=y
|
||||
CONFIG_MMC_UNIPHIER=y
|
||||
CONFIG_MMC_DW=y
|
||||
CONFIG_MMC_DW_EXYNOS=y
|
||||
CONFIG_MMC_DW_HI3798CV200=y
|
||||
@@ -672,6 +755,8 @@ CONFIG_MMC_DW_ROCKCHIP=y
|
||||
CONFIG_MMC_SUNXI=y
|
||||
CONFIG_MMC_BCM2835=y
|
||||
CONFIG_MMC_SDHCI_XENON=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
CONFIG_LEDS_PWM=y
|
||||
CONFIG_LEDS_SYSCON=y
|
||||
@@ -685,6 +770,7 @@ CONFIG_EDAC_GHES=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_MAX77686=y
|
||||
CONFIG_RTC_DRV_RK808=m
|
||||
CONFIG_RTC_DRV_RX8581=m
|
||||
CONFIG_RTC_DRV_S5M=y
|
||||
CONFIG_RTC_DRV_DS3232=y
|
||||
CONFIG_RTC_DRV_EFI=y
|
||||
@@ -694,13 +780,21 @@ CONFIG_RTC_DRV_PL031=y
|
||||
CONFIG_RTC_DRV_SUN6I=y
|
||||
CONFIG_RTC_DRV_ARMADA38X=y
|
||||
CONFIG_RTC_DRV_TEGRA=y
|
||||
CONFIG_RTC_DRV_SNVS=m
|
||||
CONFIG_RTC_DRV_IMX_SC=m
|
||||
CONFIG_RTC_DRV_XGENE=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_BCM2835=m
|
||||
CONFIG_DMA_SUN6I=m
|
||||
CONFIG_FSL_EDMA=y
|
||||
CONFIG_IMX_SDMA=y
|
||||
CONFIG_K3_DMA=y
|
||||
CONFIG_MV_XOR=y
|
||||
CONFIG_MV_XOR_V2=y
|
||||
CONFIG_OWL_DMA=y
|
||||
CONFIG_PL330_DMA=y
|
||||
CONFIG_TEGRA20_APB_DMA=y
|
||||
CONFIG_QCOM_BAM_DMA=y
|
||||
CONFIG_QCOM_HIDMA_MGMT=y
|
||||
CONFIG_QCOM_HIDMA=y
|
||||
CONFIG_RCAR_DMAC=y
|
||||
@@ -715,26 +809,73 @@ CONFIG_XEN_GRANT_DEV_ALLOC=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_ASHMEM=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_ION_SYSTEM_HEAP=y
|
||||
CONFIG_MFD_CROS_EC=y
|
||||
CONFIG_CROS_EC_I2C=y
|
||||
CONFIG_CROS_EC_SPI=y
|
||||
CONFIG_COMMON_CLK_RK808=y
|
||||
CONFIG_COMMON_CLK_SCMI=y
|
||||
CONFIG_COMMON_CLK_SCPI=y
|
||||
CONFIG_COMMON_CLK_CS2000_CP=y
|
||||
CONFIG_COMMON_CLK_S2MPS11=y
|
||||
CONFIG_CLK_QORIQ=y
|
||||
CONFIG_COMMON_CLK_PWM=y
|
||||
CONFIG_CLK_RASPBERRYPI=m
|
||||
CONFIG_CLK_IMX8MM=y
|
||||
CONFIG_CLK_IMX8MN=y
|
||||
CONFIG_CLK_IMX8MQ=y
|
||||
CONFIG_CLK_IMX8QXP=y
|
||||
CONFIG_TI_SCI_CLK=y
|
||||
CONFIG_COMMON_CLK_QCOM=y
|
||||
CONFIG_QCOM_A53PLL=y
|
||||
CONFIG_QCOM_CLK_APCS_MSM8916=y
|
||||
CONFIG_QCOM_CLK_SMD_RPM=y
|
||||
CONFIG_QCOM_CLK_RPMH=y
|
||||
CONFIG_IPQ_GCC_8074=y
|
||||
CONFIG_MSM_GCC_8916=y
|
||||
CONFIG_MSM_GCC_8994=y
|
||||
CONFIG_MSM_MMCC_8996=y
|
||||
CONFIG_MSM_GCC_8998=y
|
||||
CONFIG_QCS_GCC_404=y
|
||||
CONFIG_SDM_GCC_845=y
|
||||
CONFIG_SM_GCC_8150=y
|
||||
CONFIG_QCOM_HFPLL=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_QCOM=y
|
||||
CONFIG_ARM_MHU=y
|
||||
CONFIG_IMX_MBOX=y
|
||||
CONFIG_ARM_MHU_V2=y
|
||||
CONFIG_PLATFORM_MHU=y
|
||||
CONFIG_BCM2835_MBOX=y
|
||||
CONFIG_QCOM_APCS_IPC=y
|
||||
CONFIG_ROCKCHIP_IOMMU=y
|
||||
CONFIG_TEGRA_IOMMU_SMMU=y
|
||||
CONFIG_ARM_SMMU=m
|
||||
CONFIG_ARM_SMMU_V3=y
|
||||
CONFIG_REMOTEPROC=y
|
||||
CONFIG_QCOM_Q6V5_MSS=m
|
||||
CONFIG_QCOM_Q6V5_PAS=m
|
||||
CONFIG_QCOM_SYSMON=m
|
||||
CONFIG_RPMSG_QCOM_GLINK_RPM=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_SMEM=m
|
||||
CONFIG_RPMSG_QCOM_SMD=y
|
||||
CONFIG_OWL_PM_DOMAINS=y
|
||||
CONFIG_RASPBERRYPI_POWER=y
|
||||
CONFIG_IMX_SCU_SOC=y
|
||||
CONFIG_QCOM_AOSS_QMP=y
|
||||
CONFIG_QCOM_GENI_SE=y
|
||||
CONFIG_QCOM_GLINK_SSR=m
|
||||
CONFIG_QCOM_RMTFS_MEM=m
|
||||
CONFIG_QCOM_RPMH=y
|
||||
CONFIG_QCOM_RPMHPD=y
|
||||
CONFIG_QCOM_SMEM=y
|
||||
CONFIG_QCOM_SMD_RPM=y
|
||||
CONFIG_QCOM_SMP2P=y
|
||||
CONFIG_QCOM_SMSM=y
|
||||
CONFIG_QCOM_SOCINFO=m
|
||||
CONFIG_ARCH_R8A774A1=y
|
||||
CONFIG_ARCH_R8A774C0=y
|
||||
CONFIG_ARCH_R8A7795=y
|
||||
CONFIG_ARCH_R8A7796=y
|
||||
CONFIG_ARCH_R8A77965=y
|
||||
CONFIG_ARCH_R8A77970=y
|
||||
CONFIG_ARCH_R8A77980=y
|
||||
@@ -746,17 +887,21 @@ CONFIG_ARCH_TEGRA_210_SOC=y
|
||||
CONFIG_ARCH_TEGRA_186_SOC=y
|
||||
CONFIG_ARCH_TEGRA_194_SOC=y
|
||||
CONFIG_ARCH_K3_AM6_SOC=y
|
||||
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
|
||||
CONFIG_ARCH_K3_J721E_SOC=y
|
||||
CONFIG_TI_SCI_PM_DOMAINS=y
|
||||
CONFIG_EXTCON_USB_GPIO=y
|
||||
CONFIG_EXTCON_USBC_CROS_EC=y
|
||||
CONFIG_MEMORY=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_EXYNOS_ADC=y
|
||||
CONFIG_QCOM_SPMI_ADC5=m
|
||||
CONFIG_ROCKCHIP_SARADC=m
|
||||
CONFIG_IIO_CROS_EC_SENSORS_CORE=m
|
||||
CONFIG_IIO_CROS_EC_SENSORS=m
|
||||
CONFIG_IIO_CROS_EC_LIGHT_PROX=m
|
||||
CONFIG_SENSORS_ISL29018=m
|
||||
CONFIG_IIO_CROS_EC_BARO=m
|
||||
CONFIG_MPL3115=m
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_BCM2835=m
|
||||
CONFIG_PWM_CROS_EC=m
|
||||
@@ -764,27 +909,51 @@ CONFIG_PWM_MESON=m
|
||||
CONFIG_PWM_RCAR=m
|
||||
CONFIG_PWM_ROCKCHIP=y
|
||||
CONFIG_PWM_SAMSUNG=y
|
||||
CONFIG_PWM_SUN4I=m
|
||||
CONFIG_PWM_TEGRA=m
|
||||
CONFIG_RESET_QCOM_AOSS=y
|
||||
CONFIG_RESET_QCOM_PDC=m
|
||||
CONFIG_RESET_TI_SCI=y
|
||||
CONFIG_PHY_XGENE=y
|
||||
CONFIG_PHY_SUN4I_USB=y
|
||||
CONFIG_PHY_HI6220_USB=y
|
||||
CONFIG_PHY_HISTB_COMBPHY=y
|
||||
CONFIG_PHY_HISI_INNO_USB2=y
|
||||
CONFIG_PHY_MVEBU_CP110_COMPHY=y
|
||||
CONFIG_PHY_QCOM_QMP=m
|
||||
CONFIG_PHY_QCOM_QUSB2=m
|
||||
CONFIG_PHY_QCOM_USB_HS=y
|
||||
CONFIG_PHY_RCAR_GEN3_PCIE=y
|
||||
CONFIG_PHY_RCAR_GEN3_USB2=y
|
||||
CONFIG_PHY_RCAR_GEN3_USB3=m
|
||||
CONFIG_PHY_ROCKCHIP_EMMC=y
|
||||
CONFIG_PHY_ROCKCHIP_INNO_HDMI=m
|
||||
CONFIG_PHY_ROCKCHIP_INNO_USB2=y
|
||||
CONFIG_PHY_ROCKCHIP_PCIE=m
|
||||
CONFIG_PHY_ROCKCHIP_TYPEC=y
|
||||
CONFIG_PHY_UNIPHIER_USB2=y
|
||||
CONFIG_PHY_UNIPHIER_USB3=y
|
||||
CONFIG_PHY_TEGRA_XUSB=y
|
||||
CONFIG_ARM_SMMU_V3_PMU=m
|
||||
CONFIG_FSL_IMX8_DDR_PMU=m
|
||||
CONFIG_HISI_PMU=y
|
||||
CONFIG_QCOM_L2_PMU=y
|
||||
CONFIG_QCOM_L3_PMU=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_NVMEM_IMX_OCOTP=y
|
||||
CONFIG_NVMEM_IMX_OCOTP_SCU=y
|
||||
CONFIG_QCOM_QFPROM=y
|
||||
CONFIG_ROCKCHIP_EFUSE=y
|
||||
CONFIG_NVMEM_SUNXI_SID=y
|
||||
CONFIG_UNIPHIER_EFUSE=y
|
||||
CONFIG_MESON_EFUSE=m
|
||||
CONFIG_FPGA=y
|
||||
CONFIG_FPGA_MGR_STRATIX10_SOC=m
|
||||
CONFIG_FPGA_BRIDGE=m
|
||||
CONFIG_ALTERA_FREEZE_BRIDGE=m
|
||||
CONFIG_FPGA_REGION=m
|
||||
CONFIG_OF_FPGA_REGION=m
|
||||
CONFIG_TEE=y
|
||||
CONFIG_OPTEE=y
|
||||
CONFIG_EXT2_FS=y
|
||||
@@ -793,23 +962,23 @@ CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_BTRFS_FS=m
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_F2FS_FS=y
|
||||
CONFIG_F2FS_FS_SECURITY=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QFMT_V2=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=m
|
||||
CONFIG_OVERLAY_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_OVERLAY_FS=m
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_EFIVAR_FS=y
|
||||
CONFIG_SQUASHFS=y
|
||||
CONFIG_PSTORE_CONSOLE=y
|
||||
CONFIG_PSTORE_RAM=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V4=y
|
||||
CONFIG_NFS_V4_1=y
|
||||
CONFIG_NFS_V4_2=y
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_9P_FS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
@@ -817,16 +986,17 @@ CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_HARDENED_USERCOPY=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_CRYPTO_GCM=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_ANSI_CPRNG=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_CMA_SIZE_MBYTES=32
|
||||
CONFIG_CRYPTO_USER_API_RNG=m
|
||||
CONFIG_CRYPTO_DEV_FSL_CAAM=m
|
||||
CONFIG_CRYPTO_DEV_QCOM_RNG=m
|
||||
CONFIG_CRYPTO_DEV_HISI_ZIP=m
|
||||
CONFIG_CMA_SIZE_MBYTES=256
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_PANIC_TIMEOUT=5
|
||||
CONFIG_SCHEDSTATS=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
CONFIG_ENABLE_DEFAULT_TRACERS=y
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_MEMTEST=y
|
||||
@@ -1,3 +1,5 @@
|
||||
# Machine specific configurations
|
||||
|
||||
FILESEXTRAPATHS_prepend := "${THISDIR}/${BP}:"
|
||||
|
||||
require linux-arm-platforms.inc
|
||||
|
||||
Reference in New Issue
Block a user