mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
update meson patches for 6.9 kernel
This commit is contained in:
@@ -4893,6 +4893,7 @@ CONFIG_DRM_DW_HDMI=y
|
||||
# CONFIG_DRM_LOGICVC is not set
|
||||
CONFIG_DRM_MESON=y
|
||||
CONFIG_DRM_MESON_DW_HDMI=y
|
||||
CONFIG_DRM_MESON_TRANSWITCH_HDMI=y
|
||||
# CONFIG_DRM_MESON_DW_MIPI_DSI is not set
|
||||
# CONFIG_DRM_ARCPGU is not set
|
||||
# CONFIG_DRM_BOCHS is not set
|
||||
@@ -6910,6 +6911,7 @@ CONFIG_GENERIC_PHY=y
|
||||
# CONFIG_PHY_CAN_TRANSCEIVER is not set
|
||||
CONFIG_PHY_MESON8_HDMI_TX=y
|
||||
CONFIG_PHY_MESON8B_USB2=y
|
||||
CONFIG_PHY_MESON_CVBS_DAC=y
|
||||
# CONFIG_PHY_MESON_GXL_USB2 is not set
|
||||
# CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG is not set
|
||||
# CONFIG_PHY_MESON_G12A_USB2 is not set
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From 85409ae3c08b4b1aedc80d35f0afd6832cfe5d1f Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Wed, 16 Jun 2021 20:34:01 +0200
|
||||
Subject: [PATCH 07/96] dt-bindings: phy: meson8b-usb2: Add support for reading
|
||||
the ID signal
|
||||
|
||||
The first USB PHY on Amlogic Meson8/8b/8m2/GXBB SoCs is OTG capable.
|
||||
This means that the USB "ID" signal is routed to the PHY. Add support
|
||||
for the gpio-controller and #gpio-cells properties so the value of
|
||||
the "ID" signal can be read as a GPIO (from the PHY) for example by
|
||||
an "gpio-usb-b-connector".
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../bindings/phy/amlogic,meson8b-usb2-phy.yaml | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson8b-usb2-phy.yaml b/Documentation/devicetree/bindings/phy/amlogic,meson8b-usb2-phy.yaml
|
||||
index df68bfe5f..be722a235 100644
|
||||
--- a/Documentation/devicetree/bindings/phy/amlogic,meson8b-usb2-phy.yaml
|
||||
+++ b/Documentation/devicetree/bindings/phy/amlogic,meson8b-usb2-phy.yaml
|
||||
@@ -6,6 +6,10 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Meson8, Meson8b, Meson8m2 and GXBB USB2 PHY
|
||||
|
||||
+description: |
|
||||
+ OTG capable PHYs have the USB "ID" signal routed to them.
|
||||
+ This can be read out via the PHY-provided GPIO controller.
|
||||
+
|
||||
maintainers:
|
||||
- Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
|
||||
@@ -31,6 +35,11 @@ properties:
|
||||
- const: usb_general
|
||||
- const: usb
|
||||
|
||||
+ '#gpio-cells':
|
||||
+ const: 2
|
||||
+
|
||||
+ gpio-controller: true
|
||||
+
|
||||
resets:
|
||||
minItems: 1
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
From fa852523a5da72615695668ef4d354b6af2cae83 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sun, 3 May 2020 21:40:27 +0200
|
||||
Subject: [PATCH 08/96] phy: amlogic: meson8b-usb2: Add support for reading the
|
||||
"ID" signal
|
||||
|
||||
The first USB PHY on Amlogic Meson8/8b/8m2/GXBB SoCs is OTG capable.
|
||||
This means that the USB "ID" signal is routed to the PHY. Add support
|
||||
for the gpio-controller and #gpio-cells properties so the value of
|
||||
the "ID" signal can be read as a GPIO (from the PHY) for example by
|
||||
the usb-conn-gpio driver.
|
||||
|
||||
The registers also have a bit for the VBUS signal. That either is not
|
||||
wired in hardware inside the SoC silicon or not wired on the boards
|
||||
(e.g. Odroid-C1), which is why it's value is not exposed for now.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/phy/amlogic/phy-meson8b-usb2.c | 42 +++++++++++++++++++++++++-
|
||||
1 file changed, 41 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
|
||||
index d63147c41..d3d0bd367 100644
|
||||
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
|
||||
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
+#include <linux/gpio/driver.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
@@ -127,6 +128,7 @@ struct phy_meson8b_usb2_priv {
|
||||
struct clk *clk_usb_general;
|
||||
struct clk *clk_usb;
|
||||
struct reset_control *reset;
|
||||
+ struct gpio_chip gpiochip;
|
||||
const struct phy_meson8b_usb2_match_data *match;
|
||||
};
|
||||
|
||||
@@ -236,12 +238,44 @@ static const struct phy_ops phy_meson8b_usb2_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
+static int phy_meson8b_usb2_id_gpio_get_direction(struct gpio_chip *gc,
|
||||
+ unsigned int offset)
|
||||
+{
|
||||
+ return GPIO_LINE_DIRECTION_IN;
|
||||
+}
|
||||
+
|
||||
+static int phy_meson8b_usb2_id_gpio_get_value(struct gpio_chip *gc,
|
||||
+ unsigned int offset)
|
||||
+{
|
||||
+ struct phy_meson8b_usb2_priv *priv = gpiochip_get_data(gc);
|
||||
+ unsigned int val;
|
||||
+
|
||||
+ regmap_read(priv->regmap, REG_ADP_BC, &val);
|
||||
+
|
||||
+ return (val & REG_ADP_BC_ID_DIG) ? 1 : 0;
|
||||
+}
|
||||
+
|
||||
+static int phy_meson8b_usb2_id_gpiochip_add(struct device *dev,
|
||||
+ struct phy_meson8b_usb2_priv *priv)
|
||||
+{
|
||||
+ priv->gpiochip.label = dev_name(dev);
|
||||
+ priv->gpiochip.parent = dev;
|
||||
+ priv->gpiochip.get_direction = phy_meson8b_usb2_id_gpio_get_direction;
|
||||
+ priv->gpiochip.get = phy_meson8b_usb2_id_gpio_get_value;
|
||||
+ priv->gpiochip.of_gpio_n_cells = 2;
|
||||
+ priv->gpiochip.base = -1;
|
||||
+ priv->gpiochip.ngpio = 1;
|
||||
+
|
||||
+ return devm_gpiochip_add_data(dev, &priv->gpiochip, priv);
|
||||
+}
|
||||
+
|
||||
static int phy_meson8b_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_meson8b_usb2_priv *priv;
|
||||
- struct phy *phy;
|
||||
struct phy_provider *phy_provider;
|
||||
void __iomem *base;
|
||||
+ struct phy *phy;
|
||||
+ int ret;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
@@ -280,6 +314,12 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (device_property_read_bool(&pdev->dev, "gpio-controller")) {
|
||||
+ ret = phy_meson8b_usb2_id_gpiochip_add(&pdev->dev, priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(phy),
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
From 8d8783f1098d154b6beb13fb694cf932dbf43e43 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Wed, 16 Jun 2021 21:07:50 +0200
|
||||
Subject: [PATCH 09/96] usb: common: usb-conn-gpio: Fall back to polling the
|
||||
GPIO
|
||||
|
||||
On some SoCs (for example: Amlogic Meson8/8b/8m2 and GXBB) the ID GPIO
|
||||
cannot generate an interrupt. Fall back to polling the GPIO(s) in that
|
||||
case.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/usb/common/usb-conn-gpio.c | 76 +++++++++++++++++++-----------
|
||||
1 file changed, 48 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c
|
||||
index 501e8bc97..b0b19e026 100644
|
||||
--- a/drivers/usb/common/usb-conn-gpio.c
|
||||
+++ b/drivers/usb/common/usb-conn-gpio.c
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#define USB_GPIO_DEB_MS 20 /* ms */
|
||||
#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */
|
||||
+#define USB_GPIO_POLL_MS 1000
|
||||
|
||||
#define USB_CONN_IRQF \
|
||||
(IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT)
|
||||
@@ -45,6 +46,23 @@ struct usb_conn_info {
|
||||
bool initial_detection;
|
||||
};
|
||||
|
||||
+static void usb_conn_queue_dwork(struct usb_conn_info *info,
|
||||
+ unsigned long delay)
|
||||
+{
|
||||
+ queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay);
|
||||
+}
|
||||
+
|
||||
+static void usb_conn_gpio_start_polling(struct usb_conn_info *info)
|
||||
+{
|
||||
+ usb_conn_queue_dwork(info, msecs_to_jiffies(USB_GPIO_POLL_MS));
|
||||
+}
|
||||
+
|
||||
+static bool usb_conn_gpio_needs_polling(struct usb_conn_info *info)
|
||||
+{
|
||||
+ /* We need to poll if one of the GPIOs cannot generate an IRQ. */
|
||||
+ return info->id_irq < 0 || info->vbus_irq < 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* "DEVICE" = VBUS and "HOST" = !ID, so we have:
|
||||
* Both "DEVICE" and "HOST" can't be set as active at the same time
|
||||
@@ -88,7 +106,10 @@ static void usb_conn_detect_cable(struct work_struct *work)
|
||||
usb_role_string(info->last_role), usb_role_string(role), id, vbus);
|
||||
|
||||
if (!info->initial_detection && info->last_role == role) {
|
||||
- dev_warn(info->dev, "repeated role: %s\n", usb_role_string(role));
|
||||
+ if (usb_conn_gpio_needs_polling(info))
|
||||
+ usb_conn_gpio_start_polling(info);
|
||||
+ else
|
||||
+ dev_warn(info->dev, "repeated role: %s\n", usb_role_string(role));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -114,12 +135,9 @@ static void usb_conn_detect_cable(struct work_struct *work)
|
||||
regulator_is_enabled(info->vbus) ? "enabled" : "disabled");
|
||||
|
||||
power_supply_changed(info->charger);
|
||||
-}
|
||||
|
||||
-static void usb_conn_queue_dwork(struct usb_conn_info *info,
|
||||
- unsigned long delay)
|
||||
-{
|
||||
- queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay);
|
||||
+ if (usb_conn_gpio_needs_polling(info))
|
||||
+ usb_conn_gpio_start_polling(info);
|
||||
}
|
||||
|
||||
static irqreturn_t usb_conn_isr(int irq, void *dev_id)
|
||||
@@ -226,34 +244,34 @@ static int usb_conn_probe(struct platform_device *pdev)
|
||||
if (info->id_gpiod) {
|
||||
info->id_irq = gpiod_to_irq(info->id_gpiod);
|
||||
if (info->id_irq < 0) {
|
||||
- dev_err(dev, "failed to get ID IRQ\n");
|
||||
- ret = info->id_irq;
|
||||
- goto put_role_sw;
|
||||
- }
|
||||
-
|
||||
- ret = devm_request_threaded_irq(dev, info->id_irq, NULL,
|
||||
- usb_conn_isr, USB_CONN_IRQF,
|
||||
- pdev->name, info);
|
||||
- if (ret < 0) {
|
||||
- dev_err(dev, "failed to request ID IRQ\n");
|
||||
- goto put_role_sw;
|
||||
+ dev_info(dev,
|
||||
+ "failed to get ID IRQ - falling back to polling\n");
|
||||
+ } else {
|
||||
+ ret = devm_request_threaded_irq(dev, info->id_irq,
|
||||
+ NULL, usb_conn_isr,
|
||||
+ USB_CONN_IRQF,
|
||||
+ pdev->name, info);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "failed to request ID IRQ\n");
|
||||
+ goto put_role_sw;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
if (info->vbus_gpiod) {
|
||||
info->vbus_irq = gpiod_to_irq(info->vbus_gpiod);
|
||||
if (info->vbus_irq < 0) {
|
||||
- dev_err(dev, "failed to get VBUS IRQ\n");
|
||||
- ret = info->vbus_irq;
|
||||
- goto put_role_sw;
|
||||
- }
|
||||
-
|
||||
- ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL,
|
||||
- usb_conn_isr, USB_CONN_IRQF,
|
||||
- pdev->name, info);
|
||||
- if (ret < 0) {
|
||||
- dev_err(dev, "failed to request VBUS IRQ\n");
|
||||
- goto put_role_sw;
|
||||
+ dev_info(dev,
|
||||
+ "failed to get VBUS IRQ - falling back to polling\n");
|
||||
+ } else {
|
||||
+ ret = devm_request_threaded_irq(dev, info->vbus_irq,
|
||||
+ NULL, usb_conn_isr,
|
||||
+ USB_CONN_IRQF,
|
||||
+ pdev->name, info);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "failed to request VBUS IRQ\n");
|
||||
+ goto put_role_sw;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +318,8 @@ static int __maybe_unused usb_conn_suspend(struct device *dev)
|
||||
if (info->vbus_gpiod)
|
||||
disable_irq(info->vbus_irq);
|
||||
|
||||
+ cancel_delayed_work_sync(&info->dw_det);
|
||||
+
|
||||
pinctrl_pm_select_sleep_state(dev);
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From d7166eaf19e263a1b6dd551f1b5c40b86524b4d6 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 4 Jul 2020 21:04:29 +0200
|
||||
Subject: [PATCH 10/96] usb: dwc2: register child (USB connector) devices
|
||||
|
||||
Populate the child devices/nodes of the dwc2 controller. Typically these
|
||||
are USB connectors with a compatible string (and additional properties)
|
||||
like "gpio-usb-b-connector".
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/usb/dwc2/platform.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
|
||||
index b1d48019e..d56c1ea5b 100644
|
||||
--- a/drivers/usb/dwc2/platform.c
|
||||
+++ b/drivers/usb/dwc2/platform.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of.h>
|
||||
+#include <linux/of_platform.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/phy/phy.h>
|
||||
@@ -620,6 +621,19 @@ static int dwc2_driver_probe(struct platform_device *dev)
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
|
||||
+
|
||||
+ retval = devm_of_platform_populate(&dev->dev);
|
||||
+ if (retval) {
|
||||
+ dev_err(hsotg->dev,
|
||||
+ "Failed to create child devices/connectors for %p\n",
|
||||
+ dev->dev.of_node);
|
||||
+
|
||||
+ if (hsotg->gadget_enabled)
|
||||
+ dwc2_hsotg_remove(hsotg);
|
||||
+
|
||||
+ goto error_debugfs;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From 8a559e2ff9aa875656c3c62df16dedc84f68c2b7 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Wed, 16 Jun 2021 20:38:07 +0200
|
||||
Subject: [PATCH 11/96] ARM: dts: meson: Add GPIO controller capabilities to
|
||||
the first USB PHY
|
||||
|
||||
This is needed for boards that implement OTG functionality to read out
|
||||
the value of the "ID" signal (e.g. on Micro USB connectors).
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson.dtsi | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson.dtsi b/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
index 8cb0fc78b..0e7756c95 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
@@ -124,6 +124,8 @@ usb0_phy: phy@8800 {
|
||||
compatible = "amlogic,meson-mx-usb2-phy";
|
||||
#phy-cells = <0>;
|
||||
reg = <0x8800 0x20>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
From ebc6d5206b98d516e34304a42898d7733301cc96 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Mon, 4 May 2020 00:16:00 +0200
|
||||
Subject: [PATCH 12/96] ARM: dts: meson8b: odroidc1: Enable the Micro USB OTG
|
||||
connector
|
||||
|
||||
Enable &usb0 which is routed to the Micro USB connector. The port
|
||||
supports OTG modes and the role switch is implemented by reading out the
|
||||
"ID" signal from &usb0_phy.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../arm/boot/dts/amlogic/meson8b-odroidc1.dts | 34 ++++++++++++++++++-
|
||||
1 file changed, 33 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts b/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts
|
||||
index 941682844..eaf89638c 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts
|
||||
@@ -93,6 +93,20 @@ rtc32k_xtal: rtc32k-xtal-clk {
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
+ usb0_vbus: regulator-usb0-vbus {
|
||||
+ /* Richtek RT9715EGB */
|
||||
+ compatible = "regulator-fixed";
|
||||
+
|
||||
+ regulator-name = "USB0_VBUS";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+
|
||||
+ vin-supply = <&p5v0>;
|
||||
+
|
||||
+ gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
|
||||
+ enable-active-high;
|
||||
+ };
|
||||
+
|
||||
vcc_1v8: regulator-vcc-1v8 {
|
||||
/*
|
||||
* RICHTEK RT9179 configured for a fixed output voltage of
|
||||
@@ -363,8 +377,18 @@ &uart_AO {
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
-&usb1_phy {
|
||||
+&usb0 {
|
||||
status = "okay";
|
||||
+
|
||||
+ dr_mode = "otg";
|
||||
+ usb-role-switch;
|
||||
+
|
||||
+ connector {
|
||||
+ compatible = "gpio-usb-b-connector", "usb-b-connector";
|
||||
+ type = "micro";
|
||||
+ id-gpios = <&usb0_phy 0 GPIO_ACTIVE_HIGH>;
|
||||
+ vbus-supply = <&usb0_vbus>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&usb1 {
|
||||
@@ -381,3 +405,11 @@ hub@1 {
|
||||
reset-gpio = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+&usb0_phy {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb1_phy {
|
||||
+ status = "okay";
|
||||
+};
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
From 84f7776a36cf1b7bae65498c93dd7850efa0c12b Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Mon, 11 Oct 2021 23:37:19 +0200
|
||||
Subject: [PATCH 13/96] dt-bindings: phy: Add bindings for the Amlogic Meson
|
||||
CVBS DAC
|
||||
|
||||
Amlogic Meson SoCs embed a Composite Video Baseband Signal DAC. Add the
|
||||
bindings for this IP.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../phy/amlogic,meson-cvbs-dac-phy.yaml | 82 +++++++++++++++++++
|
||||
1 file changed, 82 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml b/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml
|
||||
new file mode 100644
|
||||
index 000000000..906a69505
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml
|
||||
@@ -0,0 +1,82 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/phy/amlogic,meson-cvbs-dac-phy.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Amlogic Meson Composite Video Baseband Signal DAC
|
||||
+
|
||||
+maintainers:
|
||||
+ - Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
+
|
||||
+description: |+
|
||||
+ The CVBS DAC node should be the child of a syscon node with the
|
||||
+ required property:
|
||||
+
|
||||
+ compatible = "amlogic,meson-hhi-sysctrl", "simple-mfd", "syscon"
|
||||
+
|
||||
+ Refer to the bindings described in
|
||||
+ Documentation/devicetree/bindings/mfd/syscon.yaml
|
||||
+
|
||||
+properties:
|
||||
+ $nodename:
|
||||
+ pattern: "^video-dac@[0-9a-f]+$"
|
||||
+
|
||||
+ compatible:
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - amlogic,meson8-cvbs-dac
|
||||
+ - amlogic,meson8b-cvbs-dac
|
||||
+ - amlogic,meson-gxbb-cvbs-dac
|
||||
+ - amlogic,meson-gxl-cvbs-dac
|
||||
+ - amlogic,meson-g12a-cvbs-dac
|
||||
+ - const: amlogic,meson-cvbs-dac
|
||||
+ - const: amlogic,meson-cvbs-dac
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ minItems: 1
|
||||
+
|
||||
+ nvmem-cells:
|
||||
+ minItems: 1
|
||||
+
|
||||
+ nvmem-cell-names:
|
||||
+ items:
|
||||
+ - const: cvbs_trimming
|
||||
+
|
||||
+ "#phy-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - "#phy-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ video-dac@2f4 {
|
||||
+ compatible = "amlogic,meson8-cvbs-dac", "amlogic,meson-cvbs-dac";
|
||||
+ reg = <0x2f4 0x8>;
|
||||
+
|
||||
+ #phy-cells = <0>;
|
||||
+
|
||||
+ clocks = <&vdac_clock>;
|
||||
+
|
||||
+ nvmem-cells = <&cvbs_trimming>;
|
||||
+ nvmem-cell-names = "cvbs_trimming";
|
||||
+ };
|
||||
+ - |
|
||||
+ video-dac@2ec {
|
||||
+ compatible = "amlogic,meson-g12a-cvbs-dac", "amlogic,meson-cvbs-dac";
|
||||
+ reg = <0x2ec 0x8>;
|
||||
+
|
||||
+ #phy-cells = <0>;
|
||||
+
|
||||
+ clocks = <&vdac_clock>;
|
||||
+ };
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,447 @@
|
||||
From a8af3998b655e87d5a10380584d2e80a93129195 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Mon, 11 Oct 2021 23:05:25 +0200
|
||||
Subject: [PATCH 14/96] phy: amlogic: Add a new driver for the CVBS DAC (CVBS
|
||||
PHY)
|
||||
|
||||
Amlogic Meson SoCs embed a CVBS DAC which converts the signal from the
|
||||
VPU to analog. The IP has evolved over time with the SoC generations:
|
||||
- Meson8/8b/8m2 has per-chip calibrated data for the CDAC_GSW register
|
||||
- GXBB is overall similar to Meson8/8b/8m2 except that it doesn't have
|
||||
per-chip calibration data and uses 0x0 in CDAC_GSW always
|
||||
- GXL/GXM are overall similar to GXBB but require a CDAC_VREF_ADJ value
|
||||
of 0xf (of which the actual meaning is unknown)
|
||||
- G12A/G12B/SM1 use different register offsets and different values for
|
||||
CDAC_CTRL_RESV2, CDAC_VREF_ADJ and CDAC_RL_ADJ. Like other SoCs from
|
||||
GXBB onwards they don't need any per-chip data.
|
||||
|
||||
For backwards compatibility with old .dtbs the driver gets
|
||||
platform_device_id's so the VPU driver can register the PHY as platform
|
||||
device if not provided via .dtb.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/phy/amlogic/Kconfig | 10 +
|
||||
drivers/phy/amlogic/Makefile | 1 +
|
||||
drivers/phy/amlogic/phy-meson-cvbs-dac.c | 376 +++++++++++++++++++++++
|
||||
3 files changed, 387 insertions(+)
|
||||
create mode 100644 drivers/phy/amlogic/phy-meson-cvbs-dac.c
|
||||
|
||||
diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig
|
||||
index ce7ba3eb2..671435b60 100644
|
||||
--- a/drivers/phy/amlogic/Kconfig
|
||||
+++ b/drivers/phy/amlogic/Kconfig
|
||||
@@ -25,6 +25,16 @@ config PHY_MESON8B_USB2
|
||||
Meson8b and GXBB SoCs.
|
||||
If unsure, say N.
|
||||
|
||||
+config PHY_MESON_CVBS_DAC
|
||||
+ tristate "Amlogic Meson CVBS DAC PHY driver"
|
||||
+ depends on ARCH_MESON || COMPILE_TEST
|
||||
+ depends on OF
|
||||
+ select MFD_SYSCON
|
||||
+ help
|
||||
+ Enable this to support the CVBS DAC (PHY) found in Amlogic
|
||||
+ Meson SoCs.
|
||||
+ If unsure, say N.
|
||||
+
|
||||
config PHY_MESON_GXL_USB2
|
||||
tristate "Meson GXL and GXM USB2 PHY drivers"
|
||||
default ARCH_MESON
|
||||
diff --git a/drivers/phy/amlogic/Makefile b/drivers/phy/amlogic/Makefile
|
||||
index 91e3b9790..f6c38f738 100644
|
||||
--- a/drivers/phy/amlogic/Makefile
|
||||
+++ b/drivers/phy/amlogic/Makefile
|
||||
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_PHY_MESON8_HDMI_TX) += phy-meson8-hdmi-tx.o
|
||||
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
|
||||
+obj-$(CONFIG_PHY_MESON_CVBS_DAC) += phy-meson-cvbs-dac.o
|
||||
obj-$(CONFIG_PHY_MESON_GXL_USB2) += phy-meson-gxl-usb2.o
|
||||
obj-$(CONFIG_PHY_MESON_G12A_USB2) += phy-meson-g12a-usb2.o
|
||||
obj-$(CONFIG_PHY_MESON_G12A_USB3_PCIE) += phy-meson-g12a-usb3-pcie.o
|
||||
diff --git a/drivers/phy/amlogic/phy-meson-cvbs-dac.c b/drivers/phy/amlogic/phy-meson-cvbs-dac.c
|
||||
new file mode 100644
|
||||
index 000000000..10edfb120
|
||||
--- /dev/null
|
||||
+++ b/drivers/phy/amlogic/phy-meson-cvbs-dac.c
|
||||
@@ -0,0 +1,376 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Copyright (C) 2016 BayLibre, SAS
|
||||
+ * Copyright (C) 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/phy/phy.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/property.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+
|
||||
+#define HHI_VDAC_CNTL0_MESON8 0x2F4 /* 0xbd offset in data sheet */
|
||||
+#define HHI_VDAC_CNTL1_MESON8 0x2F8 /* 0xbe offset in data sheet */
|
||||
+
|
||||
+#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */
|
||||
+#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */
|
||||
+
|
||||
+enum phy_meson_cvbs_dac_reg {
|
||||
+ MESON_CDAC_CTRL_RESV1,
|
||||
+ MESON_CDAC_CTRL_RESV2,
|
||||
+ MESON_CDAC_VREF_ADJ,
|
||||
+ MESON_CDAC_RL_ADJ,
|
||||
+ MESON_CDAC_CLK_PHASE_SEL,
|
||||
+ MESON_CDAC_DRIVER_ADJ,
|
||||
+ MESON_CDAC_EXT_VREF_EN,
|
||||
+ MESON_CDAC_BIAS_C,
|
||||
+ MESON_VDAC_CNTL0_RESERVED,
|
||||
+ MESON_CDAC_GSW,
|
||||
+ MESON_CDAC_PWD,
|
||||
+ MESON_VDAC_CNTL1_RESERVED,
|
||||
+ MESON_CVBS_DAC_NUM_REGS
|
||||
+};
|
||||
+
|
||||
+struct phy_meson_cvbs_dac_data {
|
||||
+ const struct reg_field *reg_fields;
|
||||
+ u8 cdac_ctrl_resv2_enable_val;
|
||||
+ u8 cdac_vref_adj_enable_val;
|
||||
+ u8 cdac_rl_adj_enable_val;
|
||||
+ u8 cdac_pwd_disable_val;
|
||||
+ bool needs_cvbs_trimming_nvmem_cell;
|
||||
+};
|
||||
+
|
||||
+struct phy_meson_cvbs_dac_priv {
|
||||
+ struct regmap_field *regs[MESON_CVBS_DAC_NUM_REGS];
|
||||
+ const struct phy_meson_cvbs_dac_data *data;
|
||||
+ u8 cdac_gsw_enable_val;
|
||||
+};
|
||||
+
|
||||
+static const struct reg_field phy_meson8_cvbs_dac_reg_fields[] = {
|
||||
+ [MESON_CDAC_CTRL_RESV1] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 0, 7),
|
||||
+ [MESON_CDAC_CTRL_RESV2] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 8, 15),
|
||||
+ [MESON_CDAC_VREF_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 16, 20),
|
||||
+ [MESON_CDAC_RL_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 21, 23),
|
||||
+ [MESON_CDAC_CLK_PHASE_SEL] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 24, 24),
|
||||
+ [MESON_CDAC_DRIVER_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 25, 25),
|
||||
+ [MESON_CDAC_EXT_VREF_EN] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 26, 26),
|
||||
+ [MESON_CDAC_BIAS_C] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 27, 27),
|
||||
+ [MESON_VDAC_CNTL0_RESERVED] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 28, 31),
|
||||
+ [MESON_CDAC_GSW] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 0, 2),
|
||||
+ [MESON_CDAC_PWD] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 3, 3),
|
||||
+ [MESON_VDAC_CNTL1_RESERVED] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 4, 31),
|
||||
+};
|
||||
+
|
||||
+static const struct reg_field phy_meson_g12a_cvbs_dac_reg_fields[] = {
|
||||
+ [MESON_CDAC_CTRL_RESV1] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 0, 7),
|
||||
+ [MESON_CDAC_CTRL_RESV2] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 8, 15),
|
||||
+ [MESON_CDAC_VREF_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 16, 20),
|
||||
+ [MESON_CDAC_RL_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 21, 23),
|
||||
+ [MESON_CDAC_CLK_PHASE_SEL] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 24, 24),
|
||||
+ [MESON_CDAC_DRIVER_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 25, 25),
|
||||
+ [MESON_CDAC_EXT_VREF_EN] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 26, 26),
|
||||
+ [MESON_CDAC_BIAS_C] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 27, 27),
|
||||
+ [MESON_VDAC_CNTL0_RESERVED] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 28, 31),
|
||||
+ [MESON_CDAC_GSW] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 0, 2),
|
||||
+ [MESON_CDAC_PWD] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 3, 3),
|
||||
+ [MESON_VDAC_CNTL1_RESERVED] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 4, 31),
|
||||
+};
|
||||
+
|
||||
+static const struct phy_meson_cvbs_dac_data phy_meson8_cvbs_dac_data = {
|
||||
+ .reg_fields = phy_meson8_cvbs_dac_reg_fields,
|
||||
+ .cdac_ctrl_resv2_enable_val = 0x0,
|
||||
+ .cdac_vref_adj_enable_val = 0x0,
|
||||
+ .cdac_rl_adj_enable_val = 0x0,
|
||||
+ .cdac_pwd_disable_val = 0x1,
|
||||
+ .needs_cvbs_trimming_nvmem_cell = true,
|
||||
+};
|
||||
+
|
||||
+static const struct phy_meson_cvbs_dac_data phy_meson_gxbb_cvbs_dac_data = {
|
||||
+ .reg_fields = phy_meson8_cvbs_dac_reg_fields,
|
||||
+ .cdac_ctrl_resv2_enable_val = 0x0,
|
||||
+ .cdac_vref_adj_enable_val = 0x0,
|
||||
+ .cdac_rl_adj_enable_val = 0x0,
|
||||
+ .cdac_pwd_disable_val = 0x1,
|
||||
+ .needs_cvbs_trimming_nvmem_cell = false,
|
||||
+};
|
||||
+
|
||||
+static const struct phy_meson_cvbs_dac_data phy_meson_gxl_cvbs_dac_data = {
|
||||
+ .reg_fields = phy_meson8_cvbs_dac_reg_fields,
|
||||
+ .cdac_ctrl_resv2_enable_val = 0x0,
|
||||
+ .cdac_vref_adj_enable_val = 0xf,
|
||||
+ .cdac_rl_adj_enable_val = 0x0,
|
||||
+ .cdac_pwd_disable_val = 0x1,
|
||||
+ .needs_cvbs_trimming_nvmem_cell = false,
|
||||
+};
|
||||
+
|
||||
+static const struct phy_meson_cvbs_dac_data phy_meson_g12a_cvbs_dac_data = {
|
||||
+ .reg_fields = phy_meson_g12a_cvbs_dac_reg_fields,
|
||||
+ .cdac_ctrl_resv2_enable_val = 0x60,
|
||||
+ .cdac_vref_adj_enable_val = 0x10,
|
||||
+ .cdac_rl_adj_enable_val = 0x4,
|
||||
+ .cdac_pwd_disable_val = 0x0,
|
||||
+ .needs_cvbs_trimming_nvmem_cell = false,
|
||||
+};
|
||||
+
|
||||
+static int phy_meson_cvbs_dac_power_on(struct phy *phy)
|
||||
+{
|
||||
+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy);
|
||||
+
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV1], 0x1);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV2],
|
||||
+ priv->data->cdac_ctrl_resv2_enable_val);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_VREF_ADJ],
|
||||
+ priv->data->cdac_vref_adj_enable_val);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_RL_ADJ],
|
||||
+ priv->data->cdac_rl_adj_enable_val);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_GSW],
|
||||
+ priv->cdac_gsw_enable_val);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_PWD], 0x0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int phy_meson_cvbs_dac_power_off(struct phy *phy)
|
||||
+{
|
||||
+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy);
|
||||
+
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV1], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV2], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_VREF_ADJ], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_RL_ADJ], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_GSW], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_PWD],
|
||||
+ priv->data->cdac_pwd_disable_val);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int phy_meson_cvbs_dac_init(struct phy *phy)
|
||||
+{
|
||||
+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy);
|
||||
+
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_CLK_PHASE_SEL], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_DRIVER_ADJ], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_EXT_VREF_EN], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_CDAC_BIAS_C], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_VDAC_CNTL0_RESERVED], 0x0);
|
||||
+ regmap_field_write(priv->regs[MESON_VDAC_CNTL1_RESERVED], 0x0);
|
||||
+
|
||||
+ return phy_meson_cvbs_dac_power_off(phy);
|
||||
+}
|
||||
+
|
||||
+static const struct phy_ops phy_meson_cvbs_dac_ops = {
|
||||
+ .init = phy_meson_cvbs_dac_init,
|
||||
+ .power_on = phy_meson_cvbs_dac_power_on,
|
||||
+ .power_off = phy_meson_cvbs_dac_power_off,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static u8 phy_meson_cvbs_trimming_version(u8 trimming1)
|
||||
+{
|
||||
+ if ((trimming1 & 0xf0) == 0xa0)
|
||||
+ return 5;
|
||||
+ else if ((trimming1 & 0xf0) == 0x40)
|
||||
+ return 2;
|
||||
+ else if ((trimming1 & 0xc0) == 0x80)
|
||||
+ return 1;
|
||||
+ else if ((trimming1 & 0xc0) == 0x00)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return 0xff;
|
||||
+}
|
||||
+
|
||||
+static int phy_meson_cvbs_read_trimming(struct device *dev,
|
||||
+ struct phy_meson_cvbs_dac_priv *priv)
|
||||
+{
|
||||
+ struct nvmem_cell *cell;
|
||||
+ u8 *trimming;
|
||||
+ size_t len;
|
||||
+
|
||||
+ cell = devm_nvmem_cell_get(dev, "cvbs_trimming");
|
||||
+ if (IS_ERR(cell))
|
||||
+ return dev_err_probe(dev, PTR_ERR(cell),
|
||||
+ "Failed to get the 'cvbs_trimming' nvmem-cell\n");
|
||||
+
|
||||
+ trimming = nvmem_cell_read(cell, &len);
|
||||
+ if (IS_ERR(trimming)) {
|
||||
+ /*
|
||||
+ * TrustZone firmware may block access to the CVBS trimming
|
||||
+ * data stored in the eFuse. On those devices the trimming data
|
||||
+ * is stored in the u-boot environment. However, the known
|
||||
+ * examples of trimming data in the u-boot environment are all
|
||||
+ * zero.
|
||||
+ */
|
||||
+ dev_dbg(dev,
|
||||
+ "Failed to read the 'cvbs_trimming' nvmem-cell - falling back to a default value\n");
|
||||
+ priv->cdac_gsw_enable_val = 0x0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (len != 2) {
|
||||
+ kfree(trimming);
|
||||
+ return dev_err_probe(dev, -EINVAL,
|
||||
+ "Read the 'cvbs_trimming' nvmem-cell with invalid length\n");
|
||||
+ }
|
||||
+
|
||||
+ switch (phy_meson_cvbs_trimming_version(trimming[1])) {
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ case 5:
|
||||
+ priv->cdac_gsw_enable_val = trimming[0] & 0x7;
|
||||
+ break;
|
||||
+ default:
|
||||
+ priv->cdac_gsw_enable_val = 0x0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ kfree(trimming);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int phy_meson_cvbs_dac_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct phy_meson_cvbs_dac_priv *priv;
|
||||
+ struct phy_provider *phy_provider;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct regmap *hhi;
|
||||
+ struct phy *phy;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (np) {
|
||||
+ priv->data = device_get_match_data(dev);
|
||||
+ if (!priv->data)
|
||||
+ return dev_err_probe(dev, -EINVAL,
|
||||
+ "Could not find the OF match data\n");
|
||||
+
|
||||
+ hhi = syscon_node_to_regmap(np->parent);
|
||||
+ if (IS_ERR(hhi))
|
||||
+ return dev_err_probe(dev, PTR_ERR(hhi),
|
||||
+ "Failed to get the parent syscon\n");
|
||||
+ } else {
|
||||
+ const struct platform_device_id *pdev_id;
|
||||
+
|
||||
+ pdev_id = platform_get_device_id(pdev);
|
||||
+ if (!pdev_id)
|
||||
+ return dev_err_probe(dev, -EINVAL,
|
||||
+ "Failed to find platform device ID\n");
|
||||
+
|
||||
+ priv->data = (void *)pdev_id->driver_data;
|
||||
+ if (!priv->data)
|
||||
+ return dev_err_probe(dev, -EINVAL,
|
||||
+ "Could not find the platform driver data\n");
|
||||
+
|
||||
+ hhi = syscon_regmap_lookup_by_compatible("amlogic,meson-gx-hhi-sysctrl");
|
||||
+ if (IS_ERR(hhi))
|
||||
+ return dev_err_probe(dev, PTR_ERR(hhi),
|
||||
+ "Failed to get the \"amlogic,meson-gx-hhi-sysctrl\" syscon\n");
|
||||
+ }
|
||||
+
|
||||
+ if (priv->data->needs_cvbs_trimming_nvmem_cell) {
|
||||
+ ret = phy_meson_cvbs_read_trimming(dev, priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_regmap_field_bulk_alloc(dev, hhi, priv->regs,
|
||||
+ priv->data->reg_fields,
|
||||
+ MESON_CVBS_DAC_NUM_REGS);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret,
|
||||
+ "Failed to create regmap fields\n");
|
||||
+
|
||||
+ phy = devm_phy_create(dev, np, &phy_meson_cvbs_dac_ops);
|
||||
+ if (IS_ERR(phy))
|
||||
+ return PTR_ERR(phy);
|
||||
+
|
||||
+ phy_set_drvdata(phy, priv);
|
||||
+
|
||||
+ if (np) {
|
||||
+ phy_provider = devm_of_phy_provider_register(dev,
|
||||
+ of_phy_simple_xlate);
|
||||
+ ret = PTR_ERR_OR_ZERO(phy_provider);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret,
|
||||
+ "Failed to register PHY provider\n");
|
||||
+ } else {
|
||||
+ platform_set_drvdata(pdev, phy);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id phy_meson_cvbs_dac_of_match[] = {
|
||||
+ {
|
||||
+ .compatible = "amlogic,meson8-cvbs-dac",
|
||||
+ .data = &phy_meson8_cvbs_dac_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "amlogic,meson8b-cvbs-dac",
|
||||
+ .data = &phy_meson8_cvbs_dac_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "amlogic,meson-gxbb-cvbs-dac",
|
||||
+ .data = &phy_meson_gxbb_cvbs_dac_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "amlogic,meson-gxl-cvbs-dac",
|
||||
+ .data = &phy_meson_gxl_cvbs_dac_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "amlogic,meson-g12a-cvbs-dac",
|
||||
+ .data = &phy_meson_g12a_cvbs_dac_data,
|
||||
+ },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, phy_meson_cvbs_dac_of_match);
|
||||
+
|
||||
+/*
|
||||
+ * The platform_device_id table is used for backwards compatibility with old
|
||||
+ * .dtbs which don't have a CVBS DAC node (where the VPU DRM driver registers
|
||||
+ * this as a platform device. Support for additional SoCs should only be added
|
||||
+ * to the of_device_id table above.
|
||||
+ */
|
||||
+static const struct platform_device_id phy_meson_cvbs_dac_device_ids[] = {
|
||||
+ {
|
||||
+ .name = "meson-gxbb-cvbs-dac",
|
||||
+ .driver_data = (kernel_ulong_t)&phy_meson_gxbb_cvbs_dac_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "meson-gxl-cvbs-dac",
|
||||
+ .driver_data = (kernel_ulong_t)&phy_meson_gxl_cvbs_dac_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "meson-g12a-cvbs-dac",
|
||||
+ .driver_data = (kernel_ulong_t)&phy_meson_g12a_cvbs_dac_data,
|
||||
+ },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(platform, phy_meson_cvbs_dac_device_ids);
|
||||
+
|
||||
+static struct platform_driver phy_meson_cvbs_dac_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "phy-meson-cvbs-dac",
|
||||
+ .of_match_table = phy_meson_cvbs_dac_of_match,
|
||||
+ },
|
||||
+ .id_table = phy_meson_cvbs_dac_device_ids,
|
||||
+ .probe = phy_meson_cvbs_dac_probe,
|
||||
+};
|
||||
+module_platform_driver(phy_meson_cvbs_dac_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
|
||||
+MODULE_DESCRIPTION("Amlogic Meson CVBS DAC driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 3b2d4e35f9726027f7fe3c0c10dae8e86169ba39 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Wed, 20 Oct 2021 22:19:25 +0200
|
||||
Subject: [PATCH 15/96] dt-bindings: display: meson-vpu: Add the CVBS DAC
|
||||
properties
|
||||
|
||||
The CVBS DAC converts the digital video signal to the (analog) composite
|
||||
video baseband signal (CVBS). This DAC is part of the HHI registers.
|
||||
Add the phy and phy-names property to describe the relation between the
|
||||
VPU (which outputs the digital signal) and the CVBS DAC.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../bindings/display/amlogic,meson-vpu.yaml | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
|
||||
index cb0a90f02..c9ab01434 100644
|
||||
--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
|
||||
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
|
||||
@@ -82,6 +82,15 @@ properties:
|
||||
description: should point to a canvas provider node
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
+ phys:
|
||||
+ maxItems: 1
|
||||
+ description:
|
||||
+ PHY specifier for the CVBS DAC
|
||||
+
|
||||
+ phy-names:
|
||||
+ items:
|
||||
+ - const: cvbs-dac
|
||||
+
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
description: phandle to the associated power domain
|
||||
@@ -130,6 +139,9 @@ examples:
|
||||
#size-cells = <0>;
|
||||
amlogic,canvas = <&canvas>;
|
||||
|
||||
+ phys = <&cvbs_dac_phy>;
|
||||
+ phy-names = "cvbs-dac";
|
||||
+
|
||||
/* CVBS VDAC output port */
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
From 8f9b70c8b353b2140e78d5aba6141b313d603e12 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Apr 2020 22:06:53 +0200
|
||||
Subject: [PATCH 16/96] drm/meson: Add support for using a PHY for the CVBS DAC
|
||||
|
||||
Currently the VPU driver hardcodes the initialization, power-on and
|
||||
power-off sequences for the CVBS DAC. The registers for the CVBS DAC are
|
||||
in the HHI register area. Also the CVBS DAC is a PHY so it can be
|
||||
modelled as such. Add support for using a PHY as CVBS DAC to de-couple
|
||||
the VPU driver from the HHI registers (at least for this part of the
|
||||
implementation).
|
||||
Register a platform device for the PHY (which creates a lookup entry to
|
||||
compensate for the missing .dtb entry) which takes over all
|
||||
HHI_VDAC_CNTL register management.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/Kconfig | 1 +
|
||||
drivers/gpu/drm/meson/meson_drv.h | 6 +
|
||||
drivers/gpu/drm/meson/meson_encoder_cvbs.c | 132 ++++++++++++++++-----
|
||||
drivers/gpu/drm/meson/meson_venc.c | 13 --
|
||||
4 files changed, 110 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
|
||||
index 615fdd0ce..47e920105 100644
|
||||
--- a/drivers/gpu/drm/meson/Kconfig
|
||||
+++ b/drivers/gpu/drm/meson/Kconfig
|
||||
@@ -10,6 +10,7 @@ config DRM_MESON
|
||||
select REGMAP_MMIO
|
||||
select MESON_CANVAS
|
||||
select CEC_CORE if CEC_NOTIFIER
|
||||
+ imply PHY_MESON_CVBS_DAC
|
||||
|
||||
config DRM_MESON_DW_HDMI
|
||||
tristate "HDMI Synopsys Controller support for Amlogic Meson Display"
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
|
||||
index 3f9345c14..69be4c67f 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.h
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.h
|
||||
@@ -16,6 +16,8 @@ struct drm_device;
|
||||
struct drm_plane;
|
||||
struct meson_drm;
|
||||
struct meson_afbcd_ops;
|
||||
+struct phy;
|
||||
+struct platform_device;
|
||||
|
||||
enum vpu_compatible {
|
||||
VPU_COMPATIBLE_GXBB = 0,
|
||||
@@ -61,6 +63,10 @@ struct meson_drm {
|
||||
|
||||
const struct meson_drm_soc_limits *limits;
|
||||
|
||||
+ struct phy *cvbs_dac;
|
||||
+ bool cvbs_dac_enabled;
|
||||
+ struct platform_device *cvbs_dac_pdev;
|
||||
+
|
||||
/* Components Data */
|
||||
struct {
|
||||
bool osd1_enabled;
|
||||
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
|
||||
index d1191de85..f849e0f85 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/of_graph.h>
|
||||
+#include <linux/phy/phy.h>
|
||||
+#include <linux/platform_device.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_bridge.h>
|
||||
@@ -24,12 +26,6 @@
|
||||
#include "meson_vclk.h"
|
||||
#include "meson_encoder_cvbs.h"
|
||||
|
||||
-/* HHI VDAC Registers */
|
||||
-#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
|
||||
-#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */
|
||||
-#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
|
||||
-#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */
|
||||
-
|
||||
struct meson_encoder_cvbs {
|
||||
struct drm_encoder encoder;
|
||||
struct drm_bridge bridge;
|
||||
@@ -87,11 +83,28 @@ static int meson_encoder_cvbs_attach(struct drm_bridge *bridge,
|
||||
{
|
||||
struct meson_encoder_cvbs *meson_encoder_cvbs =
|
||||
bridge_to_meson_encoder_cvbs(bridge);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = phy_init(meson_encoder_cvbs->priv->cvbs_dac);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
return drm_bridge_attach(bridge->encoder, meson_encoder_cvbs->next_bridge,
|
||||
&meson_encoder_cvbs->bridge, flags);
|
||||
}
|
||||
|
||||
+static void meson_encoder_cvbs_detach(struct drm_bridge *bridge)
|
||||
+{
|
||||
+ struct meson_encoder_cvbs *meson_encoder_cvbs =
|
||||
+ bridge_to_meson_encoder_cvbs(bridge);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = phy_exit(meson_encoder_cvbs->priv->cvbs_dac);
|
||||
+ if (ret)
|
||||
+ dev_err(meson_encoder_cvbs->priv->dev,
|
||||
+ "Failed to exit the CVBS DAC\n");
|
||||
+}
|
||||
+
|
||||
static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
@@ -148,6 +161,7 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge,
|
||||
struct drm_connector_state *conn_state;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_connector *connector;
|
||||
+ int ret;
|
||||
|
||||
connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
|
||||
if (WARN_ON(!connector))
|
||||
@@ -177,16 +191,13 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge,
|
||||
writel_bits_relaxed(VENC_VDAC_SEL_ATV_DMD, 0,
|
||||
priv->io_base + _REG(VENC_VDAC_DACSEL0));
|
||||
|
||||
- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 1);
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0);
|
||||
- } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
|
||||
- meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0xf0001);
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0);
|
||||
- } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0x906001);
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 0);
|
||||
+ if (!priv->cvbs_dac_enabled) {
|
||||
+ ret = phy_power_on(priv->cvbs_dac);
|
||||
+ if (ret)
|
||||
+ dev_err(priv->dev,
|
||||
+ "Failed to power on the CVBS DAC\n");
|
||||
+ else
|
||||
+ priv->cvbs_dac_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,19 +207,22 @@ static void meson_encoder_cvbs_atomic_disable(struct drm_bridge *bridge,
|
||||
struct meson_encoder_cvbs *meson_encoder_cvbs =
|
||||
bridge_to_meson_encoder_cvbs(bridge);
|
||||
struct meson_drm *priv = meson_encoder_cvbs->priv;
|
||||
+ int ret;
|
||||
|
||||
- /* Disable CVBS VDAC */
|
||||
- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0);
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 0);
|
||||
- } else {
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8);
|
||||
- }
|
||||
+ if (!priv->cvbs_dac_enabled)
|
||||
+ return;
|
||||
+
|
||||
+ ret = phy_power_off(priv->cvbs_dac);
|
||||
+ if (ret)
|
||||
+ dev_err(priv->dev,
|
||||
+ "Failed to power off the CVBS DAC\n");
|
||||
+ else
|
||||
+ priv->cvbs_dac_enabled = false;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs meson_encoder_cvbs_bridge_funcs = {
|
||||
.attach = meson_encoder_cvbs_attach,
|
||||
+ .detach = meson_encoder_cvbs_detach,
|
||||
.mode_valid = meson_encoder_cvbs_mode_valid,
|
||||
.get_modes = meson_encoder_cvbs_get_modes,
|
||||
.atomic_enable = meson_encoder_cvbs_atomic_enable,
|
||||
@@ -219,6 +233,54 @@ static const struct drm_bridge_funcs meson_encoder_cvbs_bridge_funcs = {
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
};
|
||||
|
||||
+static int meson_cvbs_dac_probe(struct meson_drm *priv)
|
||||
+{
|
||||
+ struct platform_device *pdev;
|
||||
+ const char *platform_id_name;
|
||||
+
|
||||
+ priv->cvbs_dac = devm_phy_optional_get(priv->dev, "cvbs-dac");
|
||||
+ if (IS_ERR(priv->cvbs_dac))
|
||||
+ return dev_err_probe(priv->dev, PTR_ERR(priv->cvbs_dac),
|
||||
+ "Failed to get the 'cvbs-dac' PHY\n");
|
||||
+ else if (priv->cvbs_dac)
|
||||
+ return 0;
|
||||
+
|
||||
+ switch (priv->compat) {
|
||||
+ case VPU_COMPATIBLE_GXBB:
|
||||
+ platform_id_name = "meson-gxbb-cvbs-dac";
|
||||
+ break;
|
||||
+ case VPU_COMPATIBLE_GXL:
|
||||
+ case VPU_COMPATIBLE_GXM:
|
||||
+ platform_id_name = "meson-gxl-cvbs-dac";
|
||||
+ break;
|
||||
+ case VPU_COMPATIBLE_G12A:
|
||||
+ platform_id_name = "meson-g12a-cvbs-dac";
|
||||
+ break;
|
||||
+ default:
|
||||
+ return dev_err_probe(priv->dev, -EINVAL,
|
||||
+ "No CVBS DAC platform ID found\n");
|
||||
+ }
|
||||
+
|
||||
+ pdev = platform_device_register_data(priv->dev, platform_id_name,
|
||||
+ PLATFORM_DEVID_AUTO, NULL, 0);
|
||||
+ if (IS_ERR(pdev))
|
||||
+ return dev_err_probe(priv->dev, PTR_ERR(pdev),
|
||||
+ "Failed to register fallback CVBS DAC PHY platform device\n");
|
||||
+
|
||||
+ priv->cvbs_dac = platform_get_drvdata(pdev);
|
||||
+ if (IS_ERR(priv->cvbs_dac)) {
|
||||
+ platform_device_unregister(pdev);
|
||||
+ return dev_err_probe(priv->dev, PTR_ERR(priv->cvbs_dac),
|
||||
+ "Failed to get the 'cvbs-dac' PHY from it's platform device\n");
|
||||
+ }
|
||||
+
|
||||
+ dev_info(priv->dev, "Using fallback for old .dtbs without CVBS DAC\n");
|
||||
+
|
||||
+ priv->cvbs_dac_pdev = pdev;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int meson_encoder_cvbs_probe(struct meson_drm *priv)
|
||||
{
|
||||
struct drm_device *drm = priv->drm;
|
||||
@@ -255,6 +317,10 @@ int meson_encoder_cvbs_probe(struct meson_drm *priv)
|
||||
|
||||
meson_encoder_cvbs->priv = priv;
|
||||
|
||||
+ ret = meson_cvbs_dac_probe(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
/* Encoder */
|
||||
ret = drm_simple_encoder_init(priv->drm, &meson_encoder_cvbs->encoder,
|
||||
DRM_MODE_ENCODER_TVDAC);
|
||||
@@ -268,21 +334,27 @@ int meson_encoder_cvbs_probe(struct meson_drm *priv)
|
||||
ret = drm_bridge_attach(&meson_encoder_cvbs->encoder, &meson_encoder_cvbs->bridge, NULL,
|
||||
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
||||
if (ret) {
|
||||
- dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
|
||||
- return ret;
|
||||
+ dev_err_probe(priv->dev, ret, "Failed to attach bridge\n");
|
||||
+ goto err_unregister_cvbs_dac_pdev;
|
||||
}
|
||||
|
||||
/* Initialize & attach Bridge Connector */
|
||||
connector = drm_bridge_connector_init(priv->drm, &meson_encoder_cvbs->encoder);
|
||||
- if (IS_ERR(connector))
|
||||
- return dev_err_probe(priv->dev, PTR_ERR(connector),
|
||||
- "Unable to create CVBS bridge connector\n");
|
||||
+ if (IS_ERR(connector)) {
|
||||
+ ret = dev_err_probe(priv->dev, PTR_ERR(connector),
|
||||
+ "Unable to create CVBS bridge connector\n");
|
||||
+ goto err_unregister_cvbs_dac_pdev;
|
||||
+ }
|
||||
|
||||
drm_connector_attach_encoder(connector, &meson_encoder_cvbs->encoder);
|
||||
|
||||
priv->encoders[MESON_ENC_CVBS] = meson_encoder_cvbs;
|
||||
|
||||
return 0;
|
||||
+
|
||||
+err_unregister_cvbs_dac_pdev:
|
||||
+ platform_device_unregister(priv->cvbs_dac_pdev);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
void meson_encoder_cvbs_remove(struct meson_drm *priv)
|
||||
@@ -293,4 +365,6 @@ void meson_encoder_cvbs_remove(struct meson_drm *priv)
|
||||
meson_encoder_cvbs = priv->encoders[MESON_ENC_CVBS];
|
||||
drm_bridge_remove(&meson_encoder_cvbs->bridge);
|
||||
}
|
||||
+
|
||||
+ platform_device_unregister(priv->cvbs_dac_pdev);
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
|
||||
index 3bf0d6e4f..5efd7a298 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_venc.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_venc.c
|
||||
@@ -62,10 +62,6 @@
|
||||
|
||||
/* HHI Registers */
|
||||
#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
|
||||
-#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
|
||||
-#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */
|
||||
-#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
|
||||
-#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */
|
||||
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
|
||||
|
||||
struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
|
||||
@@ -1968,15 +1964,6 @@ void meson_venc_disable_vsync(struct meson_drm *priv)
|
||||
|
||||
void meson_venc_init(struct meson_drm *priv)
|
||||
{
|
||||
- /* Disable CVBS VDAC */
|
||||
- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0);
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 8);
|
||||
- } else {
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
|
||||
- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8);
|
||||
- }
|
||||
-
|
||||
/* Power Down Dacs */
|
||||
writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From 182a6e3ae155fe2a0d9f4380c8f46b531d8e867b Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 1 May 2020 23:16:07 +0200
|
||||
Subject: [PATCH 18/96] dt-bindings: clock: meson8b: Add the RMII reference
|
||||
clock input
|
||||
|
||||
Amlogic Meson8 SoCs need an external 50MHz RMII reference clock. This is
|
||||
either provided by the Ethernet PHY or an external oscillator. Add the
|
||||
documentation for this clock input.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../devicetree/bindings/clock/amlogic,meson8b-clkc.txt | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
|
||||
index cc51e4746..a2602b5d5 100644
|
||||
--- a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
|
||||
+++ b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
|
||||
@@ -16,6 +16,8 @@ Required Properties:
|
||||
* "xtal": the 24MHz system oscillator
|
||||
* "ddr_pll": the DDR PLL clock
|
||||
* "clk_32k": (if present) the 32kHz clock signal from GPIOAO_6 (CLK_32K_IN)
|
||||
+ * "rmii_clk": (if present) the 50MHz RMII reference clock (from the PHY or
|
||||
+ an external oscillator
|
||||
|
||||
Parent node should have the following properties :
|
||||
- compatible: "amlogic,meson-hhi-sysctrl", "simple-mfd", "syscon"
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From 2b1a5a4937e6de3aeba31fdd96946ff66d3c1608 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 1 May 2020 23:23:49 +0200
|
||||
Subject: [PATCH 19/96] dt-bindings: clock: meson8b: Add the Meson8 Ethernet
|
||||
(RMII) clocks
|
||||
|
||||
Export CLKID_ETH_CLK (and it's parents) because it is used as input for
|
||||
the Ethernet controller on Meson8 SoCs.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
include/dt-bindings/clock/meson8b-clkc.h | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
|
||||
index 385bf243c..a09b686af 100644
|
||||
--- a/include/dt-bindings/clock/meson8b-clkc.h
|
||||
+++ b/include/dt-bindings/clock/meson8b-clkc.h
|
||||
@@ -221,5 +221,9 @@
|
||||
#define CLKID_VCLK2_EN 215
|
||||
#define CLKID_VID_PLL_LVDS_EN 216
|
||||
#define CLKID_HDMI_PLL_DCO_IN 217
|
||||
+#define CLKID_ETH_CLK_SEL 218
|
||||
+#define CLKID_ETH_CLK_DIV 219
|
||||
+#define CLKID_ETH_CLK_PHASE 220
|
||||
+#define CLKID_ETH_CLK 221
|
||||
|
||||
#endif /* __MESON8B_CLKC_H */
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
From 1336f3b73beada616ef72126e736598e4503fbe0 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 1 May 2020 23:25:13 +0200
|
||||
Subject: [PATCH 20/96] clk: meson: meson8b: Add the Ethernet (RMII) clock tree
|
||||
on Meson8
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add the Ethernet clock tree on Meson8 which consists of:
|
||||
- an input mux - the only known input is the RMII reference clock signal
|
||||
which is an input on one of the SoC's pads
|
||||
- a divider
|
||||
- 0° or 180° phase change
|
||||
- a gate to enable/disable the clock
|
||||
|
||||
Add these clocks only for Meson8 because they're only known to be used
|
||||
there.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/clk/meson/Kconfig | 1 +
|
||||
drivers/clk/meson/meson8b.c | 81 +++++++++++++++++++++++++++++++++++++
|
||||
drivers/clk/meson/meson8b.h | 1 +
|
||||
3 files changed, 83 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
|
||||
index 29ffd14d2..03e99ee3c 100644
|
||||
--- a/drivers/clk/meson/Kconfig
|
||||
+++ b/drivers/clk/meson/Kconfig
|
||||
@@ -55,6 +55,7 @@ config COMMON_CLK_MESON8B
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_CLKC_UTILS
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
+ select COMMON_CLK_MESON_PHASE
|
||||
select COMMON_CLK_MESON_PLL
|
||||
select MFD_SYSCON
|
||||
select RESET_CONTROLLER
|
||||
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
|
||||
index b7417ac26..8128e0864 100644
|
||||
--- a/drivers/clk/meson/meson8b.c
|
||||
+++ b/drivers/clk/meson/meson8b.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "meson8b.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "meson-clkc-utils.h"
|
||||
+#include "clk-phase.h"
|
||||
#include "clk-pll.h"
|
||||
#include "clk-mpll.h"
|
||||
|
||||
@@ -2682,6 +2683,78 @@ static struct clk_regmap meson8b_cts_i958 = {
|
||||
},
|
||||
};
|
||||
|
||||
+static u32 meson8_eth_clk_mux_table[] = { 7 };
|
||||
+
|
||||
+static struct clk_regmap meson8_eth_clk_sel = {
|
||||
+ .data = &(struct clk_regmap_mux_data) {
|
||||
+ .offset = HHI_ETH_CLK_CNTL,
|
||||
+ .mask = 0x7,
|
||||
+ .shift = 9,
|
||||
+ .table = meson8_eth_clk_mux_table,
|
||||
+ },
|
||||
+ .hw.init = &(struct clk_init_data) {
|
||||
+ .name = "eth_clk_sel",
|
||||
+ .ops = &clk_regmap_mux_ops,
|
||||
+ .parent_data = &(const struct clk_parent_data) {
|
||||
+ /* TODO: all other parents are unknown */
|
||||
+ .fw_name = "rmii_clk",
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct clk_regmap meson8_eth_clk_div = {
|
||||
+ .data = &(struct clk_regmap_div_data) {
|
||||
+ .offset = HHI_ETH_CLK_CNTL,
|
||||
+ .shift = 0,
|
||||
+ .width = 8,
|
||||
+ },
|
||||
+ .hw.init = &(struct clk_init_data) {
|
||||
+ .name = "eth_clk_div",
|
||||
+ .ops = &clk_regmap_divider_ops,
|
||||
+ .parent_hws = (const struct clk_hw *[]) {
|
||||
+ &meson8_eth_clk_sel.hw
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ .flags = CLK_SET_RATE_PARENT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct clk_regmap meson8_eth_clk_phase = {
|
||||
+ .data = &(struct meson_clk_phase_data) {
|
||||
+ .ph = {
|
||||
+ .reg_off = HHI_ETH_CLK_CNTL,
|
||||
+ .shift = 14,
|
||||
+ .width = 1,
|
||||
+ },
|
||||
+ },
|
||||
+ .hw.init = &(struct clk_init_data){
|
||||
+ .name = "eth_clk_inverted",
|
||||
+ .ops = &meson_clk_phase_ops,
|
||||
+ .parent_hws = (const struct clk_hw *[]) {
|
||||
+ &meson8_eth_clk_div.hw
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ .flags = CLK_SET_RATE_PARENT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct clk_regmap meson8_eth_clk_gate = {
|
||||
+ .data = &(struct clk_regmap_gate_data) {
|
||||
+ .offset = HHI_ETH_CLK_CNTL,
|
||||
+ .bit_idx = 8,
|
||||
+ },
|
||||
+ .hw.init = &(struct clk_init_data){
|
||||
+ .name = "eth_clk_en",
|
||||
+ .ops = &clk_regmap_gate_ops,
|
||||
+ .parent_hws = (const struct clk_hw *[]) {
|
||||
+ &meson8_eth_clk_phase.hw
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ .flags = CLK_SET_RATE_PARENT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
#define MESON_GATE(_name, _reg, _bit) \
|
||||
MESON_PCLK(_name, _reg, _bit, &meson8b_clk81.hw)
|
||||
|
||||
@@ -2978,6 +3051,10 @@ static struct clk_hw *meson8_hw_clks[] = {
|
||||
[CLKID_CTS_I958] = &meson8b_cts_i958.hw,
|
||||
[CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw,
|
||||
[CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw,
|
||||
+ [CLKID_ETH_CLK_SEL] = &meson8_eth_clk_sel.hw,
|
||||
+ [CLKID_ETH_CLK_DIV] = &meson8_eth_clk_div.hw,
|
||||
+ [CLKID_ETH_CLK_PHASE] = &meson8_eth_clk_phase.hw,
|
||||
+ [CLKID_ETH_CLK] = &meson8_eth_clk_gate.hw,
|
||||
};
|
||||
|
||||
static struct clk_hw *meson8b_hw_clks[] = {
|
||||
@@ -3606,6 +3683,10 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
|
||||
&meson8b_cts_mclk_i958,
|
||||
&meson8b_cts_i958,
|
||||
&meson8b_vid_pll_lvds_en,
|
||||
+ &meson8_eth_clk_sel,
|
||||
+ &meson8_eth_clk_div,
|
||||
+ &meson8_eth_clk_phase,
|
||||
+ &meson8_eth_clk_gate,
|
||||
};
|
||||
|
||||
static const struct meson8b_clk_reset_line {
|
||||
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
|
||||
index a5b6e67ee..dfec963d4 100644
|
||||
--- a/drivers/clk/meson/meson8b.h
|
||||
+++ b/drivers/clk/meson/meson8b.h
|
||||
@@ -43,6 +43,7 @@
|
||||
#define HHI_MALI_CLK_CNTL 0x1b0 /* 0x6c offset in data sheet */
|
||||
#define HHI_VPU_CLK_CNTL 0x1bc /* 0x6f offset in data sheet */
|
||||
#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */
|
||||
+#define HHI_ETH_CLK_CNTL 0x1d8 /* 0x76 offset in data sheet */
|
||||
#define HHI_VDEC_CLK_CNTL 0x1e0 /* 0x78 offset in data sheet */
|
||||
#define HHI_VDEC2_CLK_CNTL 0x1e4 /* 0x79 offset in data sheet */
|
||||
#define HHI_VDEC3_CLK_CNTL 0x1e8 /* 0x7a offset in data sheet */
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
From a2f6824d3140baec1ba1b0748b0b3ee08f083185 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 1 May 2020 23:37:35 +0200
|
||||
Subject: [PATCH 21/96] dt-bindings: net: dwmac-meson: Add the Ethernet clock
|
||||
input for Meson6/8
|
||||
|
||||
The additional DWMAC register on Amlogic Meson6 and Meson8 SoCs take a
|
||||
clock input (which is provided by the HHI clock controller). For RMII
|
||||
mode this clock is derived from the RMII reference clock. Document this
|
||||
clock input so the clock can be enabled when needed.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../bindings/net/amlogic,meson-dwmac.yaml | 22 +++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
|
||||
index ee7a65b52..ea4b75ef6 100644
|
||||
--- a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
|
||||
@@ -127,6 +127,28 @@ allOf:
|
||||
- 2800
|
||||
- 3000
|
||||
|
||||
+ - if:
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ contains:
|
||||
+ enum:
|
||||
+ - amlogic,meson6-dwmac
|
||||
+ then:
|
||||
+ properties:
|
||||
+ clocks:
|
||||
+ minItems: 1
|
||||
+ maxItems: 2
|
||||
+ items:
|
||||
+ - description: GMAC main clock
|
||||
+ - description: The RMII reference clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ minItems: 1
|
||||
+ maxItems: 2
|
||||
+ items:
|
||||
+ - const: stmmaceth
|
||||
+ - const: ethernet
|
||||
+
|
||||
properties:
|
||||
compatible:
|
||||
additionalItems: true
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
From 237a072d8b71eecddce1f9ec7dda2ae7a46f27bf Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Dec 2021 04:07:05 +0100
|
||||
Subject: [PATCH 22/96] net: stmmac: dwmac-meson: Rename the SPEED_100 macro
|
||||
|
||||
The SPEED_100 macro is part of the PREG_ETHERNET_ADDR0 register. Rename
|
||||
it accordingly to make this relationship clear.
|
||||
While here also add a comment what the SPEED_100 bit actually does.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
index a16bfa908..919c41e15 100644
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
@@ -15,7 +15,8 @@
|
||||
|
||||
#include "stmmac_platform.h"
|
||||
|
||||
-#define ETHMAC_SPEED_100 BIT(1)
|
||||
+/* divides the input clock by 20 (= 0x0) or 2 (= 0x1) */
|
||||
+#define PREG_ETHERNET_ADDR0_SPEED_100 BIT(1)
|
||||
|
||||
struct meson_dwmac {
|
||||
struct device *dev;
|
||||
@@ -31,10 +32,10 @@ static void meson6_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_10:
|
||||
- val &= ~ETHMAC_SPEED_100;
|
||||
+ val &= ~PREG_ETHERNET_ADDR0_SPEED_100;
|
||||
break;
|
||||
case SPEED_100:
|
||||
- val |= ETHMAC_SPEED_100;
|
||||
+ val |= PREG_ETHERNET_ADDR0_SPEED_100;
|
||||
break;
|
||||
}
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
From 6cfa3555ebbfd9cfab319352f436ae9d7f0ffdea Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Dec 2021 04:22:53 +0100
|
||||
Subject: [PATCH 23/96] net: stmmac: dwmac-meson: Manage the "ethernet" clock
|
||||
|
||||
Meson6 and Meson8 (both use the same glue registers on top of the DWMAC
|
||||
IP) have a dedicated Ethernet clock. For RMII mode the SoC has an input
|
||||
for an external RMII reference clock signal (which can be provided by
|
||||
either the PHY or an external oscillator). This clock needs to run at
|
||||
50MHz because the additional glue registers can divide by 2 - to achieve
|
||||
25MHz for 100Mbit/s line speed, or 20 - to achieve 2.5MHz for 10Mbit/s
|
||||
line speed.
|
||||
|
||||
Set the correct frequency for this clock and enable it during init. Also
|
||||
enable the ETHMAC_DIV_EN bit which enables the divider in the glue
|
||||
registers, based on the Ethernet clock input.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../net/ethernet/stmicro/stmmac/dwmac-meson.c | 51 ++++++++++++++++++-
|
||||
1 file changed, 50 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
index 919c41e15..2361734e3 100644
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
|
||||
*/
|
||||
|
||||
+#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/io.h>
|
||||
@@ -15,12 +16,15 @@
|
||||
|
||||
#include "stmmac_platform.h"
|
||||
|
||||
+#define PREG_ETHERNET_ADDR0_DIV_EN BIT(0)
|
||||
+
|
||||
/* divides the input clock by 20 (= 0x0) or 2 (= 0x1) */
|
||||
#define PREG_ETHERNET_ADDR0_SPEED_100 BIT(1)
|
||||
|
||||
struct meson_dwmac {
|
||||
struct device *dev;
|
||||
void __iomem *reg;
|
||||
+ struct clk *ethernet_clk;
|
||||
};
|
||||
|
||||
static void meson6_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
|
||||
@@ -42,6 +46,33 @@ static void meson6_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned
|
||||
writel(val, dwmac->reg);
|
||||
}
|
||||
|
||||
+static int meson6_dwmac_init(struct platform_device *pdev, void *priv)
|
||||
+{
|
||||
+ struct meson_dwmac *dwmac = priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_set_rate(dwmac->ethernet_clk, 50 * 1000 * 1000);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(dwmac->ethernet_clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ writel(readl(dwmac->reg) | PREG_ETHERNET_ADDR0_DIV_EN, dwmac->reg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void meson6_dwmac_exit(struct platform_device *pdev, void *priv)
|
||||
+{
|
||||
+ struct meson_dwmac *dwmac = priv;
|
||||
+
|
||||
+ writel(readl(dwmac->reg) & ~PREG_ETHERNET_ADDR0_DIV_EN, dwmac->reg);
|
||||
+
|
||||
+ clk_disable_unprepare(dwmac->ethernet_clk);
|
||||
+}
|
||||
+
|
||||
static int meson6_dwmac_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct plat_stmmacenet_data *plat_dat;
|
||||
@@ -65,10 +96,28 @@ static int meson6_dwmac_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(dwmac->reg))
|
||||
return PTR_ERR(dwmac->reg);
|
||||
|
||||
+ dwmac->ethernet_clk = devm_clk_get_optional(&pdev->dev, "ethernet");
|
||||
+ if (IS_ERR(dwmac->ethernet_clk))
|
||||
+ return PTR_ERR(dwmac->ethernet_clk);
|
||||
+
|
||||
plat_dat->bsp_priv = dwmac;
|
||||
+ plat_dat->init = meson6_dwmac_init;
|
||||
+ plat_dat->exit = meson6_dwmac_exit;
|
||||
plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
|
||||
|
||||
- return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
+ ret = meson6_dwmac_init(pdev, dwmac);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
+ if (ret)
|
||||
+ goto err_exit_dwmac;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_exit_dwmac:
|
||||
+ meson6_dwmac_exit(pdev, dwmac);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id meson6_dwmac_match[] = {
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
From 259fca64ab9ea66d43f6bd82584768fb0767789b Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Dec 2021 04:18:30 +0100
|
||||
Subject: [PATCH 24/96] net: stmmac: dwmac-meson: Initialize all known
|
||||
PREG_ETHERNET_ADDR0 bits
|
||||
|
||||
Initialize all known PREG_ETHERNET_ADDR0 register bits to be less
|
||||
dependent on the bootloader to set them up correctly.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../net/ethernet/stmicro/stmmac/dwmac-meson.c | 25 ++++++++++++++++---
|
||||
1 file changed, 22 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
index 2361734e3..b96aa4d39 100644
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
|
||||
*/
|
||||
|
||||
+#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/ethtool.h>
|
||||
@@ -16,10 +17,20 @@
|
||||
|
||||
#include "stmmac_platform.h"
|
||||
|
||||
-#define PREG_ETHERNET_ADDR0_DIV_EN BIT(0)
|
||||
+#define PREG_ETHERNET_ADDR0_DIV_EN BIT(0)
|
||||
|
||||
/* divides the input clock by 20 (= 0x0) or 2 (= 0x1) */
|
||||
-#define PREG_ETHERNET_ADDR0_SPEED_100 BIT(1)
|
||||
+#define PREG_ETHERNET_ADDR0_SPEED_100 BIT(1)
|
||||
+
|
||||
+/* 0x0 = little, 0x1 = big */
|
||||
+#define PREG_ETHERNET_ADDR0_DATA_ENDIANNESS BIT(2)
|
||||
+
|
||||
+/* 0x0 = same order, 0x1: unknown */
|
||||
+#define PREG_ETHERNET_ADDR0_DESC_ENDIANNESS BIT(3)
|
||||
+
|
||||
+#define PREG_ETHERNET_ADDR0_MII_MODE GENMASK(6, 4)
|
||||
+#define PREG_ETHERNET_ADDR0_MII_MODE_RGMII 0x1
|
||||
+#define PREG_ETHERNET_ADDR0_MII_MODE_RMII 0x4
|
||||
|
||||
struct meson_dwmac {
|
||||
struct device *dev;
|
||||
@@ -49,6 +60,7 @@ static void meson6_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned
|
||||
static int meson6_dwmac_init(struct platform_device *pdev, void *priv)
|
||||
{
|
||||
struct meson_dwmac *dwmac = priv;
|
||||
+ u32 val;
|
||||
int ret;
|
||||
|
||||
ret = clk_set_rate(dwmac->ethernet_clk, 50 * 1000 * 1000);
|
||||
@@ -59,7 +71,14 @@ static int meson6_dwmac_init(struct platform_device *pdev, void *priv)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- writel(readl(dwmac->reg) | PREG_ETHERNET_ADDR0_DIV_EN, dwmac->reg);
|
||||
+ val = readl(dwmac->reg);
|
||||
+ val &= ~PREG_ETHERNET_ADDR0_DATA_ENDIANNESS;
|
||||
+ val &= ~PREG_ETHERNET_ADDR0_DESC_ENDIANNESS;
|
||||
+ val &= ~PREG_ETHERNET_ADDR0_MII_MODE;
|
||||
+ val |= FIELD_PREP(PREG_ETHERNET_ADDR0_MII_MODE,
|
||||
+ PREG_ETHERNET_ADDR0_MII_MODE_RMII);
|
||||
+ val |= PREG_ETHERNET_ADDR0_DIV_EN;
|
||||
+ writel(val, dwmac->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From e1e3ba72f71b31abadff7ce2443b3cdeafbdacf1 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 1 May 2020 23:47:47 +0200
|
||||
Subject: [PATCH 25/96] ARM: dts: meson: meson8: Add the clock input to the
|
||||
Ethernet controller
|
||||
|
||||
The Ethernet controller on Meson8 has an additional clock input from the
|
||||
HHI clock controller. The clock signal provides the RMII reference clock
|
||||
which is used to generate the internal 25MHz or 2.5MHz clocks depending
|
||||
on the line speed.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson8.dtsi | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
index f57be9ae1..b2be52915 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
@@ -613,8 +613,8 @@ temperature_calib: calib@1f4 {
|
||||
};
|
||||
|
||||
ðmac {
|
||||
- clocks = <&clkc CLKID_ETH>;
|
||||
- clock-names = "stmmaceth";
|
||||
+ clocks = <&clkc CLKID_ETH>, <&clkc CLKID_ETH_CLK>;
|
||||
+ clock-names = "stmmaceth", "ethernet";
|
||||
|
||||
power-domains = <&pwrc PWRC_MESON8_ETHERNET_MEM_ID>;
|
||||
};
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From 0361c56921d2f1c27f35bb5ef2165e5550a26d68 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 1 Jan 2021 19:01:08 +0100
|
||||
Subject: [PATCH 26/96] dt-bindings: clock: meson8b: add the rtc_32k oscillator
|
||||
input
|
||||
|
||||
The CLK81 tree can be driven off the 32kHz oscillator connected to the
|
||||
SoCs RTC32K_XI and RTC32K_XO pads. Add this clock as a valid input.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../devicetree/bindings/clock/amlogic,meson8b-clkc.txt | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
|
||||
index a2602b5d5..855931509 100644
|
||||
--- a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
|
||||
+++ b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
|
||||
@@ -18,6 +18,8 @@ Required Properties:
|
||||
* "clk_32k": (if present) the 32kHz clock signal from GPIOAO_6 (CLK_32K_IN)
|
||||
* "rmii_clk": (if present) the 50MHz RMII reference clock (from the PHY or
|
||||
an external oscillator
|
||||
+ * "rtc_32k": the clock signal from the 32kHz oscillator connected to the
|
||||
+ RTC32K_XI and RTC32K_XO pads
|
||||
|
||||
Parent node should have the following properties :
|
||||
- compatible: "amlogic,meson-hhi-sysctrl", "simple-mfd", "syscon"
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
From 439df3198ef064825150418f9c1244a9f2a20aac Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 1 Jan 2021 18:55:05 +0100
|
||||
Subject: [PATCH 27/96] clk: meson: meson8b: Add the mpeg_rtc_osc_sel clock
|
||||
|
||||
The first input of the CLK81 clock tree uses the SoC's external
|
||||
oscillators. By default it's the 24MHz XTAL from which most frequencies
|
||||
in this SoC are derived. For power-saving purposes there's a mux to
|
||||
switch the input between the 24MHz XTAL and the 32kHz RTC oscillator.
|
||||
Add support for that mux add it to the CLK81 clock tree for a better
|
||||
representation of how the hardware is actually designed.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/clk/meson/meson8b.c | 26 ++++++++++++++++++++++--
|
||||
include/dt-bindings/clock/meson8b-clkc.h | 1 +
|
||||
2 files changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
|
||||
index 8128e0864..2f7a2adda 100644
|
||||
--- a/drivers/clk/meson/meson8b.c
|
||||
+++ b/drivers/clk/meson/meson8b.c
|
||||
@@ -611,7 +611,24 @@ static struct clk_regmap meson8b_mpll2 = {
|
||||
},
|
||||
};
|
||||
|
||||
-static u32 mux_table_clk81[] = { 6, 5, 7 };
|
||||
+static struct clk_regmap meson8b_mpeg_rtc_osc_sel = {
|
||||
+ .data = &(struct clk_regmap_mux_data){
|
||||
+ .offset = HHI_MPEG_CLK_CNTL,
|
||||
+ .mask = 0x1,
|
||||
+ .shift = 9,
|
||||
+ },
|
||||
+ .hw.init = &(struct clk_init_data){
|
||||
+ .name = "mpeg_rtc_osc_sel",
|
||||
+ .ops = &clk_regmap_mux_ro_ops,
|
||||
+ .parent_data = (const struct clk_parent_data[]) {
|
||||
+ { .fw_name = "xtal", .index = -1, },
|
||||
+ { .fw_name = "rtc_32k", .index = -1, },
|
||||
+ },
|
||||
+ .num_parents = 2,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static u32 mux_table_clk81[] = { 0, 6, 5, 7 };
|
||||
static struct clk_regmap meson8b_mpeg_clk_sel = {
|
||||
.data = &(struct clk_regmap_mux_data){
|
||||
.offset = HHI_MPEG_CLK_CNTL,
|
||||
@@ -628,11 +645,12 @@ static struct clk_regmap meson8b_mpeg_clk_sel = {
|
||||
* fclk_div4, fclk_div3, fclk_div5
|
||||
*/
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
+ &meson8b_mpeg_rtc_osc_sel.hw,
|
||||
&meson8b_fclk_div3.hw,
|
||||
&meson8b_fclk_div4.hw,
|
||||
&meson8b_fclk_div5.hw,
|
||||
},
|
||||
- .num_parents = 3,
|
||||
+ .num_parents = 4,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3055,6 +3073,7 @@ static struct clk_hw *meson8_hw_clks[] = {
|
||||
[CLKID_ETH_CLK_DIV] = &meson8_eth_clk_div.hw,
|
||||
[CLKID_ETH_CLK_PHASE] = &meson8_eth_clk_phase.hw,
|
||||
[CLKID_ETH_CLK] = &meson8_eth_clk_gate.hw,
|
||||
+ [CLKID_MPEG_RTC_OSC_SEL] = &meson8b_mpeg_rtc_osc_sel.hw,
|
||||
};
|
||||
|
||||
static struct clk_hw *meson8b_hw_clks[] = {
|
||||
@@ -3270,6 +3289,7 @@ static struct clk_hw *meson8b_hw_clks[] = {
|
||||
[CLKID_CTS_I958] = &meson8b_cts_i958.hw,
|
||||
[CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw,
|
||||
[CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw,
|
||||
+ [CLKID_MPEG_RTC_OSC_SEL] = &meson8b_mpeg_rtc_osc_sel.hw,
|
||||
};
|
||||
|
||||
static struct clk_hw *meson8m2_hw_clks[] = {
|
||||
@@ -3487,6 +3507,7 @@ static struct clk_hw *meson8m2_hw_clks[] = {
|
||||
[CLKID_CTS_I958] = &meson8b_cts_i958.hw,
|
||||
[CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw,
|
||||
[CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw,
|
||||
+ [CLKID_MPEG_RTC_OSC_SEL] = &meson8b_mpeg_rtc_osc_sel.hw,
|
||||
};
|
||||
|
||||
static struct clk_regmap *const meson8b_clk_regmaps[] = {
|
||||
@@ -3687,6 +3708,7 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
|
||||
&meson8_eth_clk_div,
|
||||
&meson8_eth_clk_phase,
|
||||
&meson8_eth_clk_gate,
|
||||
+ &meson8b_mpeg_rtc_osc_sel,
|
||||
};
|
||||
|
||||
static const struct meson8b_clk_reset_line {
|
||||
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
|
||||
index a09b686af..fe6c02e04 100644
|
||||
--- a/include/dt-bindings/clock/meson8b-clkc.h
|
||||
+++ b/include/dt-bindings/clock/meson8b-clkc.h
|
||||
@@ -225,5 +225,6 @@
|
||||
#define CLKID_ETH_CLK_DIV 219
|
||||
#define CLKID_ETH_CLK_PHASE 220
|
||||
#define CLKID_ETH_CLK 221
|
||||
+#define CLKID_MPEG_RTC_OSC_SEL 222
|
||||
|
||||
#endif /* __MESON8B_CLKC_H */
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
From b9f75c5b68a79dee3c4ca723a4ee92521118a92d Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 28 Aug 2021 18:50:10 +0200
|
||||
Subject: [PATCH 28/96] ARM: dts: meson: Add #address-cells, #size-cells and
|
||||
ranges to hhi
|
||||
|
||||
The HHI node has multiple child-nodes. Add #address-cells, #size-cells
|
||||
and ranges properties to the hhi node itself so the child-nodes can get
|
||||
their own offset and register sizes. Also add the reg property to the
|
||||
clock and power domain controllers inside the hhi region.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson.dtsi | 3 +++
|
||||
arch/arm/boot/dts/amlogic/meson8.dtsi | 6 ++++--
|
||||
arch/arm/boot/dts/amlogic/meson8b.dtsi | 6 ++++--
|
||||
3 files changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson.dtsi b/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
index 0e7756c95..d7f50fec8 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
@@ -35,6 +35,9 @@ hhi: system-controller@4000 {
|
||||
"simple-mfd",
|
||||
"syscon";
|
||||
reg = <0x4000 0x400>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges = <0x0 0x4000 0x400>;
|
||||
};
|
||||
|
||||
aiu: audio-controller@5400 {
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
index b2be52915..d925bdcc0 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
@@ -625,16 +625,18 @@ &gpio_intc {
|
||||
};
|
||||
|
||||
&hhi {
|
||||
- clkc: clock-controller {
|
||||
+ clkc: clock-controller@0 {
|
||||
compatible = "amlogic,meson8-clkc";
|
||||
+ reg = <0x0 0x39c>;
|
||||
clocks = <&xtal>, <&ddr_clkc DDR_CLKID_DDR_PLL>;
|
||||
clock-names = "xtal", "ddr_pll";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
- pwrc: power-controller {
|
||||
+ pwrc: power-controller@100 {
|
||||
compatible = "amlogic,meson8-pwrc";
|
||||
+ reg = <0x100 0x10>;
|
||||
#power-domain-cells = <1>;
|
||||
amlogic,ao-sysctrl = <&pmu>;
|
||||
clocks = <&clkc CLKID_VPU>;
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8b.dtsi b/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
index 2d9d24d3a..5ffedca99 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
@@ -586,16 +586,18 @@ &gpio_intc {
|
||||
};
|
||||
|
||||
&hhi {
|
||||
- clkc: clock-controller {
|
||||
+ clkc: clock-controller@0 {
|
||||
compatible = "amlogic,meson8b-clkc";
|
||||
+ reg = <0x0 0x39c>;
|
||||
clocks = <&xtal>, <&ddr_clkc DDR_CLKID_DDR_PLL>;
|
||||
clock-names = "xtal", "ddr_pll";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
- pwrc: power-controller {
|
||||
+ pwrc: power-controller@100 {
|
||||
compatible = "amlogic,meson8b-pwrc";
|
||||
+ reg = <0x100 0x10>;
|
||||
#power-domain-cells = <1>;
|
||||
amlogic,ao-sysctrl = <&pmu>;
|
||||
resets = <&reset RESET_DBLK>,
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
From 5e640e96e1224868456fda4cc2c9e8cca273a79c Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Mon, 17 May 2021 22:50:25 +0200
|
||||
Subject: [PATCH 29/96] dt-bindings: firmware: Document the Amlogic
|
||||
Meson6/8/8b/8m2 TrustZone
|
||||
|
||||
Amlogic Meson6/8/8b/8m2 SoCs can optionally use a TrustZone secure
|
||||
firmware. This prevents anything outside of the TEE (Trusted
|
||||
Execution Environment aka TrustZone secure firmware) from accessing
|
||||
certain functionality of these SoCs, such as (but not limited to):
|
||||
Bringing up/down secondary SMP cores, accessing the eFuse and getting
|
||||
the SoC misc version.
|
||||
ARM SMCCC is used for communication with the TrustZone secure
|
||||
firmware.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../amlogic,meson-mx-trustzone-firmware.yaml | 47 +++++++++++++++++++
|
||||
1 file changed, 47 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/firmware/meson/amlogic,meson-mx-trustzone-firmware.yaml
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/firmware/meson/amlogic,meson-mx-trustzone-firmware.yaml b/Documentation/devicetree/bindings/firmware/meson/amlogic,meson-mx-trustzone-firmware.yaml
|
||||
new file mode 100644
|
||||
index 000000000..1e0e19a35
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/firmware/meson/amlogic,meson-mx-trustzone-firmware.yaml
|
||||
@@ -0,0 +1,47 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
+# Copyright 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: "http://devicetree.org/schemas/firmware/meson/amlogic,meson-mx-trustzone-firmware.yaml#"
|
||||
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
+
|
||||
+title: Amlogic Meson6/8/8b/8m2 TrustZone secure firmware
|
||||
+
|
||||
+description: |
|
||||
+ Amlogic Meson6/8/8b/8m2 SoCs can optionally use a TrustZone secure
|
||||
+ firmware. This prevents anything outside of the TEE (Trusted
|
||||
+ Execution Environment aka TrustZone secure firmware) from accessing
|
||||
+ certain functionality of these SoCs, such as (but not limited to):
|
||||
+ Bringing up/down secondary SMP cores, accessing the eFuse and getting
|
||||
+ the SoC misc version.
|
||||
+ ARM SMCCC is used for communication with the TrustZone secure
|
||||
+ firmware.
|
||||
+
|
||||
+maintainers:
|
||||
+ - Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - amlogic,meson6-trustzone-firmware
|
||||
+ - amlogic,meson8-trustzone-firmware
|
||||
+ - amlogic,meson8b-trustzone-firmware
|
||||
+ - amlogic,meson8m2-trustzone-firmware
|
||||
+ - const: amlogic,meson-mx-trustzone-firmware
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ firmware {
|
||||
+ trustzone-firmware {
|
||||
+ compatible = "amlogic,meson8m2-trustzone-firmware",
|
||||
+ "amlogic,meson-mx-trustzone-firmware";
|
||||
+ };
|
||||
+ };
|
||||
+...
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From f753ee1373a56cee5d6c2e7c107a85822828c983 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 18 Dec 2021 16:38:16 +0100
|
||||
Subject: [PATCH 30/96] dt-bindings: arm: cpus: Document Meson8 TrustZone
|
||||
firmware enable-method
|
||||
|
||||
Amlogic Meson8 SoCs can run a TrustZone firmware. This results in the
|
||||
CPU registers not being accessible directly and instead require firmware
|
||||
calls for booting the secondary cores or powering off a CPU. Add a new
|
||||
compatible string for this enable-method.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/arm/cpus.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml
|
||||
index cc5a21b47..ec7593e04 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
|
||||
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
|
||||
@@ -216,6 +216,7 @@ properties:
|
||||
- allwinner,sun9i-a80-smp
|
||||
- allwinner,sun8i-a83t-smp
|
||||
- amlogic,meson8-smp
|
||||
+ - amlogic,meson8-trustzone-firmware-smp
|
||||
- amlogic,meson8b-smp
|
||||
- arm,realview-smp
|
||||
- aspeed,ast2600-smp
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,439 @@
|
||||
From 5499854ac2d2227951eb9e0437a5897d038cca97 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Mon, 3 May 2021 00:34:53 +0200
|
||||
Subject: [PATCH 31/96] ARM: meson: Add support for the TrustZone firmware
|
||||
|
||||
Amlogic Meson6/8/8b/8m2 SoCs can optionally use a TrustZone secure
|
||||
firmware. This prevents anything outside of the TEE (Trusted
|
||||
Execution Environment aka TrustZone secure firmware) from accessing
|
||||
certain functionality of these SoCs, such as (but not limited to):
|
||||
Bringing up/down secondary SMP cores, accessing the eFuse and getting
|
||||
the SoC misc version.
|
||||
ARM SMCCC is used for communication with the TrustZone secure
|
||||
firmware.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/mach-meson/Makefile | 2 +-
|
||||
arch/arm/mach-meson/meson.c | 4 +
|
||||
arch/arm/mach-meson/tz_firmware.c | 250 ++++++++++++++++++
|
||||
arch/arm/mach-meson/tz_firmware.h | 76 ++++++
|
||||
.../linux/firmware/meson/meson_mx_trustzone.h | 37 +++
|
||||
5 files changed, 368 insertions(+), 1 deletion(-)
|
||||
create mode 100644 arch/arm/mach-meson/tz_firmware.c
|
||||
create mode 100644 arch/arm/mach-meson/tz_firmware.h
|
||||
create mode 100644 include/linux/firmware/meson/meson_mx_trustzone.h
|
||||
|
||||
diff --git a/arch/arm/mach-meson/Makefile b/arch/arm/mach-meson/Makefile
|
||||
index 49cfbaee4..b8fe5f140 100644
|
||||
--- a/arch/arm/mach-meson/Makefile
|
||||
+++ b/arch/arm/mach-meson/Makefile
|
||||
@@ -1,3 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
-obj-$(CONFIG_ARCH_MESON) += meson.o
|
||||
+obj-$(CONFIG_ARCH_MESON) += meson.o tz_firmware.o
|
||||
obj-$(CONFIG_SMP) += platsmp.o
|
||||
diff --git a/arch/arm/mach-meson/meson.c b/arch/arm/mach-meson/meson.c
|
||||
index d3ae89dd8..45dae29a4 100644
|
||||
--- a/arch/arm/mach-meson/meson.c
|
||||
+++ b/arch/arm/mach-meson/meson.c
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
+#include "tz_firmware.h"
|
||||
+
|
||||
static const char * const meson_common_board_compat[] = {
|
||||
"amlogic,meson6",
|
||||
"amlogic,meson8",
|
||||
@@ -17,4 +19,6 @@ DT_MACHINE_START(MESON, "Amlogic Meson platform")
|
||||
.dt_compat = meson_common_board_compat,
|
||||
.l2c_aux_val = 0,
|
||||
.l2c_aux_mask = ~0,
|
||||
+ .init_early = meson_mx_trustzone_firmware_init,
|
||||
+ .reserve = meson_mx_trustzone_firmware_reserve_mem,
|
||||
MACHINE_END
|
||||
diff --git a/arch/arm/mach-meson/tz_firmware.c b/arch/arm/mach-meson/tz_firmware.c
|
||||
new file mode 100644
|
||||
index 000000000..9cdad4144
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-meson/tz_firmware.c
|
||||
@@ -0,0 +1,250 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (C) 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/arm-smccc.h>
|
||||
+#include <linux/firmware/meson/meson_mx_trustzone.h>
|
||||
+#include <linux/memblock.h>
|
||||
+#include <linux/of.h>
|
||||
+
|
||||
+#include <asm/firmware.h>
|
||||
+#include <asm/hardware/cache-l2x0.h>
|
||||
+#include <asm/outercache.h>
|
||||
+
|
||||
+#include "tz_firmware.h"
|
||||
+
|
||||
+struct meson_mx_trustzone_firmware_memconfig {
|
||||
+ unsigned char name[64];
|
||||
+ unsigned int start_phy_addr;
|
||||
+ unsigned int end_phy_addr;
|
||||
+} __packed;
|
||||
+
|
||||
+static struct meson_mx_trustzone_firmware_memconfig meson_firmware_memconfig[2];
|
||||
+
|
||||
+static int meson_mx_trustzone_firmware_hal_api(unsigned int cmd, u32 *args)
|
||||
+{
|
||||
+ struct arm_smccc_res res;
|
||||
+
|
||||
+ arm_smccc_smc(MESON_CALL_TRUSTZONE_HAL_API, cmd, virt_to_phys(args), 0,
|
||||
+ 0, 0, 0, 0, &res);
|
||||
+
|
||||
+ return res.a0;
|
||||
+}
|
||||
+
|
||||
+static u32 meson_mx_trustzone_firmware_mon(unsigned int cmd, unsigned int arg0,
|
||||
+ unsigned int arg1)
|
||||
+{
|
||||
+ struct arm_smccc_res res;
|
||||
+
|
||||
+ arm_smccc_smc(MESON_CALL_TRUSTZONE_MON, cmd, arg0, arg1, 0, 0, 0, 0,
|
||||
+ &res);
|
||||
+
|
||||
+ return res.a0;
|
||||
+}
|
||||
+
|
||||
+static int meson_mx_trustzone_firmware_set_cpu_boot_addr(int cpu,
|
||||
+ unsigned long boot_addr){
|
||||
+ return meson_mx_trustzone_firmware_mon(MESON_TRUSTZONE_MON_CORE_BOOTADDR_INDEX,
|
||||
+ cpu, boot_addr);
|
||||
+}
|
||||
+
|
||||
+static int meson_mx_trustzone_firmware_cpu_boot(int cpu)
|
||||
+{
|
||||
+ u32 ret, corectrl;
|
||||
+
|
||||
+ corectrl = meson_mx_trustzone_firmware_mon(MESON_TRUSTZONE_MON_CORE_RD_CTRL_INDEX,
|
||||
+ 0, 0);
|
||||
+
|
||||
+ corectrl |= BIT(cpu);
|
||||
+
|
||||
+ ret = meson_mx_trustzone_firmware_mon(MESON_TRUSTZONE_MON_CORE_WR_CTRL_INDEX,
|
||||
+ corectrl, 0);
|
||||
+ if (ret != corectrl)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void meson_mx_trustzone_firmware_l2x0_write_sec(unsigned long val,
|
||||
+ unsigned int reg)
|
||||
+{
|
||||
+ u32 fn;
|
||||
+
|
||||
+ switch (reg) {
|
||||
+ case L2X0_CTRL:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_CTRL_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ case L2X0_AUX_CTRL:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_AUXCTRL_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ case L310_TAG_LATENCY_CTRL:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_TAGLATENCY_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ case L310_DATA_LATENCY_CTRL:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_DATALATENCY_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ case L310_ADDR_FILTER_START:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_FILTERSTART_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ case L310_ADDR_FILTER_END:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_FILTEREND_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ case L2X0_DEBUG_CTRL:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_DEBUG_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ case L310_PREFETCH_CTRL:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_PREFETCH_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ case L310_POWER_CTRL:
|
||||
+ fn = MESON_TRUSTZONE_MON_L2X0_POWER_INDEX;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ pr_warn("Amlogic Meson TrustZone - unsupported L2X0 register 0x%08x\n",
|
||||
+ reg);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ WARN_ON(meson_mx_trustzone_firmware_mon(fn, val, 0));
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused meson_mx_trustzone_firmware_l2x0_init(void)
|
||||
+{
|
||||
+ if (IS_ENABLED(CONFIG_CACHE_L2X0))
|
||||
+ outer_cache.write_sec = meson_mx_trustzone_firmware_l2x0_write_sec;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct firmware_ops meson_mx_trustzone_firmware_ops = {
|
||||
+ .set_cpu_boot_addr = meson_mx_trustzone_firmware_set_cpu_boot_addr,
|
||||
+ .cpu_boot = meson_mx_trustzone_firmware_cpu_boot,
|
||||
+ .l2x0_init = meson_mx_trustzone_firmware_l2x0_init,
|
||||
+};
|
||||
+
|
||||
+void __init meson_mx_trustzone_firmware_init(void)
|
||||
+{
|
||||
+ if (!meson_mx_trustzone_firmware_available())
|
||||
+ return;
|
||||
+
|
||||
+ pr_info("Running under Amlogic Meson TrustZone secure firmware.\n");
|
||||
+
|
||||
+ register_firmware_ops(&meson_mx_trustzone_firmware_ops);
|
||||
+
|
||||
+ call_firmware_op(l2x0_init);
|
||||
+}
|
||||
+
|
||||
+static void __init meson_mx_trustzone_firmware_memconfig_init(void)
|
||||
+{
|
||||
+ unsigned int i, size;
|
||||
+ u32 args[2] = {
|
||||
+ __pa_symbol(meson_firmware_memconfig),
|
||||
+ ARRAY_SIZE(meson_firmware_memconfig),
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = meson_mx_trustzone_firmware_hal_api(MESON_TRUSTZONE_HAL_API_MEMCONFIG,
|
||||
+ args);
|
||||
+ if (ret) {
|
||||
+ pr_err("Amlogic Meson TrustZone memconfig failed: %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(meson_firmware_memconfig); i++) {
|
||||
+ size = meson_firmware_memconfig[i].end_phy_addr -
|
||||
+ meson_firmware_memconfig[i].start_phy_addr;
|
||||
+
|
||||
+ pr_debug("\tAmlogic Meson TrustZone memblock[%d]: %s (%u bytes)\n",
|
||||
+ i, meson_firmware_memconfig[i].name, size);
|
||||
+
|
||||
+ ret = memblock_mark_nomap(meson_firmware_memconfig[i].start_phy_addr,
|
||||
+ size);
|
||||
+ if (ret)
|
||||
+ pr_err("Failed to reserve %u bytes for Amlogic Meson TrustZone memblock[%d] (%s): %d\n",
|
||||
+ size, i, meson_firmware_memconfig[i].name, ret);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void __init meson_mx_trustzone_firmware_monitor_memory_init(void)
|
||||
+{
|
||||
+ u32 base, size;
|
||||
+ int ret;
|
||||
+
|
||||
+ base = meson_mx_trustzone_firmware_mon(MESON_TRUSTZONE_MON_MEM_BASE,
|
||||
+ 0, 0);
|
||||
+ WARN_ON(!base);
|
||||
+
|
||||
+ size = meson_mx_trustzone_firmware_mon(MESON_TRUSTZONE_MON_MEM_TOTAL_SIZE,
|
||||
+ 0, 0);
|
||||
+ WARN_ON(!size);
|
||||
+
|
||||
+ ret = memblock_mark_nomap(base, size);
|
||||
+ if (ret)
|
||||
+ pr_err("Failed to reserve %u bytes of Amlogic Meson TrustZone monitor memory: %d\n",
|
||||
+ size, ret);
|
||||
+}
|
||||
+
|
||||
+void __init meson_mx_trustzone_firmware_reserve_mem(void)
|
||||
+{
|
||||
+ if (!meson_mx_trustzone_firmware_available())
|
||||
+ return;
|
||||
+
|
||||
+ meson_mx_trustzone_firmware_monitor_memory_init();
|
||||
+ meson_mx_trustzone_firmware_memconfig_init();
|
||||
+}
|
||||
+
|
||||
+bool meson_mx_trustzone_firmware_available(void)
|
||||
+{
|
||||
+ struct device_node *np;
|
||||
+
|
||||
+ np = of_find_compatible_node(NULL, NULL,
|
||||
+ "amlogic,meson-mx-trustzone-firmware");
|
||||
+ if (!np)
|
||||
+ return false;
|
||||
+
|
||||
+ of_node_put(np);
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(meson_mx_trustzone_firmware_available);
|
||||
+
|
||||
+int meson_mx_trustzone_firmware_efuse_read(unsigned int offset,
|
||||
+ unsigned int bytes, void *buf)
|
||||
+{
|
||||
+ unsigned int read_bytes;
|
||||
+ u32 args[5] = {
|
||||
+ MESON_TRUSTZONE_HAL_API_EFUSE_CMD_READ,
|
||||
+ offset,
|
||||
+ bytes,
|
||||
+ __pa_symbol(buf),
|
||||
+ virt_to_phys(&read_bytes)
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = meson_mx_trustzone_firmware_hal_api(MESON_TRUSTZONE_HAL_API_EFUSE,
|
||||
+ args);
|
||||
+ if (ret)
|
||||
+ return -EIO;
|
||||
+
|
||||
+ if (read_bytes != bytes)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(meson_mx_trustzone_firmware_efuse_read);
|
||||
+
|
||||
+u32 meson_mx_trustzone_read_soc_rev1(void)
|
||||
+{
|
||||
+ return meson_mx_trustzone_firmware_mon(MESON_TRUSTZONE_MON_CORE_RD_SOC_REV1,
|
||||
+ 0, 0);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(meson_mx_trustzone_read_soc_rev1);
|
||||
diff --git a/arch/arm/mach-meson/tz_firmware.h b/arch/arm/mach-meson/tz_firmware.h
|
||||
new file mode 100644
|
||||
index 000000000..a9da3c84a
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-meson/tz_firmware.h
|
||||
@@ -0,0 +1,76 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
+/*
|
||||
+ * Amlogic Meson6/8/8b/8m2 secure TrustZone firmware definitions.
|
||||
+ *
|
||||
+ * Based on meson-secure.c and meson-secure.h from the Amlogic vendor kernel:
|
||||
+ * Copyright (C) 2002 ARM Ltd.
|
||||
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
|
||||
+ * Copyright (C) 2013 Amlogic, Inc.
|
||||
+ * Author: Platform-SH@amlogic.com
|
||||
+ *
|
||||
+ * Copyright (C) 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
+ */
|
||||
+
|
||||
+/* Meson Secure Monitor/HAL APIs */
|
||||
+#define MESON_CALL_TRUSTZONE_API 0x1
|
||||
+#define MESON_CALL_TRUSTZONE_MON 0x4
|
||||
+#define MESON_CALL_TRUSTZONE_HAL_API 0x5
|
||||
+
|
||||
+/* Secure Monitor mode APIs */
|
||||
+#define MESON_TRUSTZONE_MON_TYPE_MASK 0xF00
|
||||
+#define MESON_TRUSTZONE_MON_FUNC_MASK 0x0FF
|
||||
+
|
||||
+#define MESON_TRUSTZONE_MON_L2X0 0x100
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_CTRL_INDEX 0x101
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_AUXCTRL_INDEX 0x102
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_PREFETCH_INDEX 0x103
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_TAGLATENCY_INDEX 0x104
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_DATALATENCY_INDEX 0x105
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_FILTERSTART_INDEX 0x106
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_FILTEREND_INDEX 0x107
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_DEBUG_INDEX 0x108
|
||||
+#define MESON_TRUSTZONE_MON_L2X0_POWER_INDEX 0x109
|
||||
+
|
||||
+#define MESON_TRUSTZONE_MON_CORE 0x200
|
||||
+#define MESON_TRUSTZONE_MON_CORE_RD_CTRL_INDEX 0x201
|
||||
+#define MESON_TRUSTZONE_MON_CORE_WR_CTRL_INDEX 0x202
|
||||
+#define MESON_TRUSTZONE_MON_CORE_RD_STATUS0_INDEX 0x203
|
||||
+#define MESON_TRUSTZONE_MON_CORE_WR_STATUS0_INDEX 0x204
|
||||
+#define MESON_TRUSTZONE_MON_CORE_RD_STATUS1_INDEX 0x205
|
||||
+#define MESON_TRUSTZONE_MON_CORE_WR_STATUS1_INDEX 0x206
|
||||
+#define MESON_TRUSTZONE_MON_CORE_BOOTADDR_INDEX 0x207
|
||||
+#define MESON_TRUSTZONE_MON_CORE_DDR_INDEX 0x208
|
||||
+#define MESON_TRUSTZONE_MON_CORE_RD_SOC_REV1 0x209
|
||||
+#define MESON_TRUSTZONE_MON_CORE_RD_SOC_REV2 0x20A
|
||||
+
|
||||
+#define MESON_TRUSTZONE_MON_SUSPEND_FIRMWARE 0x300
|
||||
+#define MESON_TRUSTZONE_MON_SAVE_CPU_GIC 0x400
|
||||
+
|
||||
+#define MESON_TRUSTZONE_MON_RTC 0x500
|
||||
+#define MESON_TRUSTZONE_MON_RTC_RD_REG_INDEX 0x501
|
||||
+#define MESON_TRUSTZONE_MON_RTC_WR_REG_INDEX 0x502
|
||||
+
|
||||
+#define MESON_TRUSTZONE_MON_REG 0x600
|
||||
+#define MESON_TRUSTZONE_MON_REG_RD_INDEX 0x601
|
||||
+#define MESON_TRUSTZONE_MON_REG_WR_INDEX 0x602
|
||||
+
|
||||
+#define MESON_TRUSTZONE_MON_MEM 0x700
|
||||
+#define MESON_TRUSTZONE_MON_MEM_BASE 0x701
|
||||
+#define MESON_TRUSTZONE_MON_MEM_TOTAL_SIZE 0x702
|
||||
+#define MESON_TRUSTZONE_MON_MEM_FLASH 0x703
|
||||
+#define MESON_TRUSTZONE_MON_MEM_FLASH_SIZE 0x704
|
||||
+#define MESON_TRUSTZONE_MON_MEM_GE2D 0x705
|
||||
+
|
||||
+/* Secure HAL APIs*/
|
||||
+#define MESON_TRUSTZONE_HAL_API_EFUSE 0x100
|
||||
+#define MESON_TRUSTZONE_HAL_API_EFUSE_CMD_READ 0x0
|
||||
+#define MESON_TRUSTZONE_HAL_API_EFUSE_CMD_WRITE 0x1
|
||||
+#define MESON_TRUSTZONE_HAL_API_EFUSE_CMD_VERIFY_IMG 0x3
|
||||
+
|
||||
+#define MESON_TRUSTZONE_HAL_API_STORAGE 0x200
|
||||
+
|
||||
+#define MESON_TRUSTZONE_HAL_API_MEMCONFIG 0x300
|
||||
+#define MESON_TRUSTZONE_HAL_API_MEMCONFIG_GE2D 0x301
|
||||
+
|
||||
+void __init meson_mx_trustzone_firmware_init(void);
|
||||
+void __init meson_mx_trustzone_firmware_reserve_mem(void);
|
||||
diff --git a/include/linux/firmware/meson/meson_mx_trustzone.h b/include/linux/firmware/meson/meson_mx_trustzone.h
|
||||
new file mode 100644
|
||||
index 000000000..947463050
|
||||
--- /dev/null
|
||||
+++ b/include/linux/firmware/meson/meson_mx_trustzone.h
|
||||
@@ -0,0 +1,37 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Copyright (C) 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_MESON)
|
||||
+
|
||||
+bool meson_mx_trustzone_firmware_available(void);
|
||||
+
|
||||
+int meson_mx_trustzone_firmware_efuse_read(unsigned int offset,
|
||||
+ unsigned int bytes, void *buf);
|
||||
+
|
||||
+u32 meson_mx_trustzone_read_soc_rev1(void);
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+static inline bool meson_mx_trustzone_firmware_available(void)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static inline int meson_mx_trustzone_firmware_efuse_read(unsigned int offset,
|
||||
+ unsigned int bytes,
|
||||
+ void *buf)
|
||||
+{
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static inline u32 meson_mx_trustzone_read_soc_rev1(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
From 342867fae2835ccac6edc355c6d115f9e69a4eeb Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Mon, 3 May 2021 08:36:16 +0200
|
||||
Subject: [PATCH 32/96] ARM: meson: platsmp: Add support for SoCs running on
|
||||
TrustZone firmware
|
||||
|
||||
When the SoC is running on the TrustZone firmware we cannot modify the
|
||||
SMP related registers. Add a new set of SMP ops which use firmware calls
|
||||
to set the startup (function) address and core control (on/off).
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/mach-meson/platsmp.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/mach-meson/platsmp.c b/arch/arm/mach-meson/platsmp.c
|
||||
index 32ac60b89..3e38066fc 100644
|
||||
--- a/arch/arm/mach-meson/platsmp.c
|
||||
+++ b/arch/arm/mach-meson/platsmp.c
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cp15.h>
|
||||
+#include <asm/firmware.h>
|
||||
#include <asm/smp_scu.h>
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
@@ -291,6 +292,31 @@ static int meson8b_smp_boot_secondary(unsigned int cpu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int meson8_smp_trustzone_firmware_boot_secondary(unsigned int cpu,
|
||||
+ struct task_struct *idle)
|
||||
+{
|
||||
+ unsigned int addr = __pa_symbol(secondary_startup);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = call_firmware_op(set_cpu_boot_addr, cpu, addr);
|
||||
+ if (ret) {
|
||||
+ pr_err("Failed to set aux core boot address for CPU%u using TrustZone secure firmware\n",
|
||||
+ cpu);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = call_firmware_op(cpu_boot, cpu);
|
||||
+ if (ret) {
|
||||
+ pr_err("Failed to modify core control for CPU%u using TrustZone secure firmware\n",
|
||||
+ cpu);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ udelay(10);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static void meson8_smp_cpu_die(unsigned int cpu)
|
||||
{
|
||||
@@ -428,5 +454,12 @@ static struct smp_operations meson8b_smp_ops __initdata = {
|
||||
#endif
|
||||
};
|
||||
|
||||
+static struct smp_operations meson8_smp_trustzone_firmware_ops __initdata = {
|
||||
+ .smp_boot_secondary = meson8_smp_trustzone_firmware_boot_secondary,
|
||||
+};
|
||||
+
|
||||
CPU_METHOD_OF_DECLARE(meson8_smp, "amlogic,meson8-smp", &meson8_smp_ops);
|
||||
CPU_METHOD_OF_DECLARE(meson8b_smp, "amlogic,meson8b-smp", &meson8b_smp_ops);
|
||||
+CPU_METHOD_OF_DECLARE(meson8_trustzone_firmware_smp,
|
||||
+ "amlogic,meson8-trustzone-firmware-smp",
|
||||
+ &meson8_smp_trustzone_firmware_ops);
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
From 77011250fbd490a4b85363f62e7c4e639191a4ec Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sun, 16 May 2021 19:48:54 +0200
|
||||
Subject: [PATCH 33/96] soc: amlogic: meson-mx-socinfo: Add support for the
|
||||
TrustZone firmware
|
||||
|
||||
When the TrustZone firmware is enabled the SoC is configured so the boot
|
||||
ROM cannot be read from the (untrusted) Linux kernel. Instead a firmware
|
||||
call needs to be used to get the SoC's "misc" version.
|
||||
Add support for the firmware call to retrieve the SoC's misc version if
|
||||
the TrustZone firmware is loaded.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/soc/amlogic/meson-mx-socinfo.c | 23 +++++++++++++++--------
|
||||
1 file changed, 15 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/amlogic/meson-mx-socinfo.c b/drivers/soc/amlogic/meson-mx-socinfo.c
|
||||
index 92125dd65..25503bdd7 100644
|
||||
--- a/drivers/soc/amlogic/meson-mx-socinfo.c
|
||||
+++ b/drivers/soc/amlogic/meson-mx-socinfo.c
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
+#include <linux/firmware/meson/meson_mx_trustzone.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
@@ -118,10 +119,12 @@ static int __init meson_mx_socinfo_init(void)
|
||||
if (IS_ERR(assist_regmap))
|
||||
return PTR_ERR(assist_regmap);
|
||||
|
||||
- bootrom_regmap =
|
||||
- syscon_regmap_lookup_by_compatible("amlogic,meson-mx-bootrom");
|
||||
- if (IS_ERR(bootrom_regmap))
|
||||
- return PTR_ERR(bootrom_regmap);
|
||||
+ if (!meson_mx_trustzone_firmware_available()) {
|
||||
+ bootrom_regmap =
|
||||
+ syscon_regmap_lookup_by_compatible("amlogic,meson-mx-bootrom");
|
||||
+ if (IS_ERR(bootrom_regmap))
|
||||
+ return PTR_ERR(bootrom_regmap);
|
||||
+ }
|
||||
|
||||
np = of_find_matching_node(NULL, meson_mx_socinfo_analog_top_ids);
|
||||
if (np) {
|
||||
@@ -141,10 +144,14 @@ static int __init meson_mx_socinfo_init(void)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- ret = regmap_read(bootrom_regmap, MESON_MX_BOOTROM_MISC_VER,
|
||||
- &misc_ver);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
+ if (meson_mx_trustzone_firmware_available()) {
|
||||
+ misc_ver = meson_mx_trustzone_read_soc_rev1();
|
||||
+ } else {
|
||||
+ ret = regmap_read(bootrom_regmap, MESON_MX_BOOTROM_MISC_VER,
|
||||
+ &misc_ver);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
||||
if (!soc_dev_attr)
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
From a6e38e2f0cc7be7d75ed8b9895e7bc7af99d0fe0 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Mon, 3 May 2021 00:35:22 +0200
|
||||
Subject: [PATCH 34/96] nvmem: meson-mx-efuse: Add support for the TrustZone
|
||||
firmware interface
|
||||
|
||||
Some boards have a TrustZone firmware which prevents us from accessing
|
||||
(most of) the eFuse registers. On these boards we must use read the
|
||||
eFuse through TrustZone firmware calls (using SMC).
|
||||
Implement a .reg_read op using the Meson TrustZone firmware interface.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/nvmem/meson-mx-efuse.c | 29 ++++++++++++++++++++++++++++-
|
||||
1 file changed, 28 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c
|
||||
index 3ff04d5ca..1a08f5541 100644
|
||||
--- a/drivers/nvmem/meson-mx-efuse.c
|
||||
+++ b/drivers/nvmem/meson-mx-efuse.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
+#include <linux/firmware/meson/meson_mx_trustzone.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
@@ -166,6 +167,28 @@ static int meson_mx_efuse_read(void *context, unsigned int offset,
|
||||
return err;
|
||||
}
|
||||
|
||||
+static int meson_mx_efuse_read_trustzone_firmware(void *context,
|
||||
+ unsigned int offset,
|
||||
+ void *buf, size_t bytes)
|
||||
+{
|
||||
+ struct meson_mx_efuse *efuse = context;
|
||||
+ unsigned int tmp;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 0; i < bytes; i += efuse->config.word_size) {
|
||||
+ ret = meson_mx_trustzone_firmware_efuse_read(offset + i,
|
||||
+ sizeof(tmp),
|
||||
+ &tmp);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ memcpy(buf + i, &tmp,
|
||||
+ min_t(size_t, bytes - i, efuse->config.word_size));
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct meson_mx_efuse_platform_data meson6_efuse_data = {
|
||||
.name = "meson6-efuse",
|
||||
.word_size = 1,
|
||||
@@ -215,7 +238,11 @@ static int meson_mx_efuse_probe(struct platform_device *pdev)
|
||||
efuse->config.word_size = drvdata->word_size;
|
||||
efuse->config.size = SZ_512;
|
||||
efuse->config.read_only = true;
|
||||
- efuse->config.reg_read = meson_mx_efuse_read;
|
||||
+
|
||||
+ if (meson_mx_trustzone_firmware_available())
|
||||
+ efuse->config.reg_read = meson_mx_efuse_read_trustzone_firmware;
|
||||
+ else
|
||||
+ efuse->config.reg_read = meson_mx_efuse_read;
|
||||
|
||||
efuse->core_clk = devm_clk_get(&pdev->dev, "core");
|
||||
if (IS_ERR(efuse->core_clk)) {
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From 77298a6b2e7937abfefb0514469b03c223cb6414 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Thu, 22 Jul 2021 08:27:29 +0200
|
||||
Subject: [PATCH 36/96] ARM: dts: meson8: Add the PWM_C (DV9) and PWM_D pins
|
||||
|
||||
There are some Meson8m2 boards which don't use a PMIC (like Ricoh
|
||||
RN5T618) but use two PWM regulators for VCCK and VDDEE. Add the PWM_C
|
||||
(DV9) and PWM_D pins so the pinctrl settings can be applied on those
|
||||
boards.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson8.dtsi | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
index d925bdcc0..454c35530 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
@@ -479,6 +479,22 @@ gpio: banks@80b0 {
|
||||
gpio-ranges = <&pinctrl_cbus 0 0 120>;
|
||||
};
|
||||
|
||||
+ pwm_c_dv9_pins: pwm-c-dv9 {
|
||||
+ mux {
|
||||
+ groups = "pwm_c_dv9";
|
||||
+ function = "pwm_c";
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pwm_d_pins: pwm-d {
|
||||
+ mux {
|
||||
+ groups = "pwm_d";
|
||||
+ function = "pwm_d";
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
sd_a_pins: sd-a {
|
||||
mux {
|
||||
groups = "sd_d0_a", "sd_d1_a", "sd_d2_a",
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
From 875ed8762a46e7f0fd143b58a3002c3a76b805cd Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Apr 2020 22:16:15 +0200
|
||||
Subject: [PATCH 45/96] dt-bindings: display: meson-vpu: add support for
|
||||
Meson8/8b/8m2 - WiP
|
||||
|
||||
WiP
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
.../devicetree/bindings/display/amlogic,meson-vpu.yaml | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
|
||||
index c9ab01434..96c32747e 100644
|
||||
--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
|
||||
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
|
||||
@@ -66,8 +66,12 @@ properties:
|
||||
- const: amlogic,meson-gx-vpu
|
||||
- enum:
|
||||
- amlogic,meson-g12a-vpu # G12A (S905X2, S905Y2, S905D2)
|
||||
+ - amlogic,meson8-vpu
|
||||
+ - amlogic,meson8b-vpu
|
||||
+ - amlogic,meson8m2-vpu
|
||||
|
||||
reg:
|
||||
+ minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From f4fdd1b75e3ad64c9903a42aeeb9e45a1ad10780 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Apr 2020 21:50:45 +0200
|
||||
Subject: [PATCH 46/96] drm/meson: add Meson8/Meson8b/Meson8m2 specific
|
||||
vpu_compatible entries
|
||||
|
||||
Add values for Meson8/Meson8b/Meson8m2 to enum vpu_compatible so quirks
|
||||
for these earlier hardware generations can be added to the driver.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_drv.h | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
|
||||
index 69be4c67f..8e1c01242 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.h
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.h
|
||||
@@ -20,10 +20,13 @@ struct phy;
|
||||
struct platform_device;
|
||||
|
||||
enum vpu_compatible {
|
||||
- VPU_COMPATIBLE_GXBB = 0,
|
||||
- VPU_COMPATIBLE_GXL = 1,
|
||||
- VPU_COMPATIBLE_GXM = 2,
|
||||
- VPU_COMPATIBLE_G12A = 3,
|
||||
+ VPU_COMPATIBLE_M8 = 0,
|
||||
+ VPU_COMPATIBLE_M8B = 1,
|
||||
+ VPU_COMPATIBLE_M8M2 = 2,
|
||||
+ VPU_COMPATIBLE_GXBB = 3,
|
||||
+ VPU_COMPATIBLE_GXL = 4,
|
||||
+ VPU_COMPATIBLE_GXM = 5,
|
||||
+ VPU_COMPATIBLE_G12A = 6,
|
||||
};
|
||||
|
||||
enum {
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
From 31af191867e9272d80820cc452e3c209a24713fa Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sun, 26 Apr 2020 00:00:09 +0200
|
||||
Subject: [PATCH 47/96] drm/meson: Use 24 bits per pixel for the framebuffer on
|
||||
Meson8/8b/8m2
|
||||
|
||||
All SoC generations before GXBB don't have a way to configure the
|
||||
alpha value for DRM_FORMAT_XRGB8888 and DRM_FORMAT_XBGR8888. These
|
||||
formats have an X component instead of an alpha component. On
|
||||
Meson8/8b/8m2 there is no way to configure the alpha value to use
|
||||
instead of the X component. This results in the fact that the
|
||||
formats with X component are only supported on GXBB and newer. Use
|
||||
24 bits per pixel and therefore DRM_FORMAT_RGB888 to get a
|
||||
working framebuffer console.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_drv.c | 26 +++++++++++++++++++++++++-
|
||||
1 file changed, 25 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
|
||||
index 17a5cca00..60298cf3b 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.c
|
||||
@@ -159,6 +159,30 @@ static void meson_vpu_init(struct meson_drm *priv)
|
||||
writel_relaxed(value, priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
|
||||
}
|
||||
|
||||
+static void meson_fbdev_setup(struct meson_drm *priv)
|
||||
+{
|
||||
+ unsigned int preferred_bpp;
|
||||
+
|
||||
+ /*
|
||||
+ * All SoC generations before GXBB don't have a way to configure the
|
||||
+ * alpha value for DRM_FORMAT_XRGB8888 and DRM_FORMAT_XBGR8888. These
|
||||
+ * formats have an X component instead of an alpha component. On
|
||||
+ * Meson8/8b/8m2 there is no way to configure the alpha value to use
|
||||
+ * instead of the X component. This results in the fact that the
|
||||
+ * formats with X component are only supported on GXBB and newer. Use
|
||||
+ * 24 bits per pixel and therefore DRM_FORMAT_RGB888 to get a
|
||||
+ * working framebuffer console.
|
||||
+ */
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2))
|
||||
+ preferred_bpp = 24;
|
||||
+ else
|
||||
+ preferred_bpp = 32;
|
||||
+
|
||||
+ drm_fbdev_dma_setup(priv->drm, preferred_bpp);
|
||||
+}
|
||||
+
|
||||
struct meson_drm_soc_attr {
|
||||
struct meson_drm_soc_limits limits;
|
||||
const struct soc_device_attribute *attrs;
|
||||
@@ -362,7 +386,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
|
||||
if (ret)
|
||||
goto uninstall_irq;
|
||||
|
||||
- drm_fbdev_dma_setup(drm, 32);
|
||||
+ meson_fbdev_setup(priv);
|
||||
|
||||
return 0;
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
From fc19ccbb10a7f76c8ad92571f306782c4afebe3c Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Apr 2020 21:53:21 +0200
|
||||
Subject: [PATCH 48/96] drm/meson: Use a separate list of supported formats for
|
||||
32-bit SoCs
|
||||
|
||||
The VIU_OSD1_CTRL_STAT2 and VIU_OSD2_CTRL_STAT2 registers on
|
||||
Meson8/Meson8b/Meson8m2 don't have the following bits:
|
||||
- replaced_alpha_en in bit [14]
|
||||
- replaced_alpha in bits [13:6]
|
||||
|
||||
This results in formats with X component (currently DRM_FORMAT_XRGB8888
|
||||
and DRM_FORMAT_XBGR8888 are supported on GXBB and later) are not
|
||||
supported. Depending on the application this may work (kmscube for
|
||||
example - which seems to properly set 0xff as alpha component), but
|
||||
there's other examples (Kodi for example) where there are alpha blending
|
||||
issues because the alpha value is not defined (and thus some random
|
||||
value).
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_plane.c | 30 ++++++++++++++++++++++++++---
|
||||
1 file changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
|
||||
index 815dfe304..e71503609 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_plane.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_plane.c
|
||||
@@ -471,7 +471,20 @@ static const struct drm_plane_funcs meson_plane_funcs = {
|
||||
.format_mod_supported = meson_plane_format_mod_supported,
|
||||
};
|
||||
|
||||
-static const uint32_t supported_drm_formats[] = {
|
||||
+/*
|
||||
+ * X components (for example in DRM_FORMAT_XRGB8888 and DRM_FORMAT_XBGR8888)
|
||||
+ * are not supported because these older SoC's are lacking the OSD_REPLACE_EN
|
||||
+ * bit to replace the X alpha component with a static value, leaving the alpha
|
||||
+ * component in an undefined state.
|
||||
+ */
|
||||
+static const uint32_t supported_drm_formats_m8[] = {
|
||||
+ DRM_FORMAT_ARGB8888,
|
||||
+ DRM_FORMAT_ABGR8888,
|
||||
+ DRM_FORMAT_RGB888,
|
||||
+ DRM_FORMAT_RGB565,
|
||||
+};
|
||||
+
|
||||
+static const uint32_t supported_drm_formats_gx[] = {
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
@@ -533,6 +546,8 @@ int meson_plane_create(struct meson_drm *priv)
|
||||
{
|
||||
struct meson_plane *meson_plane;
|
||||
struct drm_plane *plane;
|
||||
+ unsigned int num_drm_formats;
|
||||
+ const uint32_t *drm_formats;
|
||||
const uint64_t *format_modifiers = format_modifiers_default;
|
||||
|
||||
meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane),
|
||||
@@ -548,10 +563,19 @@ int meson_plane_create(struct meson_drm *priv)
|
||||
else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
|
||||
format_modifiers = format_modifiers_afbc_g12a;
|
||||
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) {
|
||||
+ drm_formats = supported_drm_formats_m8;
|
||||
+ num_drm_formats = ARRAY_SIZE(supported_drm_formats_m8);
|
||||
+ } else {
|
||||
+ drm_formats = supported_drm_formats_gx;
|
||||
+ num_drm_formats = ARRAY_SIZE(supported_drm_formats_gx);
|
||||
+ }
|
||||
+
|
||||
drm_universal_plane_init(priv->drm, plane, 0xFF,
|
||||
&meson_plane_funcs,
|
||||
- supported_drm_formats,
|
||||
- ARRAY_SIZE(supported_drm_formats),
|
||||
+ drm_formats, num_drm_formats,
|
||||
format_modifiers,
|
||||
DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
From 4fec04a45ba08241d76deaa2640aad5be1743683 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Mon, 31 Jan 2022 23:02:59 +0100
|
||||
Subject: [PATCH 49/96] drm/meson: Skip VIU_OSD1_CTRL_STAT2 alpha replace value
|
||||
initialization
|
||||
|
||||
The VIU_OSD1_CTRL_STAT2 and VIU_OSD2_CTRL_STAT2 registers on
|
||||
Meson8/Meson8b/Meson8m2 don't have the following bits:
|
||||
- replaced_alpha_en in bit [14]
|
||||
- replaced_alpha in bits [13:6]
|
||||
|
||||
Don't initialize the replaced_alpha register bits in VIU_OSD1_CTRL_STAT2
|
||||
on Meson8/Meson8b/Meson8m2 because they are not implemented on those
|
||||
SoCs.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_viu.c | 18 +++++++++++-------
|
||||
1 file changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
|
||||
index cd399b0b7..bdfa342c4 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_viu.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_viu.c
|
||||
@@ -448,13 +448,17 @@ void meson_viu_init(struct meson_drm *priv)
|
||||
writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
|
||||
writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
|
||||
|
||||
- /* Set OSD alpha replace value */
|
||||
- writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
|
||||
- 0xff << OSD_REPLACE_SHIFT,
|
||||
- priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
|
||||
- writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
|
||||
- 0xff << OSD_REPLACE_SHIFT,
|
||||
- priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
|
||||
+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) &&
|
||||
+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) &&
|
||||
+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) {
|
||||
+ /* Set OSD alpha replace value */
|
||||
+ writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
|
||||
+ 0xff << OSD_REPLACE_SHIFT,
|
||||
+ priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
|
||||
+ writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
|
||||
+ 0xff << OSD_REPLACE_SHIFT,
|
||||
+ priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
|
||||
+ }
|
||||
|
||||
/* Disable VD1 AFBC */
|
||||
/* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From a7583cc8a459b072fb3613f204143bcfccd18849 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Apr 2020 22:00:57 +0200
|
||||
Subject: [PATCH 50/96] drm/meson: Enable the RGB to YUV converter on
|
||||
Meson8/Meson8b/Meson8m2
|
||||
|
||||
Set VIU_OSD1_BLK0_CFG_W0[7] to 1 to enable RGB to YUV converter, just
|
||||
like on GXBB.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_plane.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
|
||||
index e71503609..27e395772 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_plane.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_plane.c
|
||||
@@ -200,8 +200,11 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
||||
priv->viu.osd1_ctrl_stat2 &= ~OSD_DPATH_MALI_AFBCD;
|
||||
}
|
||||
|
||||
- /* On GXBB, Use the old non-HDR RGB2YUV converter */
|
||||
- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
|
||||
+ /* On GXBB and earlier, Use the old non-HDR RGB2YUV converter */
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
|
||||
priv->viu.osd1_blk0_cfg[0] |= OSD_OUTPUT_COLOR_RGB;
|
||||
|
||||
if (priv->viu.osd1_afbcd &&
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
From 8b09602979c279f579ced2d5234f878e8e9243bb Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Apr 2020 22:03:27 +0200
|
||||
Subject: [PATCH 51/96] drm/meson: Update meson_vpu_init to work with
|
||||
Meson8/Meson8b/Meson8m2
|
||||
|
||||
Don't modify the VPU_RDARB_MODE_* registers because they only exist on
|
||||
GXBB and newer SoCs. Initialize the VPU_MEM_PD_REG0 and VPU_MEM_PD_REG1
|
||||
to 0x0 (meaning: enable everything), just like vendor u-boot does for
|
||||
Meson8/Meson8b/Meson8m2.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_drv.c | 55 ++++++++++++++++++-------------
|
||||
1 file changed, 33 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
|
||||
index 60298cf3b..ffc5eb588 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.c
|
||||
@@ -135,28 +135,39 @@ static struct regmap_config meson_regmap_config = {
|
||||
|
||||
static void meson_vpu_init(struct meson_drm *priv)
|
||||
{
|
||||
- u32 value;
|
||||
-
|
||||
- /*
|
||||
- * Slave dc0 and dc5 connected to master port 1.
|
||||
- * By default other slaves are connected to master port 0.
|
||||
- */
|
||||
- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) |
|
||||
- VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1);
|
||||
- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L1C1));
|
||||
-
|
||||
- /* Slave dc0 connected to master port 1 */
|
||||
- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1);
|
||||
- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L1C2));
|
||||
-
|
||||
- /* Slave dc4 and dc7 connected to master port 1 */
|
||||
- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) |
|
||||
- VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1);
|
||||
- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L2C1));
|
||||
-
|
||||
- /* Slave dc1 connected to master port 1 */
|
||||
- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1);
|
||||
- writel_relaxed(value, priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) {
|
||||
+ writel(0x0, priv->io_base + _REG(VPU_MEM_PD_REG0));
|
||||
+ writel(0x0, priv->io_base + _REG(VPU_MEM_PD_REG1));
|
||||
+ } else {
|
||||
+ u32 value;
|
||||
+
|
||||
+ /*
|
||||
+ * Slave dc0 and dc5 connected to master port 1.
|
||||
+ * By default other slaves are connected to master port 0.
|
||||
+ */
|
||||
+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) |
|
||||
+ VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1);
|
||||
+ writel_relaxed(value,
|
||||
+ priv->io_base + _REG(VPU_RDARB_MODE_L1C1));
|
||||
+
|
||||
+ /* Slave dc0 connected to master port 1 */
|
||||
+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1);
|
||||
+ writel_relaxed(value,
|
||||
+ priv->io_base + _REG(VPU_RDARB_MODE_L1C2));
|
||||
+
|
||||
+ /* Slave dc4 and dc7 connected to master port 1 */
|
||||
+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) |
|
||||
+ VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1);
|
||||
+ writel_relaxed(value,
|
||||
+ priv->io_base + _REG(VPU_RDARB_MODE_L2C1));
|
||||
+
|
||||
+ /* Slave dc1 connected to master port 1 */
|
||||
+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1);
|
||||
+ writel_relaxed(value,
|
||||
+ priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
|
||||
+ }
|
||||
}
|
||||
|
||||
static void meson_fbdev_setup(struct meson_drm *priv)
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
From 7017db5123fbbccca0dde37e7a2f45172d50e56e Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Wed, 23 Dec 2020 21:18:35 +0100
|
||||
Subject: [PATCH 52/96] drm/meson: Describe the HDMI PHY frequency limits of
|
||||
Meson8/8b/8m2
|
||||
|
||||
The maximum HDMI PLL frequency used by the vendor kernel is 2.976GHz.
|
||||
For Meson8 and Meson8b (both "HDMI 1.4 4k" capable) the maximum HDMI PHY
|
||||
frequency therefore is 2.976GHz. This makes sure we don't expose any
|
||||
HDMI 2.0 modes.
|
||||
Meson8b only supports up to 1080p according to it's datasheet. Limit the
|
||||
Meson8b SoC's to 1.65GHz (similar to what's already there for GXL S805X
|
||||
and S805Y).
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_drv.c | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
|
||||
index ffc5eb588..bbb8b8b50 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.c
|
||||
@@ -200,13 +200,29 @@ struct meson_drm_soc_attr {
|
||||
};
|
||||
|
||||
static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = {
|
||||
- /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */
|
||||
+ /* The maximum frequency of HDMI PHY on Meson8 and Meson8m2 is ~3GHz */
|
||||
+ {
|
||||
+ .limits = {
|
||||
+ .max_hdmi_phy_freq = 2976000,
|
||||
+ },
|
||||
+ .attrs = (const struct soc_device_attribute []) {
|
||||
+ { .soc_id = "Meson8 (S802)", },
|
||||
+ { .soc_id = "Meson8m2 (S812)", },
|
||||
+ { /* sentinel */ },
|
||||
+ }
|
||||
+ },
|
||||
+ /*
|
||||
+ * GXL S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz.
|
||||
+ * Meson8b (S805) only supports "1200p@60 max resolution" according to
|
||||
+ * the public datasheet.
|
||||
+ */
|
||||
{
|
||||
.limits = {
|
||||
.max_hdmi_phy_freq = 1650000,
|
||||
},
|
||||
.attrs = (const struct soc_device_attribute []) {
|
||||
{ .soc_id = "GXL (S805*)", },
|
||||
+ { .soc_id = "Meson8b (S805)", },
|
||||
{ /* sentinel */ }
|
||||
}
|
||||
},
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
From e37f5e8c60f9ecad4b2286bec22e2989d267971b Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Wed, 6 Oct 2021 23:34:04 +0200
|
||||
Subject: [PATCH 53/96] drm/meson: Update the HDMI encoder for Meson8/8b/8m2
|
||||
|
||||
Meson8/8b/8m2 uses VPU_HDMI_OUTPUT_YCBCR for YUV444 while newer SoCs use
|
||||
VPU_HDMI_OUTPUT_CBYCR. Also the 32-bit SoCs use VPU_HDMI_OUTPUT_CRYCB
|
||||
for RGB. These are the only two known mappings for the 32-bit SoCs.
|
||||
|
||||
The VPU_HDMI_FMT_CTRL register with it's YUV444 to YUV422/YUV420
|
||||
converter is not present on these older SoCs. Avoid writing this
|
||||
reserved register on these 32-bit SoCs.
|
||||
|
||||
MEDIA_BUS_FMT_RGB888_1X24 cannot be exposed as output format because the
|
||||
RGB to YUV converter is always enabled in meson_plane_atomic_update()
|
||||
(so there's currently no way to configure it).
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 66 ++++++++++++++++------
|
||||
1 file changed, 49 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
||||
index 0593a1cde..d8aae0952 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
||||
@@ -190,13 +190,13 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge,
|
||||
{
|
||||
struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
|
||||
struct drm_atomic_state *state = bridge_state->base.state;
|
||||
- unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR;
|
||||
struct meson_drm *priv = encoder_hdmi->priv;
|
||||
struct drm_connector_state *conn_state;
|
||||
const struct drm_display_mode *mode;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_connector *connector;
|
||||
bool yuv420_mode = false;
|
||||
+ unsigned int ycrcb_map;
|
||||
int vic;
|
||||
|
||||
connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
|
||||
@@ -217,11 +217,21 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge,
|
||||
|
||||
dev_dbg(priv->dev, "\"%s\" vic %d\n", mode->name, vic);
|
||||
|
||||
- if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) {
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) {
|
||||
+ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_RGB888_1X24)
|
||||
+ ycrcb_map = VPU_HDMI_OUTPUT_YCBCR;
|
||||
+ else
|
||||
+ ycrcb_map = VPU_HDMI_OUTPUT_CRYCB;
|
||||
+ } else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) {
|
||||
ycrcb_map = VPU_HDMI_OUTPUT_CRYCB;
|
||||
yuv420_mode = true;
|
||||
- } else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16)
|
||||
+ } else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) {
|
||||
ycrcb_map = VPU_HDMI_OUTPUT_CRYCB;
|
||||
+ } else {
|
||||
+ ycrcb_map = VPU_HDMI_OUTPUT_CBYCR;
|
||||
+ }
|
||||
|
||||
/* VENC + VENC-DVI Mode setup */
|
||||
meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, yuv420_mode, mode);
|
||||
@@ -229,17 +239,21 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge,
|
||||
/* VCLK Set clock */
|
||||
meson_encoder_hdmi_set_vclk(encoder_hdmi, mode);
|
||||
|
||||
- if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
|
||||
- /* Setup YUV420 to HDMI-TX, no 10bit diphering */
|
||||
- writel_relaxed(2 | (2 << 2),
|
||||
- priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
|
||||
- else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16)
|
||||
- /* Setup YUV422 to HDMI-TX, no 10bit diphering */
|
||||
- writel_relaxed(1 | (2 << 2),
|
||||
- priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
|
||||
- else
|
||||
- /* Setup YUV444 to HDMI-TX, no 10bit diphering */
|
||||
- writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
|
||||
+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) &&
|
||||
+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) &&
|
||||
+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) {
|
||||
+ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
|
||||
+ /* Setup YUV420 to HDMI-TX, no 10bit diphering */
|
||||
+ writel_relaxed(2 | (2 << 2),
|
||||
+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
|
||||
+ else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16)
|
||||
+ /* Setup YUV422 to HDMI-TX, no 10bit diphering */
|
||||
+ writel_relaxed(1 | (2 << 2),
|
||||
+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
|
||||
+ else
|
||||
+ /* Setup YUV444 to HDMI-TX, no 10bit diphering */
|
||||
+ writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
|
||||
+ }
|
||||
|
||||
dev_dbg(priv->dev, "%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP");
|
||||
|
||||
@@ -262,7 +276,11 @@ static void meson_encoder_hdmi_atomic_disable(struct drm_bridge *bridge,
|
||||
writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
|
||||
}
|
||||
|
||||
-static const u32 meson_encoder_hdmi_out_bus_fmts[] = {
|
||||
+static const u32 meson8_encoder_hdmi_out_bus_fmts[] = {
|
||||
+ MEDIA_BUS_FMT_YUV8_1X24,
|
||||
+};
|
||||
+
|
||||
+static const u32 meson_gx_encoder_hdmi_out_bus_fmts[] = {
|
||||
MEDIA_BUS_FMT_YUV8_1X24,
|
||||
MEDIA_BUS_FMT_UYVY8_1X16,
|
||||
MEDIA_BUS_FMT_UYYVYY8_0_5X24,
|
||||
@@ -276,13 +294,27 @@ meson_encoder_hdmi_get_inp_bus_fmts(struct drm_bridge *bridge,
|
||||
u32 output_fmt,
|
||||
unsigned int *num_input_fmts)
|
||||
{
|
||||
+ struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
|
||||
+ struct meson_drm *priv = encoder_hdmi->priv;
|
||||
+ unsigned int num_out_bus_fmts;
|
||||
+ const u32 *out_bus_fmts;
|
||||
u32 *input_fmts = NULL;
|
||||
int i;
|
||||
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) {
|
||||
+ num_out_bus_fmts = ARRAY_SIZE(meson8_encoder_hdmi_out_bus_fmts);
|
||||
+ out_bus_fmts = meson8_encoder_hdmi_out_bus_fmts;
|
||||
+ } else {
|
||||
+ num_out_bus_fmts = ARRAY_SIZE(meson_gx_encoder_hdmi_out_bus_fmts);
|
||||
+ out_bus_fmts = meson_gx_encoder_hdmi_out_bus_fmts;
|
||||
+ }
|
||||
+
|
||||
*num_input_fmts = 0;
|
||||
|
||||
- for (i = 0 ; i < ARRAY_SIZE(meson_encoder_hdmi_out_bus_fmts) ; ++i) {
|
||||
- if (output_fmt == meson_encoder_hdmi_out_bus_fmts[i]) {
|
||||
+ for (i = 0 ; i < num_out_bus_fmts ; ++i) {
|
||||
+ if (output_fmt == out_bus_fmts[i]) {
|
||||
*num_input_fmts = 1;
|
||||
input_fmts = kcalloc(*num_input_fmts,
|
||||
sizeof(*input_fmts),
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 7ba0841fd85b2f8fd11602ea92fb8887ecd3d81c Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Wed, 6 Oct 2021 23:37:44 +0200
|
||||
Subject: [PATCH 54/96] drm/meson: Only set ycbcr_420_allowed on 64-bit SoCs
|
||||
|
||||
The 32-bit SoCs don't support YUV420 so we don't enable that
|
||||
functionality there.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
||||
index d8aae0952..4a84d7d99 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
||||
@@ -481,8 +481,11 @@ int meson_encoder_hdmi_probe(struct meson_drm *priv)
|
||||
|
||||
drm_connector_attach_max_bpc_property(meson_encoder_hdmi->connector, 8, 8);
|
||||
|
||||
- /* Handle this here until handled by drm_bridge_connector_init() */
|
||||
- meson_encoder_hdmi->connector->ycbcr_420_allowed = true;
|
||||
+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) &&
|
||||
+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) &&
|
||||
+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2))
|
||||
+ /* Handle this here until handled by drm_bridge_connector_init() */
|
||||
+ meson_encoder_hdmi->connector->ycbcr_420_allowed = true;
|
||||
|
||||
pdev = of_find_device_by_node(remote);
|
||||
of_node_put(remote);
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
From 39042addabb9910ec95e916fb619f5af8097f0c8 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Thu, 7 Oct 2021 19:09:49 +0200
|
||||
Subject: [PATCH 55/96] drm/meson: Make the HHI registers optional - WIP
|
||||
|
||||
The HHI area contains the clock controller registers as well as the
|
||||
registers for the CVBS DAC. Make the HHI registers optional because the
|
||||
functionality provided by them can be handled by separate drivers
|
||||
(especially on the 32-bit SoCs).
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_drv.c | 35 ++++++++++++++++--------------
|
||||
drivers/gpu/drm/meson/meson_venc.c | 11 +++++++---
|
||||
2 files changed, 27 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
|
||||
index bbb8b8b50..104b53861 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.c
|
||||
@@ -271,24 +271,27 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
|
||||
|
||||
priv->io_base = regs;
|
||||
|
||||
+ /*
|
||||
+ * The HHI resource is optional because it contains the clocks and CVBS
|
||||
+ * encoder registers. These are managed by separate drivers though.
|
||||
+ */
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi");
|
||||
- if (!res) {
|
||||
- ret = -EINVAL;
|
||||
- goto free_drm;
|
||||
- }
|
||||
- /* Simply ioremap since it may be a shared register zone */
|
||||
- regs = devm_ioremap(dev, res->start, resource_size(res));
|
||||
- if (!regs) {
|
||||
- ret = -EADDRNOTAVAIL;
|
||||
- goto free_drm;
|
||||
- }
|
||||
+ if (res) {
|
||||
+ /* Simply ioremap since it may be a shared register zone */
|
||||
+ regs = devm_ioremap(dev, res->start, resource_size(res));
|
||||
+ if (!regs) {
|
||||
+ ret = -EADDRNOTAVAIL;
|
||||
+ goto free_drm;
|
||||
+ }
|
||||
|
||||
- priv->hhi = devm_regmap_init_mmio(dev, regs,
|
||||
- &meson_regmap_config);
|
||||
- if (IS_ERR(priv->hhi)) {
|
||||
- dev_err(&pdev->dev, "Couldn't create the HHI regmap\n");
|
||||
- ret = PTR_ERR(priv->hhi);
|
||||
- goto free_drm;
|
||||
+ priv->hhi = devm_regmap_init_mmio(dev, regs,
|
||||
+ &meson_regmap_config);
|
||||
+ if (IS_ERR(priv->hhi)) {
|
||||
+ dev_err(&pdev->dev,
|
||||
+ "Couldn't create the HHI regmap\n");
|
||||
+ ret = PTR_ERR(priv->hhi);
|
||||
+ goto free_drm;
|
||||
+ }
|
||||
}
|
||||
|
||||
priv->canvas = meson_canvas_get(dev);
|
||||
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
|
||||
index 5efd7a298..805751b9e 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_venc.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_venc.c
|
||||
@@ -1953,12 +1953,16 @@ void meson_venc_enable_vsync(struct meson_drm *priv)
|
||||
writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
|
||||
priv->io_base + _REG(VENC_INTCTRL));
|
||||
}
|
||||
- regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
|
||||
+
|
||||
+ if (priv->hhi)
|
||||
+ regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
|
||||
}
|
||||
|
||||
void meson_venc_disable_vsync(struct meson_drm *priv)
|
||||
{
|
||||
- regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
|
||||
+ if (priv->hhi)
|
||||
+ regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
|
||||
+
|
||||
writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
|
||||
}
|
||||
|
||||
@@ -1968,7 +1972,8 @@ void meson_venc_init(struct meson_drm *priv)
|
||||
writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
|
||||
|
||||
/* Disable HDMI PHY */
|
||||
- regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
|
||||
+ if (priv->hhi)
|
||||
+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
|
||||
|
||||
/* Disable HDMI */
|
||||
writel_bits_relaxed(VPU_HDMI_ENCI_DATA_TO_HDMI |
|
||||
--
|
||||
2.45.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,485 @@
|
||||
From f105e98570211cb16a2ffdca32ac2869c92f9353 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Apr 2020 22:13:51 +0200
|
||||
Subject: [PATCH 57/96] drm/meson: Meson8/Meson8b/Meson8m2 VCLK - HACK
|
||||
|
||||
WiP
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_drv.c | 101 ++++++++++++++++++--
|
||||
drivers/gpu/drm/meson/meson_drv.h | 32 +++++++
|
||||
drivers/gpu/drm/meson/meson_vclk.c | 146 +++++++++++++++++++++++++++++
|
||||
drivers/gpu/drm/meson/meson_venc.c | 24 ++++-
|
||||
4 files changed, 293 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
|
||||
index 104b53861..2fb074e53 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.c
|
||||
@@ -170,6 +170,35 @@ static void meson_vpu_init(struct meson_drm *priv)
|
||||
}
|
||||
}
|
||||
|
||||
+static int meson_video_clock_init(struct meson_drm *priv)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_bulk_prepare(VPU_VID_CLK_NUM, priv->vid_clks);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(priv->dev, ret,
|
||||
+ "Failed to prepare the video clocks\n");
|
||||
+
|
||||
+ ret = clk_bulk_prepare(priv->num_intr_clks, priv->intr_clks);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(priv->dev, ret,
|
||||
+ "Failed to prepare the interrupt clocks\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void meson_video_clock_exit(struct meson_drm *priv)
|
||||
+{
|
||||
+ if (priv->clk_dac_enabled)
|
||||
+ clk_disable(priv->clk_dac);
|
||||
+
|
||||
+ if (priv->clk_venc_enabled)
|
||||
+ clk_disable(priv->clk_venc);
|
||||
+
|
||||
+ clk_bulk_unprepare(priv->num_intr_clks, priv->intr_clks);
|
||||
+ clk_bulk_unprepare(VPU_VID_CLK_NUM, priv->vid_clks);
|
||||
+}
|
||||
+
|
||||
static void meson_fbdev_setup(struct meson_drm *priv)
|
||||
{
|
||||
unsigned int preferred_bpp;
|
||||
@@ -263,10 +292,59 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
|
||||
priv->compat = match->compat;
|
||||
priv->afbcd.ops = match->afbcd_ops;
|
||||
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) {
|
||||
+ priv->vid_pll_resets[VPU_RESET_VID_PLL_PRE].id = "vid_pll_pre";
|
||||
+ priv->vid_pll_resets[VPU_RESET_VID_PLL_POST].id = "vid_pll_post";
|
||||
+ priv->vid_pll_resets[VPU_RESET_VID_PLL_SOFT_PRE].id = "vid_pll_soft_pre";
|
||||
+ priv->vid_pll_resets[VPU_RESET_VID_PLL_SOFT_POST].id = "vid_pll_soft_post";
|
||||
+
|
||||
+ ret = devm_reset_control_bulk_get_exclusive(dev,
|
||||
+ VPU_RESET_VID_PLL_NUM,
|
||||
+ priv->vid_pll_resets);
|
||||
+ if (ret)
|
||||
+ goto free_drm;
|
||||
+
|
||||
+ priv->intr_clks[0].id = "vpu_intr";
|
||||
+ priv->intr_clks[1].id = "hdmi_intr_sync";
|
||||
+ priv->intr_clks[2].id = "venci_int";
|
||||
+ priv->num_intr_clks = 3;
|
||||
+
|
||||
+ ret = devm_clk_bulk_get(dev, priv->num_intr_clks,
|
||||
+ priv->intr_clks);
|
||||
+ if (ret)
|
||||
+ goto free_drm;
|
||||
+
|
||||
+ priv->vid_clks[VPU_VID_CLK_TMDS].id = "tmds";
|
||||
+ priv->vid_clks[VPU_VID_CLK_HDMI_TX_PIXEL].id = "hdmi_tx_pixel";
|
||||
+ priv->vid_clks[VPU_VID_CLK_CTS_ENCP].id = "cts_encp";
|
||||
+ priv->vid_clks[VPU_VID_CLK_CTS_ENCI].id = "cts_enci";
|
||||
+ priv->vid_clks[VPU_VID_CLK_CTS_ENCT].id = "cts_enct";
|
||||
+ priv->vid_clks[VPU_VID_CLK_CTS_ENCL].id = "cts_encl";
|
||||
+ priv->vid_clks[VPU_VID_CLK_CTS_VDAC0].id = "cts_vdac0";
|
||||
+
|
||||
+ ret = devm_clk_bulk_get(dev, VPU_VID_CLK_NUM, priv->vid_clks);
|
||||
+ if (ret)
|
||||
+ goto free_drm;
|
||||
+ } else {
|
||||
+ priv->intr_clks[0].id = "vpu_intr";
|
||||
+ priv->num_intr_clks = 1;
|
||||
+
|
||||
+ ret = devm_clk_bulk_get_optional(dev, priv->num_intr_clks,
|
||||
+ priv->intr_clks);
|
||||
+ if (ret)
|
||||
+ goto free_drm;
|
||||
+ }
|
||||
+
|
||||
+ ret = meson_video_clock_init(priv);
|
||||
+ if (ret)
|
||||
+ goto free_drm;
|
||||
+
|
||||
regs = devm_platform_ioremap_resource_byname(pdev, "vpu");
|
||||
if (IS_ERR(regs)) {
|
||||
ret = PTR_ERR(regs);
|
||||
- goto free_drm;
|
||||
+ goto video_clock_exit;
|
||||
}
|
||||
|
||||
priv->io_base = regs;
|
||||
@@ -281,7 +359,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
|
||||
regs = devm_ioremap(dev, res->start, resource_size(res));
|
||||
if (!regs) {
|
||||
ret = -EADDRNOTAVAIL;
|
||||
- goto free_drm;
|
||||
+ goto video_clock_exit;
|
||||
}
|
||||
|
||||
priv->hhi = devm_regmap_init_mmio(dev, regs,
|
||||
@@ -290,36 +368,36 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
|
||||
dev_err(&pdev->dev,
|
||||
"Couldn't create the HHI regmap\n");
|
||||
ret = PTR_ERR(priv->hhi);
|
||||
- goto free_drm;
|
||||
+ goto video_clock_exit;
|
||||
}
|
||||
}
|
||||
|
||||
priv->canvas = meson_canvas_get(dev);
|
||||
if (IS_ERR(priv->canvas)) {
|
||||
ret = PTR_ERR(priv->canvas);
|
||||
- goto free_drm;
|
||||
+ goto video_clock_exit;
|
||||
}
|
||||
|
||||
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1);
|
||||
if (ret)
|
||||
- goto free_drm;
|
||||
+ goto video_clock_exit;
|
||||
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0);
|
||||
if (ret) {
|
||||
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
|
||||
- goto free_drm;
|
||||
+ goto video_clock_exit;
|
||||
}
|
||||
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1);
|
||||
if (ret) {
|
||||
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
|
||||
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
|
||||
- goto free_drm;
|
||||
+ goto video_clock_exit;
|
||||
}
|
||||
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2);
|
||||
if (ret) {
|
||||
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
|
||||
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
|
||||
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1);
|
||||
- goto free_drm;
|
||||
+ goto video_clock_exit;
|
||||
}
|
||||
|
||||
priv->vsync_irq = platform_get_irq(pdev, 0);
|
||||
@@ -425,6 +503,8 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
|
||||
exit_afbcd:
|
||||
if (priv->afbcd.ops)
|
||||
priv->afbcd.ops->exit(priv);
|
||||
+video_clock_exit:
|
||||
+ meson_video_clock_exit(priv);
|
||||
free_drm:
|
||||
drm_dev_put(drm);
|
||||
|
||||
@@ -469,6 +549,8 @@ static void meson_drv_unbind(struct device *dev)
|
||||
|
||||
if (priv->afbcd.ops)
|
||||
priv->afbcd.ops->exit(priv);
|
||||
+
|
||||
+ meson_video_clock_exit(priv);
|
||||
}
|
||||
|
||||
static const struct component_master_ops meson_drv_master_ops = {
|
||||
@@ -483,6 +565,8 @@ static int __maybe_unused meson_drv_pm_suspend(struct device *dev)
|
||||
if (!priv)
|
||||
return 0;
|
||||
|
||||
+ // TODO: video clock suspend
|
||||
+
|
||||
return drm_mode_config_helper_suspend(priv->drm);
|
||||
}
|
||||
|
||||
@@ -493,6 +577,7 @@ static int __maybe_unused meson_drv_pm_resume(struct device *dev)
|
||||
if (!priv)
|
||||
return 0;
|
||||
|
||||
+ meson_video_clock_init(priv);
|
||||
meson_vpu_init(priv);
|
||||
meson_venc_init(priv);
|
||||
meson_vpp_init(priv);
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
|
||||
index 8e1c01242..59f80fcc6 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.h
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.h
|
||||
@@ -7,9 +7,11 @@
|
||||
#ifndef __MESON_DRV_H
|
||||
#define __MESON_DRV_H
|
||||
|
||||
+#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
|
||||
struct drm_crtc;
|
||||
struct drm_device;
|
||||
@@ -45,6 +47,25 @@ struct meson_drm_soc_limits {
|
||||
unsigned int max_hdmi_phy_freq;
|
||||
};
|
||||
|
||||
+enum vpu_bulk_clk_id {
|
||||
+ VPU_VID_CLK_TMDS = 0,
|
||||
+ VPU_VID_CLK_HDMI_TX_PIXEL,
|
||||
+ VPU_VID_CLK_CTS_ENCP,
|
||||
+ VPU_VID_CLK_CTS_ENCI,
|
||||
+ VPU_VID_CLK_CTS_ENCT,
|
||||
+ VPU_VID_CLK_CTS_ENCL,
|
||||
+ VPU_VID_CLK_CTS_VDAC0,
|
||||
+ VPU_VID_CLK_NUM
|
||||
+};
|
||||
+
|
||||
+enum vpu_bulk_vid_pll_reset_id {
|
||||
+ VPU_RESET_VID_PLL_PRE = 0,
|
||||
+ VPU_RESET_VID_PLL_POST,
|
||||
+ VPU_RESET_VID_PLL_SOFT_PRE,
|
||||
+ VPU_RESET_VID_PLL_SOFT_POST,
|
||||
+ VPU_RESET_VID_PLL_NUM
|
||||
+};
|
||||
+
|
||||
struct meson_drm {
|
||||
struct device *dev;
|
||||
enum vpu_compatible compat;
|
||||
@@ -70,6 +91,17 @@ struct meson_drm {
|
||||
bool cvbs_dac_enabled;
|
||||
struct platform_device *cvbs_dac_pdev;
|
||||
|
||||
+ struct clk_bulk_data intr_clks[3];
|
||||
+ unsigned int num_intr_clks;
|
||||
+ bool intr_clks_enabled;
|
||||
+ struct clk_bulk_data vid_clks[VPU_VID_CLK_NUM];
|
||||
+ bool vid_clk_rate_exclusive[VPU_VID_CLK_NUM];
|
||||
+ struct clk *clk_venc;
|
||||
+ bool clk_venc_enabled;
|
||||
+ struct clk *clk_dac;
|
||||
+ bool clk_dac_enabled;
|
||||
+ struct reset_control_bulk_data vid_pll_resets[VPU_RESET_VID_PLL_NUM];
|
||||
+
|
||||
/* Components Data */
|
||||
struct {
|
||||
bool osd1_enabled;
|
||||
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
|
||||
index 2a82119eb..a2c1bf1ae 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_vclk.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_vclk.c
|
||||
@@ -732,6 +732,11 @@ meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq)
|
||||
return MODE_CLOCK_HIGH;
|
||||
}
|
||||
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2))
|
||||
+ return MODE_OK;
|
||||
+
|
||||
if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
|
||||
return MODE_OK;
|
||||
|
||||
@@ -784,6 +789,11 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
||||
return MODE_CLOCK_HIGH;
|
||||
}
|
||||
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2))
|
||||
+ return MODE_OK;
|
||||
+
|
||||
for (i = 0 ; params[i].pixel_freq ; ++i) {
|
||||
DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
|
||||
i, params[i].pixel_freq,
|
||||
@@ -1024,6 +1034,128 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
||||
regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
|
||||
}
|
||||
|
||||
+static int meson_vclk_set_rate_exclusive(struct meson_drm *priv,
|
||||
+ enum vpu_bulk_clk_id clk_id,
|
||||
+ unsigned int rate_khz)
|
||||
+{
|
||||
+ struct clk *clk = priv->vid_clks[clk_id].clk;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_set_rate_exclusive(clk, rate_khz * 1000UL);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ priv->vid_clk_rate_exclusive[clk_id] = true;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void meson_vclk_disable_ccf(struct meson_drm *priv)
|
||||
+{
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ /* allow all clocks to be changed in _enable again */
|
||||
+ for (i = 0; i < VPU_VID_CLK_NUM; i++) {
|
||||
+ if (!priv->vid_clk_rate_exclusive[i])
|
||||
+ continue;
|
||||
+
|
||||
+ clk_rate_exclusive_put(priv->vid_clks[i].clk);
|
||||
+ priv->vid_clk_rate_exclusive[i] = false;
|
||||
+ }
|
||||
+
|
||||
+ if (priv->clk_dac_enabled) {
|
||||
+ clk_disable(priv->clk_dac);
|
||||
+ priv->clk_dac_enabled = false;
|
||||
+ }
|
||||
+
|
||||
+ if (priv->clk_venc_enabled) {
|
||||
+ clk_disable(priv->clk_venc);
|
||||
+ priv->clk_venc_enabled = false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int meson_vclk_enable_ccf(struct meson_drm *priv, unsigned int target,
|
||||
+ bool hdmi_use_enci, unsigned int phy_freq,
|
||||
+ unsigned int dac_freq, unsigned int venc_freq)
|
||||
+{
|
||||
+ enum vpu_bulk_clk_id venc_clk_id, dac_clk_id;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (target == MESON_VCLK_TARGET_CVBS || hdmi_use_enci)
|
||||
+ venc_clk_id = VPU_VID_CLK_CTS_ENCI;
|
||||
+ else
|
||||
+ venc_clk_id = VPU_VID_CLK_CTS_ENCP;
|
||||
+
|
||||
+ if (target == MESON_VCLK_TARGET_CVBS)
|
||||
+ dac_clk_id = VPU_VID_CLK_CTS_VDAC0;
|
||||
+ else
|
||||
+ dac_clk_id = VPU_VID_CLK_HDMI_TX_PIXEL;
|
||||
+
|
||||
+ /*
|
||||
+ * The TMDS clock also updates the PLL. Protect the PLL rate so all
|
||||
+ * following clocks are derived from the PLL setting which matches the
|
||||
+ * TMDS clock.
|
||||
+ */
|
||||
+ ret = meson_vclk_set_rate_exclusive(priv, VPU_VID_CLK_TMDS, phy_freq);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "Failed to set TMDS clock to %ukHz: %d\n",
|
||||
+ phy_freq, ret);
|
||||
+ goto out_enable_clocks;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * The DAC clock may be derived from a parent of the VENC clock so we
|
||||
+ * must protect the VENC clock from changing it's rate. This works
|
||||
+ * because the DAC freq can be divided by the VENC clock.
|
||||
+ */
|
||||
+ ret = meson_vclk_set_rate_exclusive(priv, venc_clk_id, venc_freq);
|
||||
+ if (ret) {
|
||||
+ dev_warn(priv->dev,
|
||||
+ "Failed to set VENC clock to %ukHz while TMDS clock is %ukHz: %d\n",
|
||||
+ venc_freq, phy_freq, ret);
|
||||
+ goto out_enable_clocks;
|
||||
+ }
|
||||
+
|
||||
+ priv->clk_venc = priv->vid_clks[venc_clk_id].clk;
|
||||
+
|
||||
+ /*
|
||||
+ * after changing any of the VID_PLL_* clocks (which can happen when
|
||||
+ * update the VENC clock rate) we need to assert and then de-assert the
|
||||
+ * VID_DIVIDER_CNTL_* reset lines.
|
||||
+ */
|
||||
+ reset_control_bulk_assert(VPU_RESET_VID_PLL_NUM, priv->vid_pll_resets);
|
||||
+ reset_control_bulk_deassert(VPU_RESET_VID_PLL_NUM, priv->vid_pll_resets);
|
||||
+
|
||||
+ ret = meson_vclk_set_rate_exclusive(priv, dac_clk_id, dac_freq);
|
||||
+ if (ret) {
|
||||
+ dev_warn(priv->dev,
|
||||
+ "Failed to set pixel clock to %ukHz while TMDS clock is %ukHz: %d\n",
|
||||
+ dac_freq, phy_freq, ret);
|
||||
+ goto out_enable_clocks;
|
||||
+ }
|
||||
+
|
||||
+ priv->clk_dac = priv->vid_clks[dac_clk_id].clk;
|
||||
+
|
||||
+out_enable_clocks:
|
||||
+ ret = clk_enable(priv->clk_venc);
|
||||
+ if (ret)
|
||||
+ dev_err(priv->dev,
|
||||
+ "Failed to re-enable the VENC clock at %ukHz: %d\n",
|
||||
+ venc_freq, ret);
|
||||
+ else
|
||||
+ priv->clk_venc_enabled = true;
|
||||
+
|
||||
+ ret = clk_enable(priv->clk_dac);
|
||||
+ if (ret)
|
||||
+ dev_err(priv->dev,
|
||||
+ "Failed to re-enable the pixel clock at %ukHz: %d\n",
|
||||
+ dac_freq, ret);
|
||||
+ else
|
||||
+ priv->clk_dac_enabled = true;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||
unsigned int phy_freq, unsigned int vclk_freq,
|
||||
unsigned int venc_freq, unsigned int dac_freq,
|
||||
@@ -1034,6 +1166,20 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||
unsigned int hdmi_tx_div;
|
||||
unsigned int venc_div;
|
||||
|
||||
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) ||
|
||||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) {
|
||||
+ /* CVBS video clocks are generated off a 1296MHz base clock */
|
||||
+ if (target == MESON_VCLK_TARGET_CVBS)
|
||||
+ phy_freq = 1296000;
|
||||
+
|
||||
+ dev_err(priv->dev, "%s(target: %u, phy: %u, dac: %u, venc: %u, hdmi_use_enci: %u)\n", __func__, target, phy_freq, dac_freq, venc_freq, hdmi_use_enci);
|
||||
+ meson_vclk_disable_ccf(priv);
|
||||
+ meson_vclk_enable_ccf(priv, target, hdmi_use_enci, phy_freq,
|
||||
+ dac_freq, venc_freq);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (target == MESON_VCLK_TARGET_CVBS) {
|
||||
meson_venci_cvbs_clock_config(priv);
|
||||
return;
|
||||
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
|
||||
index 805751b9e..d834359c1 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_venc.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_venc.c
|
||||
@@ -1954,14 +1954,34 @@ void meson_venc_enable_vsync(struct meson_drm *priv)
|
||||
priv->io_base + _REG(VENC_INTCTRL));
|
||||
}
|
||||
|
||||
- if (priv->hhi)
|
||||
+ if (priv->intr_clks[0].clk) {
|
||||
+ if (!priv->intr_clks_enabled) {
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_bulk_enable(priv->num_intr_clks,
|
||||
+ priv->intr_clks);
|
||||
+ if (ret)
|
||||
+ dev_err(priv->dev,
|
||||
+ "Failed to enable the interrupt clocks\n");
|
||||
+ else
|
||||
+ priv->intr_clks_enabled = true;
|
||||
+ }
|
||||
+ } else {
|
||||
regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
|
||||
+ }
|
||||
}
|
||||
|
||||
void meson_venc_disable_vsync(struct meson_drm *priv)
|
||||
{
|
||||
- if (priv->hhi)
|
||||
+ if (priv->intr_clks[0].clk) {
|
||||
+ if (priv->intr_clks_enabled) {
|
||||
+ clk_bulk_disable(priv->num_intr_clks,
|
||||
+ priv->intr_clks);
|
||||
+ priv->intr_clks_enabled = false;
|
||||
+ }
|
||||
+ } else {
|
||||
regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
|
||||
+ }
|
||||
|
||||
writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
|
||||
}
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
From 8717397eb0cad729cc6244019665476aec47dbaf Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 25 Apr 2020 22:14:27 +0200
|
||||
Subject: [PATCH 58/96] drm/meson: Enable support for Meson8/Meson8b/Meson8m2
|
||||
|
||||
Add a compatible string for each of the three SoCs now that all hardware
|
||||
specific quirks are added to the driver.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_drv.c | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
|
||||
index 2fb074e53..3a853fa25 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.c
|
||||
@@ -660,6 +660,18 @@ static void meson_drv_remove(struct platform_device *pdev)
|
||||
component_master_del(&pdev->dev, &meson_drv_master_ops);
|
||||
}
|
||||
|
||||
+static struct meson_drm_match_data meson_drm_m8_data = {
|
||||
+ .compat = VPU_COMPATIBLE_M8,
|
||||
+};
|
||||
+
|
||||
+static struct meson_drm_match_data meson_drm_m8b_data = {
|
||||
+ .compat = VPU_COMPATIBLE_M8B,
|
||||
+};
|
||||
+
|
||||
+static struct meson_drm_match_data meson_drm_m8m2_data = {
|
||||
+ .compat = VPU_COMPATIBLE_M8M2,
|
||||
+};
|
||||
+
|
||||
static struct meson_drm_match_data meson_drm_gxbb_data = {
|
||||
.compat = VPU_COMPATIBLE_GXBB,
|
||||
};
|
||||
@@ -679,6 +691,12 @@ static struct meson_drm_match_data meson_drm_g12a_data = {
|
||||
};
|
||||
|
||||
static const struct of_device_id dt_match[] = {
|
||||
+ { .compatible = "amlogic,meson8-vpu",
|
||||
+ .data = (void *)&meson_drm_m8_data },
|
||||
+ { .compatible = "amlogic,meson8b-vpu",
|
||||
+ .data = (void *)&meson_drm_m8b_data },
|
||||
+ { .compatible = "amlogic,meson8m2-vpu",
|
||||
+ .data = (void *)&meson_drm_m8m2_data },
|
||||
{ .compatible = "amlogic,meson-gxbb-vpu",
|
||||
.data = (void *)&meson_drm_gxbb_data },
|
||||
{ .compatible = "amlogic,meson-gxl-vpu",
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
From 997c2fe858ecc56b1d0d2ccd56cce6c571b87d17 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sat, 8 Dec 2018 13:50:48 +0100
|
||||
Subject: [PATCH 59/96] ARM: dts: meson: add the VPU - WiP
|
||||
|
||||
WiP
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson.dtsi | 10 +++
|
||||
arch/arm/boot/dts/amlogic/meson8.dtsi | 80 ++++++++++++++++++++++++
|
||||
arch/arm/boot/dts/amlogic/meson8b.dtsi | 81 +++++++++++++++++++++++++
|
||||
arch/arm/boot/dts/amlogic/meson8m2.dtsi | 4 ++
|
||||
4 files changed, 175 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson.dtsi b/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
index d7f50fec8..d729a06da 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson.dtsi
|
||||
@@ -38,6 +38,16 @@ hhi: system-controller@4000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x4000 0x400>;
|
||||
+
|
||||
+
|
||||
+ cvbs_dac: video-dac@2f4 {
|
||||
+ compatible = "amlogic,meson-cvbs-dac";
|
||||
+ reg = <0x2f4 0x8>;
|
||||
+
|
||||
+ #phy-cells = <0>;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
};
|
||||
|
||||
aiu: audio-controller@5400 {
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
index 454c35530..519443e19 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
@@ -314,6 +314,71 @@ mali: gpu@c0000 {
|
||||
operating-points-v2 = <&gpu_opp_table>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
};
|
||||
+
|
||||
+ vpu: vpu@100000 {
|
||||
+ compatible = "amlogic,meson8-vpu";
|
||||
+
|
||||
+ reg = <0x100000 0x10000>;
|
||||
+ reg-names = "vpu";
|
||||
+
|
||||
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
|
||||
+
|
||||
+ amlogic,canvas = <&canvas>;
|
||||
+
|
||||
+ /*
|
||||
+ * The VCLK{,2}_IN path always needs to derived from
|
||||
+ * the CLKID_VID_PLL_FINAL_DIV so other clocks like
|
||||
+ * MPLL1 are not used (MPLL1 is reserved for audio
|
||||
+ * purposes).
|
||||
+ */
|
||||
+ assigned-clocks = <&clkc CLKID_VCLK_IN_SEL>,
|
||||
+ <&clkc CLKID_VCLK2_IN_SEL>;
|
||||
+ assigned-clock-parents = <&clkc CLKID_VID_PLL_FINAL_DIV>,
|
||||
+ <&clkc CLKID_VID_PLL_FINAL_DIV>;
|
||||
+
|
||||
+ clocks = <&clkc CLKID_VPU_INTR>,
|
||||
+ <&clkc CLKID_HDMI_INTR_SYNC>,
|
||||
+ <&clkc CLKID_GCLK_VENCI_INT>,
|
||||
+ <&clkc CLKID_HDMI_PLL_HDMI_OUT>,
|
||||
+ <&clkc CLKID_HDMI_TX_PIXEL>,
|
||||
+ <&clkc CLKID_CTS_ENCP>,
|
||||
+ <&clkc CLKID_CTS_ENCI>,
|
||||
+ <&clkc CLKID_CTS_ENCT>,
|
||||
+ <&clkc CLKID_CTS_ENCL>,
|
||||
+ <&clkc CLKID_CTS_VDAC0>;
|
||||
+ clock-names = "vpu_intr",
|
||||
+ "hdmi_intr_sync",
|
||||
+ "venci_int",
|
||||
+ "tmds",
|
||||
+ "hdmi_tx_pixel",
|
||||
+ "cts_encp",
|
||||
+ "cts_enci",
|
||||
+ "cts_enct",
|
||||
+ "cts_encl",
|
||||
+ "cts_vdac0";
|
||||
+
|
||||
+ resets = <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE>,
|
||||
+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST>,
|
||||
+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE>,
|
||||
+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST>;
|
||||
+ reset-names = "vid_pll_pre",
|
||||
+ "vid_pll_post",
|
||||
+ "vid_pll_soft_pre",
|
||||
+ "vid_pll_soft_post";
|
||||
+
|
||||
+ phys = <&cvbs_dac>;
|
||||
+ phy-names = "cvbs-dac";
|
||||
+
|
||||
+ power-domains = <&pwrc PWRC_MESON8_VPU_ID>;
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ /* CVBS VDAC output port */
|
||||
+ cvbs_vdac_port: port@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
}; /* end of / */
|
||||
|
||||
@@ -617,6 +682,17 @@ smp-sram@1ff80 {
|
||||
};
|
||||
};
|
||||
|
||||
+&cvbs_dac {
|
||||
+ compatible = "amlogic,meson8-cvbs-dac", "amlogic,meson-cvbs-dac";
|
||||
+
|
||||
+ clocks = <&clkc CLKID_CTS_VDAC0>;
|
||||
+
|
||||
+ nvmem-cells = <&cvbs_trimming>;
|
||||
+ nvmem-cell-names = "cvbs_trimming";
|
||||
+
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&efuse {
|
||||
compatible = "amlogic,meson8-efuse";
|
||||
clocks = <&clkc CLKID_EFUSE>;
|
||||
@@ -626,6 +702,10 @@ temperature_calib: calib@1f4 {
|
||||
/* only the upper two bytes are relevant */
|
||||
reg = <0x1f4 0x4>;
|
||||
};
|
||||
+
|
||||
+ cvbs_trimming: calib@1f8 {
|
||||
+ reg = <0x1f8 0x2>;
|
||||
+ };
|
||||
};
|
||||
|
||||
ðmac {
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8b.dtsi b/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
index 5ffedca99..87aa74675 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
@@ -276,6 +276,71 @@ mali: gpu@c0000 {
|
||||
operating-points-v2 = <&gpu_opp_table>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
};
|
||||
+
|
||||
+ vpu: vpu@100000 {
|
||||
+ compatible = "amlogic,meson8b-vpu";
|
||||
+
|
||||
+ reg = <0x100000 0x10000>;
|
||||
+ reg-names = "vpu";
|
||||
+
|
||||
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
|
||||
+
|
||||
+ amlogic,canvas = <&canvas>;
|
||||
+
|
||||
+ /*
|
||||
+ * The VCLK{,2}_IN path always needs to derived from
|
||||
+ * the CLKID_VID_PLL_FINAL_DIV so other clocks like
|
||||
+ * MPLL1 are not used (MPLL1 is reserved for audio
|
||||
+ * purposes).
|
||||
+ */
|
||||
+ assigned-clocks = <&clkc CLKID_VCLK_IN_SEL>,
|
||||
+ <&clkc CLKID_VCLK2_IN_SEL>;
|
||||
+ assigned-clock-parents = <&clkc CLKID_VID_PLL_FINAL_DIV>,
|
||||
+ <&clkc CLKID_VID_PLL_FINAL_DIV>;
|
||||
+
|
||||
+ clocks = <&clkc CLKID_VPU_INTR>,
|
||||
+ <&clkc CLKID_HDMI_INTR_SYNC>,
|
||||
+ <&clkc CLKID_GCLK_VENCI_INT>,
|
||||
+ <&clkc CLKID_HDMI_PLL_HDMI_OUT>,
|
||||
+ <&clkc CLKID_HDMI_TX_PIXEL>,
|
||||
+ <&clkc CLKID_CTS_ENCP>,
|
||||
+ <&clkc CLKID_CTS_ENCI>,
|
||||
+ <&clkc CLKID_CTS_ENCT>,
|
||||
+ <&clkc CLKID_CTS_ENCL>,
|
||||
+ <&clkc CLKID_CTS_VDAC0>;
|
||||
+ clock-names = "vpu_intr",
|
||||
+ "hdmi_intr_sync",
|
||||
+ "venci_int",
|
||||
+ "tmds",
|
||||
+ "hdmi_tx_pixel",
|
||||
+ "cts_encp",
|
||||
+ "cts_enci",
|
||||
+ "cts_enct",
|
||||
+ "cts_encl",
|
||||
+ "cts_vdac0";
|
||||
+
|
||||
+ resets = <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE>,
|
||||
+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST>,
|
||||
+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE>,
|
||||
+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST>;
|
||||
+ reset-names = "vid_pll_pre",
|
||||
+ "vid_pll_post",
|
||||
+ "vid_pll_soft_pre",
|
||||
+ "vid_pll_soft_post";
|
||||
+
|
||||
+ phys = <&cvbs_dac>;
|
||||
+ phy-names = "cvbs-dac";
|
||||
+
|
||||
+ power-domains = <&pwrc PWRC_MESON8_VPU_ID>;
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ /* CVBS VDAC output port */
|
||||
+ cvbs_vdac_port: port@0 {
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
}; /* end of / */
|
||||
|
||||
@@ -389,6 +454,8 @@ &ao_arc_rproc {
|
||||
sram = <&ao_arc_sram>;
|
||||
resets = <&reset RESET_MEDIA_CPU>;
|
||||
clocks = <&clkc CLKID_AO_MEDIA_CPU>;
|
||||
+ status = "okay";
|
||||
+ firmware-name = "zephyr.elf";
|
||||
};
|
||||
|
||||
&cbus {
|
||||
@@ -547,6 +614,16 @@ smp-sram@1ff80 {
|
||||
};
|
||||
};
|
||||
|
||||
+&cvbs_dac {
|
||||
+ compatible = "amlogic,meson8b-cvbs-dac", "amlogic,meson-cvbs-dac";
|
||||
+
|
||||
+ clocks = <&clkc CLKID_CTS_VDAC0>;
|
||||
+
|
||||
+ nvmem-cells = <&cvbs_trimming>;
|
||||
+ nvmem-cell-names = "cvbs_trimming";
|
||||
+
|
||||
+ status = "okay";
|
||||
+};
|
||||
|
||||
&efuse {
|
||||
compatible = "amlogic,meson8b-efuse";
|
||||
@@ -557,6 +634,10 @@ temperature_calib: calib@1f4 {
|
||||
/* only the upper two bytes are relevant */
|
||||
reg = <0x1f4 0x4>;
|
||||
};
|
||||
+
|
||||
+ cvbs_trimming: calib@1f8 {
|
||||
+ reg = <0x1f8 0x2>;
|
||||
+ };
|
||||
};
|
||||
|
||||
ðmac {
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8m2.dtsi b/arch/arm/boot/dts/amlogic/meson8m2.dtsi
|
||||
index 6725dd9fd..fcb2ad976 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8m2.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8m2.dtsi
|
||||
@@ -96,6 +96,10 @@ &usb1_phy {
|
||||
compatible = "amlogic,meson8m2-usb2-phy", "amlogic,meson-mx-usb2-phy";
|
||||
};
|
||||
|
||||
+&vpu {
|
||||
+ compatible = "amlogic,meson8m2-vpu";
|
||||
+};
|
||||
+
|
||||
&wdt {
|
||||
compatible = "amlogic,meson8m2-wdt", "amlogic,meson8b-wdt";
|
||||
};
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
From d724d428a4f5d92bf2b5f169f948e698549b4386 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sun, 5 May 2019 02:30:11 +0200
|
||||
Subject: [PATCH 60/96] ARM: dts: meson8: add the HDMI controller - WiP
|
||||
|
||||
WiP
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson8.dtsi | 67 ++++++++++++++++++++++++++-
|
||||
1 file changed, 65 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
index 519443e19..f63ac1404 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
@@ -315,6 +315,39 @@ mali: gpu@c0000 {
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
};
|
||||
|
||||
+ hdmi_tx: hdmi-tx@42000 {
|
||||
+ compatible = "amlogic,meson8-hdmi-tx";
|
||||
+ reg = <0x42000 0xc>;
|
||||
+ interrupts = <GIC_SPI 57 IRQ_TYPE_EDGE_RISING>;
|
||||
+ phys = <&hdmi_tx_phy>;
|
||||
+ phy-names = "hdmi";
|
||||
+ clocks = <&clkc CLKID_HDMI_PCLK>,
|
||||
+ <&clkc CLKID_HDMI_SYS>;
|
||||
+ clock-names = "pclk", "sys";
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ #sound-dai-cells = <1>;
|
||||
+ sound-name-prefix = "HDMITX";
|
||||
+
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ /* VPU VENC Input */
|
||||
+ hdmi_tx_venc_port: port@0 {
|
||||
+ reg = <0>;
|
||||
+
|
||||
+ hdmi_tx_in: endpoint {
|
||||
+ remote-endpoint = <&hdmi_tx_out>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ /* TMDS Output */
|
||||
+ hdmi_tx_tmds_port: port@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
vpu: vpu@100000 {
|
||||
compatible = "amlogic,meson8-vpu";
|
||||
|
||||
@@ -378,6 +411,15 @@ vpu: vpu@100000 {
|
||||
cvbs_vdac_port: port@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
+
|
||||
+ /* HDMI-TX output port */
|
||||
+ hdmi_tx_port: port@1 {
|
||||
+ reg = <1>;
|
||||
+
|
||||
+ hdmi_tx_out: endpoint {
|
||||
+ remote-endpoint = <&hdmi_tx_in>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
};
|
||||
}; /* end of / */
|
||||
@@ -544,11 +586,26 @@ gpio: banks@80b0 {
|
||||
gpio-ranges = <&pinctrl_cbus 0 0 120>;
|
||||
};
|
||||
|
||||
+ hdmi_hpd_pins: hdmi-hpd {
|
||||
+ mux {
|
||||
+ groups = "hdmi_hpd";
|
||||
+ function = "hdmi";
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ hdmi_i2c_pins: hdmi-i2c {
|
||||
+ mux {
|
||||
+ groups = "hdmi_sda", "hdmi_scl";
|
||||
+ function = "hdmi";
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
pwm_c_dv9_pins: pwm-c-dv9 {
|
||||
mux {
|
||||
groups = "pwm_c_dv9";
|
||||
function = "pwm_c";
|
||||
- bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -556,7 +613,6 @@ pwm_d_pins: pwm-d {
|
||||
mux {
|
||||
groups = "pwm_d";
|
||||
function = "pwm_d";
|
||||
- bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -740,6 +796,13 @@ pwrc: power-controller@100 {
|
||||
assigned-clocks = <&clkc CLKID_VPU>;
|
||||
assigned-clock-rates = <364285714>;
|
||||
};
|
||||
+
|
||||
+ hdmi_tx_phy: hdmi-phy@3a0 {
|
||||
+ compatible = "amlogic,meson8-hdmi-tx-phy";
|
||||
+ clocks = <&clkc CLKID_HDMI_PLL_HDMI_OUT>;
|
||||
+ reg = <0x3a0 0xc>;
|
||||
+ #phy-cells = <0>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&hwrng {
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From 1b8ef484e7a3af4367b771e74c8f72e8326f897f Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 4 Jun 2021 21:50:06 +0200
|
||||
Subject: [PATCH 61/96] ARM: dts: meson8: Add the shared CMA dma memory pool
|
||||
|
||||
The 4K HDMI modes needs more CMA memory (than the default 64MiB) to be
|
||||
reserved at boot-time. Add a shared-dma-pool with increased size so the
|
||||
4K HDMI modes can be used.
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson8.dtsi | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
index f63ac1404..de9845433 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
@@ -193,6 +193,14 @@ power-firmware@4f00000 {
|
||||
reg = <0x4f00000 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
+
|
||||
+ linux,cma {
|
||||
+ compatible = "shared-dma-pool";
|
||||
+ reusable;
|
||||
+ size = <0x10000000>;
|
||||
+ alignment = <0x400000>;
|
||||
+ linux,cma-default;
|
||||
+ };
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From 4d4c55a553ee723670f756737589633fc95894f2 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sun, 5 May 2019 11:44:08 +0200
|
||||
Subject: [PATCH 62/96] ARM: dts: meson8: add the AO CEC controller - WiP
|
||||
|
||||
WiP
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson8.dtsi | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
index de9845433..ae1047eca 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
|
||||
@@ -478,6 +478,14 @@ gpio_ao: ao-bank@14 {
|
||||
gpio-ranges = <&pinctrl_aobus 0 0 16>;
|
||||
};
|
||||
|
||||
+ hdmi_cec_ao_pins: hdmi-cec-ao {
|
||||
+ mux {
|
||||
+ groups = "hdmi_cec_ao";
|
||||
+ function = "hdmi_cec_ao";
|
||||
+ bias-pull-up;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
i2s_am_clk_pins: i2s-am-clk-out {
|
||||
mux {
|
||||
groups = "i2s_am_clk_out_ao";
|
||||
@@ -542,6 +550,15 @@ mux {
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ cec_AO: cec@100 {
|
||||
+ compatible = "amlogic,meson-gx-ao-cec"; // FIXME
|
||||
+ reg = <0x100 0x14>;
|
||||
+ interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
|
||||
+ // TODO: 32768HZ clock
|
||||
+ hdmi-phandle = <&hdmi_tx>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
};
|
||||
|
||||
&ao_arc_rproc {
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
From 15091212cb8b362780e0c54ae0e430bfeca46525 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sun, 5 May 2019 02:30:29 +0200
|
||||
Subject: [PATCH 63/96] ARM: dts: meson8b: add the HDMI controller - WiP
|
||||
|
||||
WiP
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson8b.dtsi | 69 ++++++++++++++++++++++++++
|
||||
1 file changed, 69 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8b.dtsi b/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
index 87aa74675..176b2dc71 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
@@ -277,6 +277,39 @@ mali: gpu@c0000 {
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
};
|
||||
|
||||
+ hdmi_tx: hdmi-tx@42000 {
|
||||
+ compatible = "amlogic,meson8b-hdmi-tx";
|
||||
+ reg = <0x42000 0xc>;
|
||||
+ interrupts = <GIC_SPI 57 IRQ_TYPE_EDGE_RISING>;
|
||||
+ phys = <&hdmi_tx_phy>;
|
||||
+ phy-names = "hdmi";
|
||||
+ clocks = <&clkc CLKID_HDMI_PCLK>,
|
||||
+ <&clkc CLKID_HDMI_SYS>;
|
||||
+ clock-names = "pclk", "sys";
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ #sound-dai-cells = <1>;
|
||||
+ sound-name-prefix = "HDMITX";
|
||||
+
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ /* VPU VENC Input */
|
||||
+ hdmi_tx_venc_port: port@0 {
|
||||
+ reg = <0>;
|
||||
+
|
||||
+ hdmi_tx_in: endpoint {
|
||||
+ remote-endpoint = <&hdmi_tx_out>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ /* TMDS Output */
|
||||
+ hdmi_tx_tmds_port: port@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
vpu: vpu@100000 {
|
||||
compatible = "amlogic,meson8b-vpu";
|
||||
|
||||
@@ -336,10 +369,22 @@ vpu: vpu@100000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ sound-name-prefix = "HDMITX";
|
||||
+
|
||||
/* CVBS VDAC output port */
|
||||
cvbs_vdac_port: port@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
+
|
||||
+ /* HDMI-TX output port */
|
||||
+ hdmi_tx_port: port@1 {
|
||||
+ reg = <1>;
|
||||
+
|
||||
+ hdmi_tx_out: endpoint {
|
||||
+ remote-endpoint = <&hdmi_tx_in>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
};
|
||||
}; /* end of / */
|
||||
@@ -538,6 +583,22 @@ mux {
|
||||
};
|
||||
};
|
||||
|
||||
+ hdmi_hpd_pins: hdmi-hpd {
|
||||
+ mux {
|
||||
+ groups = "hdmi_hpd";
|
||||
+ function = "hdmi";
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ hdmi_i2c_pins: hdmi-i2c {
|
||||
+ mux {
|
||||
+ groups = "hdmi_sda", "hdmi_scl";
|
||||
+ function = "hdmi";
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
i2c_a_pins: i2c-a {
|
||||
mux {
|
||||
groups = "i2c_sda_a", "i2c_sck_a";
|
||||
@@ -700,6 +761,14 @@ pwrc: power-controller@100 {
|
||||
assigned-clocks = <&clkc CLKID_VPU>;
|
||||
assigned-clock-rates = <182142857>;
|
||||
};
|
||||
+
|
||||
+ hdmi_tx_phy: hdmi-phy@3a0 {
|
||||
+ compatible = "amlogic,meson8b-hdmi-tx-phy",
|
||||
+ "amlogic,meson8-hdmi-tx-phy";
|
||||
+ clocks = <&clkc CLKID_HDMI_PLL_HDMI_OUT>;
|
||||
+ reg = <0x3a0 0xc>;
|
||||
+ #phy-cells = <0>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&hwrng {
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From 6b21e706b95e5e0c8c5b9f691f2fc64befdf8d08 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Sun, 5 May 2019 11:44:20 +0200
|
||||
Subject: [PATCH 64/96] ARM: dts: meson8b: add the AO CEC controller - WiP
|
||||
|
||||
WiP
|
||||
|
||||
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
---
|
||||
arch/arm/boot/dts/amlogic/meson8b.dtsi | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8b.dtsi b/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
index 176b2dc71..3e5d97e0c 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8b.dtsi
|
||||
@@ -435,6 +435,14 @@ gpio_ao: ao-bank@14 {
|
||||
gpio-ranges = <&pinctrl_aobus 0 0 16>;
|
||||
};
|
||||
|
||||
+ hdmi_cec_ao_pins: hdmi-cec-ao {
|
||||
+ mux {
|
||||
+ groups = "hdmi_cec_1";
|
||||
+ function = "hdmi_cec";
|
||||
+ bias-pull-up;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
i2s_am_clk_pins: i2s-am-clk-out {
|
||||
mux {
|
||||
groups = "i2s_am_clk_out";
|
||||
@@ -491,6 +499,15 @@ mux {
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ cec_AO: cec@100 {
|
||||
+ compatible = "amlogic,meson-gx-ao-cec"; // FIXME
|
||||
+ reg = <0x100 0x14>;
|
||||
+ interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
|
||||
+ // TODO: 32768HZ clock
|
||||
+ hdmi-phandle = <&hdmi_tx>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
};
|
||||
|
||||
&ao_arc_rproc {
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From e9d0d7bb75ff8234d717fb640c020ffe303a8d11 Mon Sep 17 00:00:00 2001
|
||||
From 9d61f99a90171d451718e0afb254d5733c4b4852 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Fri, 20 Mar 2020 15:17:51 +0100
|
||||
Subject: [PATCH] ARM: dts: meson8b: odroid-c1: enable HDMI for the
|
||||
Subject: [PATCH 66/96] ARM: dts: meson8b: odroid-c1: enable HDMI for the
|
||||
Odroid-C1 - WiP
|
||||
|
||||
WiP
|
||||
@@ -12,7 +12,7 @@ Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
1 file changed, 59 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts b/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts
|
||||
index 94168284..7e43212e 100644
|
||||
index eaf89638c..b03273d90 100644
|
||||
--- a/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts
|
||||
+++ b/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts
|
||||
@@ -32,6 +32,17 @@ emmc_pwrseq: emmc-pwrseq {
|
||||
@@ -69,10 +69,10 @@ index 94168284..7e43212e 100644
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
vcc_1v8: regulator-vcc-1v8 {
|
||||
/*
|
||||
* RICHTEK RT9179 configured for a fixed output voltage of
|
||||
@@ -187,6 +230,10 @@ vdd_rtc: regulator-vdd-rtc {
|
||||
usb0_vbus: regulator-usb0-vbus {
|
||||
/* Richtek RT9715EGB */
|
||||
compatible = "regulator-fixed";
|
||||
@@ -201,6 +244,10 @@ vdd_rtc: regulator-vdd-rtc {
|
||||
};
|
||||
};
|
||||
|
||||
@@ -83,7 +83,7 @@ index 94168284..7e43212e 100644
|
||||
&cpu0 {
|
||||
cpu-supply = <&vcck>;
|
||||
};
|
||||
@@ -283,6 +330,18 @@ &gpio_ao {
|
||||
@@ -297,6 +344,18 @@ &gpio_ao {
|
||||
"SYS_LED", "", "";
|
||||
};
|
||||
|
||||
@@ -103,5 +103,5 @@ index 94168284..7e43212e 100644
|
||||
status = "okay";
|
||||
pinctrl-0 = <&ir_recv_pins>;
|
||||
--
|
||||
2.34.1
|
||||
2.45.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
From d11b44bf44111b9f1d5497e92826df46ff065dbd Mon Sep 17 00:00:00 2001
|
||||
From: hzy <hzyitc@outlook.com>
|
||||
Date: Sat, 18 Nov 2023 01:22:03 +0800
|
||||
Subject: [PATCH 2/3] meson8/meson8b/meson8m2: drm: Forcefully enable XRGB
|
||||
format
|
||||
|
||||
Signed-off-by: hzy <hzyitc@outlook.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_plane.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
|
||||
index 27e39577..027b2fe7 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_plane.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_plane.c
|
||||
@@ -483,6 +483,8 @@ static const struct drm_plane_funcs meson_plane_funcs = {
|
||||
static const uint32_t supported_drm_formats_m8[] = {
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
+ DRM_FORMAT_XRGB8888,
|
||||
+ DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_RGB888,
|
||||
DRM_FORMAT_RGB565,
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
From 99a889c050d71d663aba1ba2a706348be72ca787 Mon Sep 17 00:00:00 2001
|
||||
From: hzy <hzyitc@outlook.com>
|
||||
Date: Fri, 17 Nov 2023 22:54:18 +0800
|
||||
Subject: [PATCH 3/3] drm/meson: Support meson{8,8b}-hdmi-tx components
|
||||
|
||||
Signed-off-by: hzy <hzyitc@outlook.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_drv.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
|
||||
index e8134e4c..c3e8fef9 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_drv.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_drv.c
|
||||
@@ -668,6 +668,8 @@ static void meson_drv_shutdown(struct platform_device *pdev)
|
||||
* private structure for HHI registers.
|
||||
*/
|
||||
static const struct of_device_id components_dev_match[] = {
|
||||
+ { .compatible = "amlogic,meson8-hdmi-tx" },
|
||||
+ { .compatible = "amlogic,meson8b-hdmi-tx" },
|
||||
{ .compatible = "amlogic,meson-gxbb-dw-hdmi" },
|
||||
{ .compatible = "amlogic,meson-gxl-dw-hdmi" },
|
||||
{ .compatible = "amlogic,meson-gxm-dw-hdmi" },
|
||||
--
|
||||
2.34.1
|
||||
|
||||
Reference in New Issue
Block a user