bcm27xx: pull 6.6 patches from RPi repo

Adds latest 6.6 patches from the Raspberry Pi repository.

These patches were generated from:
https://github.com/raspberrypi/linux/commits/rpi-6.6.y/
With the following command:
git format-patch -N v6.6.67..HEAD
(HEAD -> 811ff707533bcd67cdcd368bbd46223082009b12)

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
(cherry picked from commit 692205305d)
This commit is contained in:
Álvaro Fernández Rojas 2024-12-27 17:14:40 +01:00
parent cccc7651ec
commit 3a5584e0df
114 changed files with 10583 additions and 131 deletions

View File

@ -314,6 +314,7 @@ CONFIG_PRINTK_TIME=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PWM=y
CONFIG_PWM_BCM2835=y
CONFIG_PWM_GPIO=y
CONFIG_PWM_SYSFS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RASPBERRYPI_FIRMWARE=y
@ -346,6 +347,7 @@ CONFIG_SERIAL_DEV_BUS=y
# CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_RPI_FW=y
CONFIG_SG_POOL=y
CONFIG_SMSC_PHY=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y

View File

@ -398,6 +398,7 @@ CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PWM=y
CONFIG_PWM_BCM2835=y
CONFIG_PWM_GPIO=y
CONFIG_PWM_SYSFS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RAS=y
@ -435,6 +436,7 @@ CONFIG_SERIAL_DEV_BUS=y
# CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_RPI_FW=y
CONFIG_SG_POOL=y
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y

View File

@ -389,6 +389,7 @@ CONFIG_PRINTK_TIME=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PWM=y
CONFIG_PWM_BCM2835=y
CONFIG_PWM_GPIO=y
CONFIG_PWM_SYSFS=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
@ -428,6 +429,7 @@ CONFIG_SERIAL_DEV_BUS=y
# CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_RPI_FW=y
CONFIG_SG_POOL=y
CONFIG_SMP=y
CONFIG_SMSC_PHY=y

View File

@ -405,6 +405,7 @@ CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PWM=y
CONFIG_PWM_BCM2835=y
CONFIG_PWM_GPIO=y
CONFIG_PWM_SYSFS=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
@ -445,6 +446,7 @@ CONFIG_SERIAL_DEV_BUS=y
# CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_RPI_FW=y
CONFIG_SG_POOL=y
CONFIG_SMP=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y

View File

@ -513,6 +513,7 @@ CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PWM=y
CONFIG_PWM_BCM2835=y
CONFIG_PWM_BRCMSTB=y
CONFIG_PWM_GPIO=y
CONFIG_PWM_RP1=y
CONFIG_PWM_SYSFS=y
CONFIG_QUEUED_RWLOCKS=y
@ -577,6 +578,7 @@ CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSE_IRQ=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SRAM=y
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y

View File

@ -28,6 +28,8 @@
# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2 is not set
# CONFIG_RP1_PIO is not set
# CONFIG_SENSORS_RP1_ADC is not set
# CONFIG_SERIAL_RPI_FW is not set
# CONFIG_SND_PIMIDI is not set
# CONFIG_SPI_RP2040_GPIO_BRIDGE is not set
# CONFIG_VIDEO_AD5398 is not set
# CONFIG_VIDEO_ARDUCAM_64MP is not set

View File

@ -1,34 +0,0 @@
From cc63d552b9aab92fb581dfb08267d5af697f477b Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 18 Sep 2024 16:45:24 +0100
Subject: [PATCH 1267/1350] dts: rp1: Disable DMA usage for UART0
Some recent DMA changes have led to data loss in UART0 on Pi 5. It also
seems that even prior to these changes there was a problem with aborted
transfers.
As this is the only RP1 UART configured for DMA, it is better to remove
the DMA usage until it is shown to be reliable.
Link: https://github.com/raspberrypi/linux/issues/6365
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
arch/arm64/boot/dts/broadcom/rp1.dtsi | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
@@ -55,9 +55,9 @@
interrupts = <RP1_INT_UART0 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
clock-names = "uartclk", "apb_pclk";
- dmas = <&rp1_dma RP1_DMA_UART0_TX>,
- <&rp1_dma RP1_DMA_UART0_RX>;
- dma-names = "tx", "rx";
+ // dmas = <&rp1_dma RP1_DMA_UART0_TX>,
+ // <&rp1_dma RP1_DMA_UART0_RX>;
+ // dma-names = "tx", "rx";
pinctrl-names = "default";
arm,primecell-periphid = <0x00541011>;
uart-has-rtscts;

View File

@ -0,0 +1,141 @@
From 25e6acfe00f589a5989ebd2c8d21a130fb3bf106 Mon Sep 17 00:00:00 2001
From: Naushir Patuck <naush@raspberrypi.com>
Date: Fri, 18 Oct 2024 09:18:10 +0100
Subject: [PATCH] drivers: media: bcm2835_isp: Cache LS table dmabuf
Clients such as libcamera do not change the LS table dmabuf on every
frame. In such cases instead of mapping/remapping the same dmabuf on
every frame to send to the firmware, cache the dmabuf once and only
update and remap if the dmabuf has been changed by the userland client.
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
.../bcm2835-isp/bcm2835-v4l2-isp.c | 77 +++++++++++--------
1 file changed, 46 insertions(+), 31 deletions(-)
--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
@@ -139,6 +139,8 @@ struct bcm2835_isp_dev {
/* Image pipeline controls. */
int r_gain;
int b_gain;
+ struct dma_buf *last_ls_dmabuf;
+ struct mmal_parameter_lens_shading_v2 ls;
};
struct bcm2835_isp_buffer {
@@ -657,18 +659,18 @@ static void bcm2835_isp_node_stop_stream
atomic_dec(&dev->num_streaming);
/* If all ports disabled, then disable the component */
if (atomic_read(&dev->num_streaming) == 0) {
- struct bcm2835_isp_lens_shading ls;
/*
* The ISP component on the firmware has a reference to the
* dmabuf handle for the lens shading table. Pass a null handle
* to remove that reference now.
*/
- memset(&ls, 0, sizeof(ls));
+ memset(&dev->ls, 0, sizeof(dev->ls));
/* Must set a valid grid size for the FW */
- ls.grid_cell_size = 16;
+ dev->ls.grid_cell_size = 16;
set_isp_param(&dev->node[0],
MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
- &ls, sizeof(ls));
+ &dev->ls, sizeof(dev->ls));
+ dev->last_ls_dmabuf = NULL;
ret = vchiq_mmal_component_disable(dev->mmal_instance,
dev->component);
@@ -719,6 +721,36 @@ static inline unsigned int get_sizeimage
return (bpl * height * fmt->size_multiplier_x2) >> 1;
}
+static int map_ls_table(struct bcm2835_isp_dev *dev, struct dma_buf *dmabuf,
+ const struct bcm2835_isp_lens_shading *v4l2_ls)
+{
+ void *vcsm_handle;
+ int ret;
+
+ if (IS_ERR_OR_NULL(dmabuf))
+ return -EINVAL;
+
+ /*
+ * struct bcm2835_isp_lens_shading and struct
+ * mmal_parameter_lens_shading_v2 match so that we can do a
+ * simple memcpy here.
+ * Only the dmabuf to the actual table needs any manipulation.
+ */
+ memcpy(&dev->ls, v4l2_ls, sizeof(dev->ls));
+ ret = vc_sm_cma_import_dmabuf(dmabuf, &vcsm_handle);
+ if (ret) {
+ dma_buf_put(dmabuf);
+ return ret;
+ }
+
+ dev->ls.mem_handle_table = vc_sm_cma_int_handle(vcsm_handle);
+ dev->last_ls_dmabuf = dmabuf;
+
+ vc_sm_cma_free(vcsm_handle);
+
+ return 0;
+}
+
static int bcm2835_isp_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct bcm2835_isp_dev *dev =
@@ -754,44 +786,27 @@ static int bcm2835_isp_s_ctrl(struct v4l
case V4L2_CID_USER_BCM2835_ISP_LENS_SHADING:
{
struct bcm2835_isp_lens_shading *v4l2_ls;
- struct mmal_parameter_lens_shading_v2 ls;
- struct dma_buf *dmabuf;
- void *vcsm_handle;
v4l2_ls = (struct bcm2835_isp_lens_shading *)ctrl->p_new.p_u8;
- /*
- * struct bcm2835_isp_lens_shading and struct
- * mmal_parameter_lens_shading_v2 match so that we can do a
- * simple memcpy here.
- * Only the dmabuf to the actual table needs any manipulation.
- */
- memcpy(&ls, v4l2_ls, sizeof(ls));
+ struct dma_buf *dmabuf = dma_buf_get(v4l2_ls->dmabuf);
- dmabuf = dma_buf_get(v4l2_ls->dmabuf);
- if (IS_ERR_OR_NULL(dmabuf))
- return -EINVAL;
-
- ret = vc_sm_cma_import_dmabuf(dmabuf, &vcsm_handle);
- if (ret) {
- dma_buf_put(dmabuf);
- return -EINVAL;
- }
+ if (dmabuf != dev->last_ls_dmabuf)
+ ret = map_ls_table(dev, dmabuf, v4l2_ls);
- ls.mem_handle_table = vc_sm_cma_int_handle(vcsm_handle);
- if (ls.mem_handle_table)
- /* The VPU will take a reference on the vcsm handle,
+ if (!ret && dev->ls.mem_handle_table)
+ /*
+ * The VPU will take a reference on the vcsm handle,
* which in turn will retain a reference on the dmabuf.
* This code can therefore safely release all
* references to the buffer.
*/
- ret = set_isp_param(node,
- MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
- &ls,
- sizeof(ls));
+ ret =
+ set_isp_param(node,
+ MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
+ &dev->ls, sizeof(dev->ls));
else
ret = -EINVAL;
- vc_sm_cma_free(vcsm_handle);
dma_buf_put(dmabuf);
break;
}

View File

@ -0,0 +1,330 @@
From 3ab72fc21ea8576e59f6aad10bd6b1a0eae6e5eb Mon Sep 17 00:00:00 2001
From: Vincent Whitchurch <vincent.whitchurch@axis.com>
Date: Tue, 4 Jun 2024 23:00:41 +0200
Subject: [PATCH] pwm: Add GPIO PWM driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit 7f61257cd6e1ad4769b4b819668cab00f68f2556 upstream.
Add a software PWM which toggles a GPIO from a high-resolution timer.
This will naturally not be as accurate or as efficient as a hardware
PWM, but it is useful in some cases. I have for example used it for
evaluating LED brightness handling (via leds-pwm) on a board where the
LED was just hooked up to a GPIO, and for a simple verification of the
timer frequency on another platform.
Since high-resolution timers are used, sleeping GPIO chips are not
supported and are rejected in the probe function.
Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
Co-developed-by: Stefan Wahren <wahrenst@gmx.net>
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
Co-developed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Dhruva Gole <d-gole@ti.com>
Link: https://lore.kernel.org/r/20240604-pwm-gpio-v7-2-6b67cf60db92@linaro.org
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
Signed-off-by: Tim Gover <tim.gover@raspberrypi.com>
pwm: Backport pwm-gpio.c to rpi-6.6.y
---
.../driver-api/gpio/drivers-on-gpio.rst | 7 +-
drivers/pwm/Kconfig | 11 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-gpio.c | 240 ++++++++++++++++++
4 files changed, 258 insertions(+), 1 deletion(-)
create mode 100644 drivers/pwm/pwm-gpio.c
--- a/Documentation/driver-api/gpio/drivers-on-gpio.rst
+++ b/Documentation/driver-api/gpio/drivers-on-gpio.rst
@@ -27,7 +27,12 @@ hardware descriptions such as device tre
to the lines for a more permanent solution of this type.
- gpio-beeper: drivers/input/misc/gpio-beeper.c is used to provide a beep from
- an external speaker connected to a GPIO line.
+ an external speaker connected to a GPIO line. (If the beep is controlled by
+ off/on, for an actual PWM waveform, see pwm-gpio below.)
+
+- pwm-gpio: drivers/pwm/pwm-gpio.c is used to toggle a GPIO with a high
+ resolution timer producing a PWM waveform on the GPIO line, as well as
+ Linux high resolution timers can do.
- extcon-gpio: drivers/extcon/extcon-gpio.c is used when you need to read an
external connector status, such as a headset line for an audio driver or an
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -217,6 +217,17 @@ config PWM_FSL_FTM
To compile this driver as a module, choose M here: the module
will be called pwm-fsl-ftm.
+config PWM_GPIO
+ tristate "GPIO PWM support"
+ depends on GPIOLIB
+ depends on HIGH_RES_TIMERS
+ help
+ Generic PWM framework driver for software PWM toggling a GPIO pin
+ from kernel high-resolution timers.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-gpio.
+
config PWM_HIBVT
tristate "HiSilicon BVT PWM support"
depends on ARCH_HISI || COMPILE_TEST
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_PWM_CROS_EC) += pwm-cros-ec
obj-$(CONFIG_PWM_DWC) += pwm-dwc.o
obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o
+obj-$(CONFIG_PWM_GPIO) += pwm-gpio.o
obj-$(CONFIG_PWM_HIBVT) += pwm-hibvt.o
obj-$(CONFIG_PWM_IMG) += pwm-img.o
obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o
--- /dev/null
+++ b/drivers/pwm/pwm-gpio.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Generic software PWM for modulating GPIOs
+ *
+ * Copyright (C) 2020 Axis Communications AB
+ * Copyright (C) 2020 Nicola Di Lieto
+ * Copyright (C) 2024 Stefan Wahren
+ * Copyright (C) 2024 Linus Walleij
+ */
+
+#include <linux/cleanup.h>
+#include <linux/container_of.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/hrtimer.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/pwm.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+struct pwm_gpio {
+ struct hrtimer gpio_timer;
+ struct gpio_desc *gpio;
+ struct pwm_state state;
+ struct pwm_state next_state;
+
+ /* Protect internal state between pwm_ops and hrtimer */
+ spinlock_t lock;
+
+ bool changing;
+ bool running;
+ bool level;
+ struct pwm_chip chip;
+};
+
+static void pwm_gpio_round(struct pwm_state *dest, const struct pwm_state *src)
+{
+ u64 dividend;
+ u32 remainder;
+
+ *dest = *src;
+
+ /* Round down to hrtimer resolution */
+ dividend = dest->period;
+ remainder = do_div(dividend, hrtimer_resolution);
+ dest->period -= remainder;
+
+ dividend = dest->duty_cycle;
+ remainder = do_div(dividend, hrtimer_resolution);
+ dest->duty_cycle -= remainder;
+}
+
+static u64 pwm_gpio_toggle(struct pwm_gpio *gpwm, bool level)
+{
+ const struct pwm_state *state = &gpwm->state;
+ bool invert = state->polarity == PWM_POLARITY_INVERSED;
+
+ gpwm->level = level;
+ gpiod_set_value(gpwm->gpio, gpwm->level ^ invert);
+
+ if (!state->duty_cycle || state->duty_cycle == state->period) {
+ gpwm->running = false;
+ return 0;
+ }
+
+ gpwm->running = true;
+ return level ? state->duty_cycle : state->period - state->duty_cycle;
+}
+
+static enum hrtimer_restart pwm_gpio_timer(struct hrtimer *gpio_timer)
+{
+ struct pwm_gpio *gpwm = container_of(gpio_timer, struct pwm_gpio,
+ gpio_timer);
+ u64 next_toggle;
+ bool new_level;
+
+ guard(spinlock_irqsave)(&gpwm->lock);
+
+ /* Apply new state at end of current period */
+ if (!gpwm->level && gpwm->changing) {
+ gpwm->changing = false;
+ gpwm->state = gpwm->next_state;
+ new_level = !!gpwm->state.duty_cycle;
+ } else {
+ new_level = !gpwm->level;
+ }
+
+ next_toggle = pwm_gpio_toggle(gpwm, new_level);
+ if (next_toggle)
+ hrtimer_forward(gpio_timer, hrtimer_get_expires(gpio_timer),
+ ns_to_ktime(next_toggle));
+
+ return next_toggle ? HRTIMER_RESTART : HRTIMER_NORESTART;
+}
+
+static int pwm_gpio_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ struct pwm_gpio *gpwm = container_of(chip, struct pwm_gpio, chip);
+ bool invert = state->polarity == PWM_POLARITY_INVERSED;
+
+ if (state->duty_cycle && state->duty_cycle < hrtimer_resolution)
+ return -EINVAL;
+
+ if (state->duty_cycle != state->period &&
+ (state->period - state->duty_cycle < hrtimer_resolution))
+ return -EINVAL;
+
+ if (!state->enabled) {
+ hrtimer_cancel(&gpwm->gpio_timer);
+ } else if (!gpwm->running) {
+ int ret;
+
+ /*
+ * This just enables the output, but pwm_gpio_toggle()
+ * really starts the duty cycle.
+ */
+ ret = gpiod_direction_output(gpwm->gpio, invert);
+ if (ret)
+ return ret;
+ }
+
+ guard(spinlock_irqsave)(&gpwm->lock);
+
+ if (!state->enabled) {
+ pwm_gpio_round(&gpwm->state, state);
+ gpwm->running = false;
+ gpwm->changing = false;
+
+ gpiod_set_value(gpwm->gpio, invert);
+ } else if (gpwm->running) {
+ pwm_gpio_round(&gpwm->next_state, state);
+ gpwm->changing = true;
+ } else {
+ unsigned long next_toggle;
+
+ pwm_gpio_round(&gpwm->state, state);
+ gpwm->changing = false;
+
+ next_toggle = pwm_gpio_toggle(gpwm, !!state->duty_cycle);
+ if (next_toggle)
+ hrtimer_start(&gpwm->gpio_timer, next_toggle,
+ HRTIMER_MODE_REL);
+ }
+
+ return 0;
+}
+
+static int pwm_gpio_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ struct pwm_gpio *gpwm = container_of(chip, struct pwm_gpio, chip);
+
+ guard(spinlock_irqsave)(&gpwm->lock);
+
+ if (gpwm->changing)
+ *state = gpwm->next_state;
+ else
+ *state = gpwm->state;
+
+ return 0;
+}
+
+static const struct pwm_ops pwm_gpio_ops = {
+ .apply = pwm_gpio_apply,
+ .get_state = pwm_gpio_get_state,
+};
+
+static void pwm_gpio_disable_hrtimer(void *data)
+{
+ struct pwm_gpio *gpwm = data;
+
+ hrtimer_cancel(&gpwm->gpio_timer);
+}
+
+static int pwm_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct pwm_chip *chip;
+ struct pwm_gpio *gpwm;
+ int ret;
+
+ gpwm = devm_kzalloc(&pdev->dev, sizeof(*gpwm), GFP_KERNEL);
+ if (IS_ERR(gpwm))
+ return PTR_ERR(gpwm);
+
+ chip = &gpwm->chip;
+
+ spin_lock_init(&gpwm->lock);
+
+ gpwm->gpio = devm_gpiod_get(dev, NULL, GPIOD_ASIS);
+ if (IS_ERR(gpwm->gpio))
+ return dev_err_probe(dev, PTR_ERR(gpwm->gpio),
+ "%pfw: could not get gpio\n",
+ dev_fwnode(dev));
+
+ if (gpiod_cansleep(gpwm->gpio))
+ return dev_err_probe(dev, -EINVAL,
+ "%pfw: sleeping GPIO not supported\n",
+ dev_fwnode(dev));
+
+ chip->dev = dev;
+ chip->ops = &pwm_gpio_ops;
+ chip->atomic = true;
+ chip->npwm = 1;
+
+ hrtimer_init(&gpwm->gpio_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ ret = devm_add_action_or_reset(dev, pwm_gpio_disable_hrtimer, gpwm);
+ if (ret)
+ return ret;
+
+ gpwm->gpio_timer.function = pwm_gpio_timer;
+
+ return devm_pwmchip_add(dev, chip);
+}
+
+static const struct of_device_id pwm_gpio_dt_ids[] = {
+ { .compatible = "pwm-gpio" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pwm_gpio_dt_ids);
+
+static struct platform_driver pwm_gpio_driver = {
+ .driver = {
+ .name = "pwm-gpio",
+ .of_match_table = pwm_gpio_dt_ids,
+ },
+ .probe = pwm_gpio_probe,
+};
+module_platform_driver(pwm_gpio_driver);
+
+MODULE_DESCRIPTION("PWM GPIO driver");
+MODULE_AUTHOR("Vincent Whitchurch");
+MODULE_LICENSE("GPL");

View File

@ -0,0 +1,79 @@
From ff0fe12ab875d587348b6f2b9e73ae928049ebee Mon Sep 17 00:00:00 2001
From: Tim Gover <tim.gover@raspberrypi.com>
Date: Thu, 31 Oct 2024 16:12:54 +0000
Subject: [PATCH] dtoverlay: Add a dtoverlay for pwm-gpio
Signed-off-by: Tim Gover <tim.gover@raspberrypi.com>
---
arch/arm/boot/dts/overlays/Makefile | 1 +
arch/arm/boot/dts/overlays/README | 6 +++
.../boot/dts/overlays/pwm-gpio-overlay.dts | 38 +++++++++++++++++++
3 files changed, 45 insertions(+)
create mode 100644 arch/arm/boot/dts/overlays/pwm-gpio-overlay.dts
--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -217,6 +217,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
proto-codec.dtbo \
pwm.dtbo \
pwm-2chan.dtbo \
+ pwm-gpio.dtbo \
pwm-ir-tx.dtbo \
pwm1.dtbo \
qca7000.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -3903,6 +3903,12 @@ Params: pin Output p
clock PWM clock frequency (informational)
+Name: pwm-gpio
+Info: Configures the software PWM GPIO driver
+Load: dtoverlay=pwm-gpio,<param>=<val>
+Params: gpio Output pin (default 4)
+
+
Name: pwm-ir-tx
Info: Use GPIO pin as pwm-assisted infrared transmitter output.
This is an alternative to "gpio-ir-tx". pwm-ir-tx makes use
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/pwm-gpio-overlay.dts
@@ -0,0 +1,38 @@
+// Device tree overlay for software GPIO PWM.
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2835";
+
+ fragment@0 {
+ target = <&gpio>;
+ __overlay__ {
+ pwm_gpio_pins: pwm_gpio_pins@4 {
+ brcm,pins = <4>; /* gpio 4 */
+ brcm,function = <1>; /* output */
+ brcm,pull = <0>; /* pull-none */
+ };
+ };
+ };
+
+ fragment@1 {
+ target-path = "/";
+ __overlay__ {
+ pwm_gpio: pwm_gpio@4 {
+ compatible = "pwm-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_gpio_pins>;
+ gpios = <&gpio 4 0>;
+ };
+ };
+ };
+
+ __overrides__ {
+ gpio = <&pwm_gpio>,"gpios:4",
+ <&pwm_gpio_pins>,"brcm,pins:0",
+ /* modify reg values to allow multiple instantiation */
+ <&pwm_gpio>,"reg:0",
+ <&pwm_gpio_pins>,"reg:0";
+ };
+};

View File

@ -0,0 +1,29 @@
From 624eb357e1a16385b3d6171e9194e4c5f8d4fd5f Mon Sep 17 00:00:00 2001
From: Dom Cobley <popcornmix@gmail.com>
Date: Wed, 23 Oct 2024 19:09:18 +0100
Subject: [PATCH] dts: 2712: Drop some numa options from bootargs
iommu_dma_numa_policy=interleave is not valid in the current tree
It generates an unknown setting will be passed to usespace warning
system_heap.max_order=0 is wanted when numa is enabled, but may not
be when it is disabled.
Add it on firmware side when we know if numa=fake=<n> is used.
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
---
arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
@@ -99,7 +99,7 @@
/ {
chosen: chosen {
- bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe cgroup_disable=memory numa_policy=interleave iommu_dma_numa_policy=interleave system_heap.max_order=0";
+ bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe cgroup_disable=memory numa_policy=interleave";
stdout-path = "serial10:115200n8";
};

View File

@ -0,0 +1,42 @@
From 74f3ca5e39586ea26201fe6eaf1b9e6793b101b7 Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.com>
Date: Tue, 29 Oct 2024 13:33:21 +0000
Subject: [PATCH] mmc: quirks: add more broken Kingston Canvas Go! SD card date
ranges
A user has reported that a card of this model from late 2021 doesn't
work, so extend the date range and make it match on all card sizes.
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
---
drivers/mmc/core/quirks.h | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
--- a/drivers/mmc/core/quirks.h
+++ b/drivers/mmc/core/quirks.h
@@ -18,10 +18,22 @@
static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
/*
* Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
- * This has so far only been observed on cards from 11/2019, while new
- * cards from 2023/05 do not exhibit this behavior.
+ * This has been observed on cards from 2019/11 and 2021/11, while new
+ * cards from 2023/05 and 2024/08 do not exhibit this behavior.
*/
- _FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11,
+ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_KINGSTON_SD, 0x5449, 2019, CID_MONTH_ANY,
+ 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
+ MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
+
+ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_KINGSTON_SD, 0x5449, 2020, CID_MONTH_ANY,
+ 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
+ MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
+
+ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_KINGSTON_SD, 0x5449, 2021, CID_MONTH_ANY,
+ 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
+ MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
+
+ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_KINGSTON_SD, 0x5449, 2022, CID_MONTH_ANY,
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),

View File

@ -0,0 +1,35 @@
From 6c0f34fb0f83741f7f03f6bfd3fcbc89cb2c7cde Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.com>
Date: Wed, 6 Nov 2024 10:26:55 +0000
Subject: [PATCH] dt-bindings: usb: snps,dwc3: add FS/HS periodic NAK polling
quirk
Add two quirk properties that control whether or not the controller
issues many more handshakes to FS/HS Async endpoints in a single
(micro)frame. Enabling these can significantly increase throughput for
endpoints that frequently respond with NAKs.
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
---
Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
@@ -231,6 +231,16 @@ properties:
description: When set, disable u2mac linestate check during HS transmit
type: boolean
+ snps,enhanced-nak-fs-quirk:
+ description:
+ When set, the controller schedules many more handshakes to Async FS
+ endpoints, improving throughput when they frequently respond with NAKs.
+
+ snps,enhanced-nak-hs-quirk:
+ description:
+ When set, the controller schedules many more handshakes to Async HS
+ endpoints, improving throughput when they frequently respond with NAKs.
+
snps,parkmode-disable-ss-quirk:
description:
When set, disable park mode for all Superspeed bus instances.

View File

@ -0,0 +1,77 @@
From bb53ca75f9e3631e753f397ccab704a8f975658b Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.com>
Date: Wed, 6 Nov 2024 10:45:24 +0000
Subject: [PATCH] usb: dwc3: core: add support for setting NAK enhancement bits
for FS/HS
If a device frequently NAKs, it can exhaust the scheduled handshakes in
a frame. It will then not get polled by the controller until the next
frame interval. This is most noticeable on FS devices as the controller
schedules a small set of transactions only once per full-speed frame.
Setting the ENH_PER_NAK_FS/LS bits in the GUCTL1 register increases the
number of transactions that can be scheduled to Async (Control/Bulk)
endpoints in the respective frame time. In the FS case, this only
applies to FS devices directly connected to root ports.
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
---
drivers/usb/dwc3/core.c | 10 ++++++++++
drivers/usb/dwc3/core.h | 6 ++++++
2 files changed, 16 insertions(+)
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1366,6 +1366,12 @@ static int dwc3_core_init(struct dwc3 *d
if (dwc->dis_tx_ipgap_linecheck_quirk)
reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
+ if (dwc->enh_nak_fs_quirk)
+ reg |= DWC3_GUCTL1_NAK_PER_ENH_FS;
+
+ if (dwc->enh_nak_hs_quirk)
+ reg |= DWC3_GUCTL1_NAK_PER_ENH_HS;
+
if (dwc->parkmode_disable_ss_quirk)
reg |= DWC3_GUCTL1_PARKMODE_DISABLE_SS;
@@ -1669,6 +1675,10 @@ static void dwc3_get_properties(struct d
"snps,resume-hs-terminations");
dwc->ulpi_ext_vbus_drv = device_property_read_bool(dev,
"snps,ulpi-ext-vbus-drv");
+ dwc->enh_nak_fs_quirk = device_property_read_bool(dev,
+ "snps,enhanced-nak-fs-quirk");
+ dwc->enh_nak_hs_quirk = device_property_read_bool(dev,
+ "snps,enhanced-nak-hs-quirk");
dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev,
"snps,parkmode-disable-ss-quirk");
dwc->parkmode_disable_hs_quirk = device_property_read_bool(dev,
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -269,6 +269,8 @@
#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
#define DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK BIT(26)
#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24)
+#define DWC3_GUCTL1_NAK_PER_ENH_FS BIT(19)
+#define DWC3_GUCTL1_NAK_PER_ENH_HS BIT(18)
#define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17)
#define DWC3_GUCTL1_PARKMODE_DISABLE_HS BIT(16)
#define DWC3_GUCTL1_PARKMODE_DISABLE_FSLS BIT(15)
@@ -1118,6 +1120,8 @@ struct dwc3_scratchpad_array {
* generation after resume from suspend.
* @ulpi_ext_vbus_drv: Set to confiure the upli chip to drives CPEN pin
* VBUS with an external supply.
+ * @enh_nak_fs_quirk: Set to schedule more handshakes to Async FS endpoints.
+ * @enh_nak_hs_quirk: Set to schedule more handshakes to Async HS endpoints.
* @parkmode_disable_ss_quirk: If set, disable park mode feature for all
* Superspeed instances.
* @parkmode_disable_hs_quirk: If set, disable park mode feature for all
@@ -1348,6 +1352,8 @@ struct dwc3 {
unsigned dis_tx_ipgap_linecheck_quirk:1;
unsigned resume_hs_terminations:1;
unsigned ulpi_ext_vbus_drv:1;
+ unsigned enh_nak_fs_quirk:1;
+ unsigned enh_nak_hs_quirk:1;
unsigned parkmode_disable_ss_quirk:1;
unsigned parkmode_disable_hs_quirk:1;
unsigned parkmode_disable_fsls_quirk:1;

View File

@ -0,0 +1,30 @@
From 803757627b48bdad9530b50053321fdea6dfcab4 Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.com>
Date: Wed, 6 Nov 2024 10:54:58 +0000
Subject: [PATCH] DTS: rp1: set enhanced FS NAK quirk for usb3 controllers
There seem to be only benefits, and no downsides.
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
---
arch/arm64/boot/dts/broadcom/rp1.dtsi | 2 ++
1 file changed, 2 insertions(+)
--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
@@ -1077,6 +1077,7 @@
usb3-lpm-capable;
snps,axi-pipe-limit = /bits/ 8 <8>;
snps,dis_rxdet_inp3_quirk;
+ snps,enhanced-nak-fs-quirk;
snps,parkmode-disable-ss-quirk;
snps,parkmode-disable-hs-quirk;
snps,parkmode-disable-fsls-quirk;
@@ -1093,6 +1094,7 @@
usb3-lpm-capable;
snps,axi-pipe-limit = /bits/ 8 <8>;
snps,dis_rxdet_inp3_quirk;
+ snps,enhanced-nak-fs-quirk;
snps,parkmode-disable-ss-quirk;
snps,parkmode-disable-hs-quirk;
snps,parkmode-disable-fsls-quirk;

View File

@ -0,0 +1,50 @@
From e9e852af347ae3ccee4e7abb01f9ef91387980f9 Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.com>
Date: Wed, 6 Nov 2024 11:07:55 +0000
Subject: [PATCH] drivers: usb: xhci: prevent a theoretical race on
non-coherent platforms
For platforms that have xHCI controllers attached over PCIe, and
non-coherent routes to main memory, a theoretical race exists between
posting new TRBs to a ring, and writing to the doorbell register.
In a contended system, write traffic from the CPU may be stalled before
the memory controller, whereas the CPU to Endpoint route is separate
and not likely to be contended. Similarly, the DMA route from the
endpoint to main memory may be separate and uncontended.
Therefore the xHCI can receive a doorbell write and find a stale view
of a transfer ring. In cases where only a single TRB is ping-ponged at
a time, this can cause the endpoint to not get polled at all.
Adding a readl() before the write forces a round-trip transaction
across PCIe, definitively serialising the CPU along the PCI
producer-consumer ordering rules.
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
---
drivers/usb/host/xhci-ring.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -505,6 +505,19 @@ void xhci_ring_ep_doorbell(struct xhci_h
trace_xhci_ring_ep_doorbell(slot_id, DB_VALUE(ep_index, stream_id));
+ /*
+ * For non-coherent systems with PCIe DMA (such as Pi 4, Pi 5) there
+ * is a theoretical race between the TRB write and barrier, which
+ * is reported complete as soon as the write leaves the CPU domain,
+ * the doorbell write, which may be reported as complete by the RC
+ * at some arbitrary point, and the visibility of new TRBs in system
+ * RAM by the endpoint DMA engine.
+ *
+ * This read before the write positively serialises the CPU state
+ * by incurring a round-trip across the link.
+ */
+ readl(db_addr);
+
writel(DB_VALUE(ep_index, stream_id), db_addr);
/* flush the write */
readl(db_addr);

View File

@ -0,0 +1,32 @@
From ce65ed02cb6707ae5c9f3a304f5b0124f4eed559 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Mon, 4 Nov 2024 14:10:53 +0000
Subject: [PATCH] iio: humidity: dht11: Allow non-zero decimals
The DHT11 datasheet is pretty cryptic, but it does suggest that after
each integer value (humidity and temperature) there are "decimal"
values. Validate these as integers in the range 0-9 and treat them as
tenths of a unit.
Link: https://github.com/raspberrypi/linux/issues/6220
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/iio/humidity/dht11.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/iio/humidity/dht11.c
+++ b/drivers/iio/humidity/dht11.c
@@ -152,9 +152,9 @@ static int dht11_decode(struct dht11 *dh
dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) *
((temp_int & 0x80) ? -100 : 100);
dht11->humidity = ((hum_int << 8) + hum_dec) * 100;
- } else if (temp_dec == 0 && hum_dec == 0) { /* DHT11 */
- dht11->temperature = temp_int * 1000;
- dht11->humidity = hum_int * 1000;
+ } else if (temp_dec < 10 && hum_dec < 10) { /* DHT11 */
+ dht11->temperature = temp_int * 1000 + temp_dec * 100;
+ dht11->humidity = hum_int * 1000 + hum_dec * 100;
} else {
dev_err(dht11->dev,
"Don't know how to decode data: %d %d %d %d\n",

View File

@ -0,0 +1,41 @@
From c3393ac1098d1f191e37eed73bf366ebc88ac4ee Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Wed, 11 Sep 2024 14:49:05 +0100
Subject: [PATCH] drm/vc4: Correct condition for ignoring a plane to src rect
=0, not <1.0
The logic for dropping a plane less than zero didn't account for the
possibility that a plane could be being upscaled with a src_rect with
width/height < 1 pixel, but not 0 subpixels.
Check for not 0 subpixels, not < 1, in both vc4 and vc6 paths.
Fixes: dac616899f87 ("drm/vc4: Drop planes that have 0 destination size")
Fixes: f73b18eb0d48 ("drm/vc4: Drop planes that are completely off-screen")
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/vc4/vc4_plane.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -1160,7 +1160,8 @@ static int vc4_plane_mode_set(struct drm
width = vc4_state->src_w[0] >> 16;
height = vc4_state->src_h[0] >> 16;
- if (!width || !height || !vc4_state->crtc_w || !vc4_state->crtc_h) {
+ if (!vc4_state->src_w[0] || !vc4_state->src_h[0] ||
+ !vc4_state->crtc_w || !vc4_state->crtc_h) {
/* 0 source size probably means the plane is offscreen */
vc4_state->dlist_initialized = 1;
return 0;
@@ -1698,7 +1699,8 @@ static int vc6_plane_mode_set(struct drm
width = vc4_state->src_w[0] >> 16;
height = vc4_state->src_h[0] >> 16;
- if (!width || !height || !vc4_state->crtc_w || !vc4_state->crtc_h) {
+ if (!vc4_state->src_w[0] || !vc4_state->src_h[0] ||
+ !vc4_state->crtc_w || !vc4_state->crtc_h) {
/* 0 source size probably means the plane is offscreen.
* 0 destination size is a redundant plane.
*/

View File

@ -0,0 +1,59 @@
From ca621585c573cae54dc1235d90822e8bcef2f73d Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Wed, 11 Sep 2024 15:23:33 +0100
Subject: [PATCH] drm/vc4: Use the TPZ scaling filter for 1x1 source images
The documentation says that the TPZ filter can not upscale,
and requesting a scaling factor > 1:1 will output the original
image in the top left, and repeat the right/bottom most pixels
thereafter.
That fits perfectly with upscaling a 1x1 image which is done
a fair amount by some compositors to give solid colour, and it
saves a large amount of LBM (TPZ is based on src size, whilst
PPF is based on dest size).
Select TPZ filter for images with source rectangle <=1.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/vc4/vc4_plane.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -265,7 +265,11 @@ static enum vc4_scaling_mode vc4_get_sca
{
if (dst == src >> 16)
return VC4_SCALING_NONE;
- if (3 * dst >= 2 * (src >> 16))
+
+ if (src <= (1 << 16))
+ /* Source rectangle <= 1 pixel can use TPZ for resize/upscale */
+ return VC4_SCALING_TPZ;
+ else if (3 * dst >= 2 * (src >> 16))
return VC4_SCALING_PPF;
else
return VC4_SCALING_TPZ;
@@ -560,12 +564,17 @@ static void vc4_write_tpz(struct vc4_pla
WARN_ON_ONCE(vc4->gen > VC4_GEN_6);
- scale = src / dst;
+ if ((dst << 16) < src) {
+ scale = src / dst;
- /* The specs note that while the reciprocal would be defined
- * as (1<<32)/scale, ~0 is close enough.
- */
- recip = ~0 / scale;
+ /* The specs note that while the reciprocal would be defined
+ * as (1<<32)/scale, ~0 is close enough.
+ */
+ recip = ~0 / scale;
+ } else {
+ scale = (1 << 16) + 1;
+ recip = (1 << 16) - 1;
+ }
vc4_dlist_write(vc4_state,
/*

View File

@ -0,0 +1,30 @@
From 68b0ff3549148e614e1733d773cee8e689c763c6 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Tue, 20 Aug 2024 16:25:10 +0100
Subject: [PATCH] drm: Set non-desktop property to true for writeback and
virtual connectors
The non-desktop property "Indicates the output should be ignored for
purposes of displaying a standard desktop environment or console."
That sounds like it should be true for all writeback and virtual
connectors as you shouldn't render a desktop to them, so set it
by default.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/drm_connector.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -361,7 +361,8 @@ static int __drm_connector_init(struct d
drm_object_attach_property(&connector->base,
config->non_desktop_property,
- 0);
+ (connector_type != DRM_MODE_CONNECTOR_VIRTUAL &&
+ connector_type != DRM_MODE_CONNECTOR_WRITEBACK) ? 0 : 1;
drm_object_attach_property(&connector->base,
config->tile_property,
0);

View File

@ -0,0 +1,101 @@
From 8181e682d6f4ef209845ec24f0a1eb37764d6731 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Fri, 21 Oct 2022 14:26:12 +0100
Subject: [PATCH] drm: Increase plane_mask to 64bit.
The limit of 32 planes per DRM device is dictated by the use
of planes_mask returning a u32.
Change to a u64 such that 64 planes can be supported by a device.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/drm_atomic.c | 2 +-
drivers/gpu/drm/drm_framebuffer.c | 2 +-
drivers/gpu/drm/drm_mode_config.c | 2 +-
drivers/gpu/drm/drm_plane.c | 2 +-
drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c | 2 +-
include/drm/drm_crtc.h | 2 +-
include/drm/drm_plane.h | 4 ++--
7 files changed, 8 insertions(+), 8 deletions(-)
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -451,7 +451,7 @@ static void drm_atomic_crtc_print_state(
drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
- drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
+ drm_printf(p, "\tplane_mask=%llx\n", state->plane_mask);
drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -959,7 +959,7 @@ static int atomic_remove_fb(struct drm_f
struct drm_connector *conn __maybe_unused;
struct drm_connector_state *conn_state;
int i, ret;
- unsigned plane_mask;
+ u64 plane_mask;
bool disable_crtcs = false;
retry_disable:
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -636,7 +636,7 @@ void drm_mode_config_validate(struct drm
struct drm_encoder *encoder;
struct drm_crtc *crtc;
struct drm_plane *plane;
- u32 primary_with_crtc = 0, cursor_with_crtc = 0;
+ u64 primary_with_crtc = 0, cursor_with_crtc = 0;
unsigned int num_primary = 0;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -249,7 +249,7 @@ static int __drm_universal_plane_init(st
int ret;
/* plane index is used with 32bit bitmasks */
- if (WARN_ON(config->num_total_plane >= 32))
+ if (WARN_ON(config->num_total_plane >= 64))
return -EINVAL;
/*
--- a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
@@ -230,7 +230,7 @@ static int ipu_crtc_atomic_check(struct
{
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
crtc);
- u32 primary_plane_mask = drm_plane_mask(crtc->primary);
+ u64 primary_plane_mask = drm_plane_mask(crtc->primary);
if (crtc_state->active && (primary_plane_mask & crtc_state->plane_mask) == 0)
return -EINVAL;
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -192,7 +192,7 @@ struct drm_crtc_state {
* @plane_mask: Bitmask of drm_plane_mask(plane) of planes attached to
* this CRTC.
*/
- u32 plane_mask;
+ u64 plane_mask;
/**
* @connector_mask: Bitmask of drm_connector_mask(connector) of
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -915,9 +915,9 @@ static inline unsigned int drm_plane_ind
* drm_plane_mask - find the mask of a registered plane
* @plane: plane to find mask for
*/
-static inline u32 drm_plane_mask(const struct drm_plane *plane)
+static inline u64 drm_plane_mask(const struct drm_plane *plane)
{
- return 1 << drm_plane_index(plane);
+ return 1ULL << drm_plane_index(plane);
}
struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx);

View File

@ -0,0 +1,42 @@
From 5dc4cef7d7fcda4ea59b9e456a835fa54336af6b Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Fri, 21 Oct 2022 14:27:45 +0100
Subject: [PATCH] drm/vc4: Increase number of overlay planes from 16 to 48
The HVS can accept an arbitrary number of planes, provided
that the overall pixel read load is within limits, and
the display list can fit into the dlist memory.
Now that DRM will support 64 planes per device, increase
the number of overlay planes from 16 to 48 so that the
dlist complexity can be increased (eg 4x4 video wall on
each of 3 displays).
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/drm_connector.c | 2 +-
drivers/gpu/drm/vc4/vc4_plane.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -362,7 +362,7 @@ static int __drm_connector_init(struct d
drm_object_attach_property(&connector->base,
config->non_desktop_property,
(connector_type != DRM_MODE_CONNECTOR_VIRTUAL &&
- connector_type != DRM_MODE_CONNECTOR_WRITEBACK) ? 0 : 1;
+ connector_type != DRM_MODE_CONNECTOR_WRITEBACK) ? 0 : 1);
drm_object_attach_property(&connector->base,
config->tile_property,
0);
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -2517,7 +2517,7 @@ struct drm_plane *vc4_plane_init(struct
return plane;
}
-#define VC4_NUM_OVERLAY_PLANES 16
+#define VC4_NUM_OVERLAY_PLANES 48
int vc4_plane_create_additional_planes(struct drm_device *drm)
{

View File

@ -0,0 +1,71 @@
From dd340cb082a020fbd42b794493ffd063dd8e15b4 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Tue, 15 Aug 2023 15:44:34 +0100
Subject: [PATCH] drm/vc4: Assign 32 overlay planes to writeback only
Instead of having 48 generic overlay planes, assign 32 to the
writeback connector so that there is no ambiguity in wlroots
when trying to find a plane for composition using the writeback
connector vs display.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/vc4/vc4_plane.c | 34 +++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -2517,13 +2517,28 @@ struct drm_plane *vc4_plane_init(struct
return plane;
}
-#define VC4_NUM_OVERLAY_PLANES 48
+#define VC4_NUM_OVERLAY_PLANES 16
+#define VC4_NUM_TXP_OVERLAY_PLANES 32
int vc4_plane_create_additional_planes(struct drm_device *drm)
{
struct drm_plane *cursor_plane;
struct drm_crtc *crtc;
unsigned int i;
+ struct drm_crtc *txp_crtc;
+ uint32_t non_txp_crtc_mask;
+
+ drm_for_each_crtc(crtc, drm) {
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+
+ if (vc4_crtc->feeds_txp) {
+ txp_crtc = crtc;
+ break;
+ }
+ }
+
+ non_txp_crtc_mask = GENMASK(drm->mode_config.num_crtc - 1, 0) -
+ drm_crtc_mask(txp_crtc);
/* Set up some arbitrary number of planes. We're not limited
* by a set number of physical registers, just the space in
@@ -2537,7 +2552,22 @@ int vc4_plane_create_additional_planes(s
for (i = 0; i < VC4_NUM_OVERLAY_PLANES; i++) {
struct drm_plane *plane =
vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY,
- GENMASK(drm->mode_config.num_crtc - 1, 0));
+ non_txp_crtc_mask);
+
+ if (IS_ERR(plane))
+ continue;
+
+ /* Create zpos property. Max of all the overlays + 1 primary +
+ * 1 cursor plane on a crtc.
+ */
+ drm_plane_create_zpos_property(plane, i + 1, 1,
+ VC4_NUM_OVERLAY_PLANES + 1);
+ }
+
+ for (i = 0; i < VC4_NUM_TXP_OVERLAY_PLANES; i++) {
+ struct drm_plane *plane =
+ vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY,
+ drm_crtc_mask(txp_crtc));
if (IS_ERR(plane))
continue;

View File

@ -0,0 +1,47 @@
From b3b3d12cf0734318a0fed0b33e13d714188369db Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Tue, 22 Oct 2024 17:17:31 +0100
Subject: [PATCH] drm: Add a DRM_MODE_TRANSPOSE option to the DRM rotation
property
Some hardware will implement transpose as a rotation operation,
which when combined with X and Y reflect can result in a rotation,
but is a discrete operation in its own right.
Add an option for transpose only.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/drm_blend.c | 3 +++
include/uapi/drm/drm_mode.h | 1 +
2 files changed, 4 insertions(+)
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -263,6 +263,8 @@ EXPORT_SYMBOL(drm_plane_create_alpha_pro
* "reflect-x"
* DRM_MODE_REFLECT_Y:
* "reflect-y"
+ * DRM_MODE_TRANSPOSE:
+ * "transpose"
*
* Rotation is the specified amount in degrees in counter clockwise direction,
* the X and Y axis are within the source rectangle, i.e. the X/Y axis before
@@ -280,6 +282,7 @@ int drm_plane_create_rotation_property(s
{ __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
{ __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
{ __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
+ { __builtin_ffs(DRM_MODE_TRANSPOSE) - 1, "transpose" },
};
struct drm_property *prop;
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -203,6 +203,7 @@ extern "C" {
*/
#define DRM_MODE_REFLECT_X (1<<4)
#define DRM_MODE_REFLECT_Y (1<<5)
+#define DRM_MODE_TRANSPOSE (1<<6)
/*
* DRM_MODE_REFLECT_MASK

View File

@ -0,0 +1,164 @@
From 8fec3ff870499256f2c18fe7983f6ed3fea4faaf Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Tue, 22 Oct 2024 17:22:40 +0100
Subject: [PATCH] drm: Add a rotation parameter to connectors.
Some connectors, particularly writeback, can implement flip
or transpose operations as writing back to memory.
Add a connector rotation property to control this.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/drm_atomic_uapi.c | 4 +++
drivers/gpu/drm/drm_blend.c | 50 ++++++++++++++++++++++++-------
include/drm/drm_blend.h | 5 ++++
include/drm/drm_connector.h | 11 +++++++
4 files changed, 60 insertions(+), 10 deletions(-)
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -811,6 +811,8 @@ static int drm_atomic_connector_set_prop
state->max_requested_bpc = val;
} else if (property == connector->privacy_screen_sw_state_property) {
state->privacy_screen_sw_state = val;
+ } else if (property == connector->rotation_property) {
+ state->rotation = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -900,6 +902,8 @@ drm_atomic_connector_get_property(struct
*val = state->max_requested_bpc;
} else if (property == connector->privacy_screen_sw_state_property) {
*val = state->privacy_screen_sw_state;
+ } else if (property == connector->rotation_property) {
+ *val = state->rotation;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -235,6 +235,16 @@ int drm_plane_create_alpha_property(stru
}
EXPORT_SYMBOL(drm_plane_create_alpha_property);
+static const struct drm_prop_enum_list drm_rotate_props[] = {
+ { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
+ { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
+ { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
+ { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
+ { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
+ { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
+ { __builtin_ffs(DRM_MODE_TRANSPOSE) - 1, "transpose" },
+};
+
/**
* drm_plane_create_rotation_property - create a new rotation property
* @plane: drm plane
@@ -275,15 +285,6 @@ int drm_plane_create_rotation_property(s
unsigned int rotation,
unsigned int supported_rotations)
{
- static const struct drm_prop_enum_list props[] = {
- { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
- { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
- { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
- { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
- { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
- { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
- { __builtin_ffs(DRM_MODE_TRANSPOSE) - 1, "transpose" },
- };
struct drm_property *prop;
WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0);
@@ -291,7 +292,8 @@ int drm_plane_create_rotation_property(s
WARN_ON(rotation & ~supported_rotations);
prop = drm_property_create_bitmask(plane->dev, 0, "rotation",
- props, ARRAY_SIZE(props),
+ drm_rotate_props,
+ ARRAY_SIZE(drm_rotate_props),
supported_rotations);
if (!prop)
return -ENOMEM;
@@ -307,6 +309,34 @@ int drm_plane_create_rotation_property(s
}
EXPORT_SYMBOL(drm_plane_create_rotation_property);
+int drm_connector_create_rotation_property(struct drm_connector *conn,
+ unsigned int rotation,
+ unsigned int supported_rotations)
+{
+ struct drm_property *prop;
+
+ WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0);
+ WARN_ON(!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK));
+ WARN_ON(rotation & ~supported_rotations);
+
+ prop = drm_property_create_bitmask(conn->dev, 0, "rotation",
+ drm_rotate_props,
+ ARRAY_SIZE(drm_rotate_props),
+ supported_rotations);
+ if (!prop)
+ return -ENOMEM;
+
+ drm_object_attach_property(&conn->base, prop, rotation);
+
+ if (conn->state)
+ conn->state->rotation = rotation;
+
+ conn->rotation_property = prop;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_connector_create_rotation_property);
+
/**
* drm_rotation_simplify() - Try to simplify the rotation
* @rotation: Rotation to be simplified
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -34,6 +34,7 @@
struct drm_device;
struct drm_atomic_state;
struct drm_plane;
+struct drm_connector;
static inline bool drm_rotation_90_or_270(unsigned int rotation)
{
@@ -58,4 +59,8 @@ int drm_atomic_normalize_zpos(struct drm
struct drm_atomic_state *state);
int drm_plane_create_blend_mode_property(struct drm_plane *plane,
unsigned int supported_modes);
+
+int drm_connector_create_rotation_property(struct drm_connector *conn,
+ unsigned int rotation,
+ unsigned int supported_rotations);
#endif
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1029,6 +1029,11 @@ struct drm_connector_state {
* DRM blob property for HDR output metadata
*/
struct drm_property_blob *hdr_output_metadata;
+
+ /**
+ * @rotation: Connector property to rotate the maximum output image.
+ */
+ u32 rotation;
};
/**
@@ -1696,6 +1701,12 @@ struct drm_connector {
*/
struct drm_property *privacy_screen_hw_state_property;
+ /**
+ * @rotation_property: Optional DRM property controlling rotation of the
+ * output.
+ */
+ struct drm_property *rotation_property;
+
#define DRM_CONNECTOR_POLL_HPD (1 << 0)
#define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)

View File

@ -0,0 +1,65 @@
From 8346446098032c62d1de891a97c7f62264b18f81 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Wed, 14 Aug 2024 16:41:07 +0100
Subject: [PATCH] drm/vc4: txp: Add a rotation property to the writeback
connector
The txp block can implement transpose as it writes out the image
data, so expose that through the new connector rotation property.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/vc4/vc4_txp.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -15,6 +15,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
#include <drm/drm_fb_dma_helper.h>
@@ -259,10 +260,15 @@ static int vc4_txp_connector_atomic_chec
crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
fb = conn_state->writeback_job->fb;
- if (fb->width != crtc_state->mode.hdisplay ||
- fb->height != crtc_state->mode.vdisplay) {
- DRM_DEBUG_KMS("Invalid framebuffer size %ux%u\n",
- fb->width, fb->height);
+ if ((conn_state->rotation == DRM_MODE_ROTATE_0 &&
+ fb->width != crtc_state->mode.hdisplay &&
+ fb->height != crtc_state->mode.vdisplay) ||
+ (conn_state->rotation == (DRM_MODE_ROTATE_0 | DRM_MODE_TRANSPOSE) &&
+ fb->width != crtc_state->mode.vdisplay &&
+ fb->height != crtc_state->mode.hdisplay)) {
+ DRM_DEBUG_KMS("Invalid framebuffer size %ux%u vs mode %ux%u\n",
+ fb->width, fb->height,
+ crtc_state->mode.hdisplay, crtc_state->mode.vdisplay);
return -EINVAL;
}
@@ -330,6 +336,9 @@ static void vc4_txp_connector_atomic_com
*/
ctrl |= TXP_ALPHA_INVERT;
+ if (conn_state->rotation & DRM_MODE_TRANSPOSE)
+ ctrl |= TXP_TRANSPOSE;
+
if (!drm_dev_enter(drm, &idx))
return;
@@ -608,6 +617,10 @@ static int vc4_txp_bind(struct device *d
if (ret)
return ret;
+ drm_connector_create_rotation_property(&txp->connector.base, DRM_MODE_ROTATE_0,
+ DRM_MODE_ROTATE_0 |
+ DRM_MODE_TRANSPOSE);
+
ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0,
dev_name(dev), txp);
if (ret)

View File

@ -0,0 +1,40 @@
From a2fa911d90495762047c05dec4241308ae61ca36 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 19 Sep 2024 18:05:00 +0100
Subject: [PATCH] dmaengine: dw-axi-dmac: Allow client-chosen width
For devices where transfer lengths are not known upfront, there is a
danger when the destination is wider than the source that partial words
can be lost at the end of a transfer. Ideally the controller would be
able to flush the residue, but it can't - it's not even possible to tell
that there is any.
Instead, allow the client driver to avoid the problem by setting a
smaller width.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -724,6 +724,18 @@ static int dw_axi_dma_set_hw_desc(struct
case DMA_DEV_TO_MEM:
reg_burst_msize = axi_dma_encode_msize(chan->config.src_maxburst);
reg_width = __ffs(chan->config.src_addr_width);
+ /*
+ * For devices where transfer lengths are not known upfront,
+ * there is a danger when the destination is wider than the
+ * source that partial words can be lost at the end of a transfer.
+ * Ideally the controller would be able to flush the residue, but
+ * it can't - it's not even possible to tell that there is any.
+ * Instead, allow the client driver to avoid the problem by setting
+ * a smaller width.
+ */
+ if (chan->config.dst_addr_width &&
+ (chan->config.dst_addr_width < mem_width))
+ mem_width = chan->config.dst_addr_width;
device_addr = phys_to_dma(chan->chip->dev, chan->config.src_addr);
ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS |
mem_width << CH_CTL_L_DST_WIDTH_POS |

View File

@ -0,0 +1,31 @@
From 5cf7209c294a58029984880d4858e2d3c7e46a3c Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 19 Sep 2024 18:12:12 +0100
Subject: [PATCH] spi: dw: Let the DMAC set the transfer widths
SPI transfers are of defined length, unlike some UART traffic, so it is
safe to let the DMA controller choose a suitable memory width.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/spi/spi-dw-dma.c | 2 --
1 file changed, 2 deletions(-)
--- a/drivers/spi/spi-dw-dma.c
+++ b/drivers/spi/spi-dw-dma.c
@@ -330,7 +330,6 @@ static int dw_spi_dma_config_tx(struct d
txconf.direction = DMA_MEM_TO_DEV;
txconf.dst_addr = dws->dma_addr;
txconf.dst_maxburst = dws->txburst;
- txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
txconf.dst_addr_width = dw_spi_dma_convert_width(dws->n_bytes);
txconf.device_fc = false;
@@ -431,7 +430,6 @@ static int dw_spi_dma_config_rx(struct d
rxconf.direction = DMA_DEV_TO_MEM;
rxconf.src_addr = dws->dma_addr;
rxconf.src_maxburst = dws->rxburst;
- rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
rxconf.src_addr_width = dw_spi_dma_convert_width(dws->n_bytes);
rxconf.device_fc = false;

View File

@ -0,0 +1,25 @@
From 8894298105f4cb41dfa41e0b0d3c40c3f7b92c44 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 19 Sep 2024 18:22:24 +0100
Subject: [PATCH] serial: pl011: Request a memory width of 1 byte
In order to avoid losing residue bytes when a receive is terminated
early, set the destination width to single bytes.
Link: https://github.com/raspberrypi/linux/issues/6365
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/tty/serial/amba-pl011.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -468,6 +468,7 @@ static void pl011_dma_probe(struct uart_
.src_addr = uap->port.mapbase +
pl011_reg_to_offset(uap, REG_DR),
.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+ .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.direction = DMA_DEV_TO_MEM,
.src_maxburst = uap->fifosize >> 2,
.device_fc = false,

View File

@ -0,0 +1,56 @@
From 66aef6ce3557edd9d58d794e4a800c5be49ca0e7 Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.com>
Date: Mon, 11 Nov 2024 10:30:38 +0000
Subject: [PATCH] drivers: usb: xhci: set HID bit in streaming endpoint
contexts
The xHC may commence Host Initiated Data Moves for streaming endpoints -
see USB3.2 spec s8.12.1.4.2.4. However, this behaviour is typically
counterproductive as the submission of UAS URBs in {Status, Data,
Command} order and 1 outstanding IO per stream ID means the device never
enters Move Data after a HIMD for Status or Data stages with the same
stream ID. For OUT transfers this is especially inefficient as the host
will start transmitting multiple bulk packets as a burst, all of which
get NAKed by the device - wasting bandwidth.
Also, some buggy UAS adapters don't properly handle the EP flow control
state this creates - e.g. RTL9210.
Set Host Initiated Data Move Disable to always defer stream selection to
the device. xHC implementations may treat this field as "don't care,
forced to 1" anyway - xHCI 1.2 s4.12.1.
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
---
drivers/usb/host/xhci-mem.c | 8 ++++++++
drivers/usb/host/xhci.h | 2 ++
2 files changed, 10 insertions(+)
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -716,6 +716,14 @@ void xhci_setup_streams_ep_input_ctx(str
ep_ctx->ep_info &= cpu_to_le32(~EP_MAXPSTREAMS_MASK);
ep_ctx->ep_info |= cpu_to_le32(EP_MAXPSTREAMS(max_primary_streams)
| EP_HAS_LSA);
+
+ /*
+ * Set Host Initiated Data Move Disable to always defer stream
+ * selection to the device. xHC implementations may treat this
+ * field as "don't care, forced to 1" anyway - xHCI 1.2 s4.12.1.
+ */
+ ep_ctx->ep_info2 |= EP_HID;
+
ep_ctx->deq = cpu_to_le64(stream_info->ctx_array_dma);
}
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -492,6 +492,8 @@ struct xhci_ep_ctx {
#define CTX_TO_EP_MAXPSTREAMS(p) (((p) & EP_MAXPSTREAMS_MASK) >> 10)
/* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */
#define EP_HAS_LSA (1 << 15)
+/* Host initiated data move disable in info2 */
+#define EP_HID (1 << 7)
/* hosts with LEC=1 use bits 31:24 as ESIT high bits. */
#define CTX_TO_MAX_ESIT_PAYLOAD_HI(p) (((p) >> 24) & 0xff)

View File

@ -0,0 +1,199 @@
From 35e50ee3d66e014d869f0d7a3468bef964d26d32 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Thu, 14 Nov 2024 13:14:02 +0000
Subject: [PATCH] media: i2c: imx477: Add options for slightly modifying the
link freq
The default link frequency of 450MHz has been noted to interfere
with GPS if they are in close proximty.
Add the option for 453 and 456MHz to move the signal slightly out
of the band. (447MHz can not be offered as corruption is then observed
on the 133x992 10bit mode).
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
fixup imx477 gps
---
drivers/media/i2c/imx477.c | 86 +++++++++++++++++++++++++++++---------
1 file changed, 67 insertions(+), 19 deletions(-)
--- a/drivers/media/i2c/imx477.c
+++ b/drivers/media/i2c/imx477.c
@@ -164,8 +164,48 @@ struct imx477_mode {
struct imx477_reg_list reg_list;
};
-static const s64 imx477_link_freq_menu[] = {
- IMX477_DEFAULT_LINK_FREQ,
+/* Link frequency setup */
+enum {
+ IMX477_LINK_FREQ_450MHZ,
+ IMX477_LINK_FREQ_453MHZ,
+ IMX477_LINK_FREQ_456MHZ,
+};
+
+static const s64 link_freqs[] = {
+ [IMX477_LINK_FREQ_450MHZ] = 450000000,
+ [IMX477_LINK_FREQ_453MHZ] = 453000000,
+ [IMX477_LINK_FREQ_456MHZ] = 456000000,
+};
+
+/* 450MHz is the nominal "default" link frequency */
+static const struct imx477_reg link_450Mhz_regs[] = {
+ {0x030E, 0x00},
+ {0x030F, 0x96},
+};
+
+static const struct imx477_reg link_453Mhz_regs[] = {
+ {0x030E, 0x00},
+ {0x030F, 0x97},
+};
+
+static const struct imx477_reg link_456Mhz_regs[] = {
+ {0x030E, 0x00},
+ {0x030F, 0x98},
+};
+
+static const struct imx477_reg_list link_freq_regs[] = {
+ [IMX477_LINK_FREQ_450MHZ] = {
+ .regs = link_450Mhz_regs,
+ .num_of_regs = ARRAY_SIZE(link_450Mhz_regs)
+ },
+ [IMX477_LINK_FREQ_453MHZ] = {
+ .regs = link_453Mhz_regs,
+ .num_of_regs = ARRAY_SIZE(link_453Mhz_regs)
+ },
+ [IMX477_LINK_FREQ_456MHZ] = {
+ .regs = link_456Mhz_regs,
+ .num_of_regs = ARRAY_SIZE(link_456Mhz_regs)
+ },
};
static const struct imx477_reg mode_common_regs[] = {
@@ -558,8 +598,6 @@ static const struct imx477_reg mode_4056
{0x0309, 0x0c},
{0x030b, 0x02},
{0x030d, 0x02},
- {0x030e, 0x00},
- {0x030f, 0x96},
{0x0310, 0x01},
{0x0820, 0x07},
{0x0821, 0x08},
@@ -659,8 +697,6 @@ static const struct imx477_reg mode_2028
{0x0309, 0x0c},
{0x030b, 0x02},
{0x030d, 0x02},
- {0x030e, 0x00},
- {0x030f, 0x96},
{0x0310, 0x01},
{0x0820, 0x07},
{0x0821, 0x08},
@@ -760,8 +796,6 @@ static const struct imx477_reg mode_2028
{0x0309, 0x0c},
{0x030b, 0x02},
{0x030d, 0x02},
- {0x030e, 0x00},
- {0x030f, 0x96},
{0x0310, 0x01},
{0x0820, 0x07},
{0x0821, 0x08},
@@ -890,8 +924,6 @@ static const struct imx477_reg mode_1332
{0x0309, 0x0a},
{0x030b, 0x02},
{0x030d, 0x02},
- {0x030e, 0x00},
- {0x030f, 0x96},
{0x0310, 0x01},
{0x0820, 0x07},
{0x0821, 0x08},
@@ -1121,6 +1153,8 @@ struct imx477 {
struct v4l2_ctrl *vblank;
struct v4l2_ctrl *hblank;
+ unsigned int link_freq_idx;
+
/* Current mode */
const struct imx477_mode *mode;
@@ -1712,7 +1746,7 @@ static int imx477_get_selection(struct v
static int imx477_start_streaming(struct imx477 *imx477)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
- const struct imx477_reg_list *reg_list;
+ const struct imx477_reg_list *reg_list, *freq_regs;
const struct imx477_reg_list *extra_regs;
int ret, tm;
@@ -1725,6 +1759,13 @@ static int imx477_start_streaming(struct
extra_regs->num_of_regs);
}
+ if (!ret) {
+ /* Update the link frequency registers */
+ freq_regs = &link_freq_regs[imx477->link_freq_idx];
+ ret = imx477_write_regs(imx477, freq_regs->regs,
+ freq_regs->num_of_regs);
+ }
+
if (ret) {
dev_err(&client->dev, "%s failed to set common settings\n",
__func__);
@@ -2010,9 +2051,8 @@ static int imx477_init_controls(struct i
/* LINK_FREQ is also read only */
imx477->link_freq =
v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx477_ctrl_ops,
- V4L2_CID_LINK_FREQ,
- ARRAY_SIZE(imx477_link_freq_menu) - 1, 0,
- imx477_link_freq_menu);
+ V4L2_CID_LINK_FREQ, 1, 0,
+ &link_freqs[imx477->link_freq_idx]);
if (imx477->link_freq)
imx477->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
@@ -2110,13 +2150,14 @@ static void imx477_free_controls(struct
mutex_destroy(&imx477->mutex);
}
-static int imx477_check_hwcfg(struct device *dev)
+static int imx477_check_hwcfg(struct device *dev, struct imx477 *imx477)
{
struct fwnode_handle *endpoint;
struct v4l2_fwnode_endpoint ep_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
int ret = -EINVAL;
+ int i;
endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
if (!endpoint) {
@@ -2141,11 +2182,18 @@ static int imx477_check_hwcfg(struct dev
goto error_out;
}
- if (ep_cfg.nr_of_link_frequencies != 1 ||
- ep_cfg.link_frequencies[0] != IMX477_DEFAULT_LINK_FREQ) {
+ for (i = 0; i < ARRAY_SIZE(link_freqs); i++) {
+ if (link_freqs[i] == ep_cfg.link_frequencies[0]) {
+ imx477->link_freq_idx = i;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(link_freqs)) {
dev_err(dev, "Link frequency not supported: %lld\n",
ep_cfg.link_frequencies[0]);
- goto error_out;
+ ret = -EINVAL;
+ goto error_out;
}
ret = 0;
@@ -2206,7 +2254,7 @@ static int imx477_probe(struct i2c_clien
(const struct imx477_compatible_data *)match->data;
/* Check the hardware configuration in device tree */
- if (imx477_check_hwcfg(dev))
+ if (imx477_check_hwcfg(dev, imx477))
return -EINVAL;
/* Default the trigger mode from OF to -1, which means invalid */

View File

@ -0,0 +1,43 @@
From 7e253a062d5a14de13ccfb410570975099c238be Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Thu, 14 Nov 2024 13:15:24 +0000
Subject: [PATCH] dtoverlays: Add link-frequency override to imx477/378 overlay
Copy of the imx708 change.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
arch/arm/boot/dts/overlays/README | 4 ++++
arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi | 1 +
2 files changed, 5 insertions(+)
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -2780,6 +2780,8 @@ Params: rotation Mounting
camera clamping I/Os such as XVS to 0V.
sync-source Configure as vsync source
sync-sink Configure as vsync sink
+ link-frequency Allowable link frequency values to use in Hz:
+ 450000000 (default), 453000000, 456000000.
Name: imx462
@@ -2822,6 +2824,8 @@ Params: rotation Mounting
camera clamping I/Os such as XVS to 0V.
sync-source Configure as vsync source
sync-sink Configure as vsync sink
+ link-frequency Allowable link frequency values to use in Hz:
+ 450000000 (default), 453000000, 456000000.
Name: imx500
--- a/arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi
+++ b/arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi
@@ -80,6 +80,7 @@
<&cam_node>, "clocks:0=",<&cam0_clk>,
<&cam_node>, "VANA-supply:0=",<&cam0_reg>;
always-on = <0>, "+99";
+ link-frequency = <&cam_endpoint>,"link-frequencies#0";
};
};

View File

@ -0,0 +1,29 @@
From 59a8855b51c1d8acf37d3c80f34782d71f474617 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 13 Nov 2024 10:37:22 +0000
Subject: [PATCH] dmaengine: dw-axi-dmac: Only start idle channels
Attempting to start a non-idle channel causes an error message to be
logged, and is inefficient. Test for emptiness of the desc_issued list
before doing so.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -536,9 +536,11 @@ static void dma_chan_issue_pending(struc
{
struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
unsigned long flags;
+ bool was_empty;
spin_lock_irqsave(&chan->vc.lock, flags);
- if (vchan_issue_pending(&chan->vc))
+ was_empty = list_empty(&chan->vc.desc_issued);
+ if (vchan_issue_pending(&chan->vc) && was_empty)
axi_chan_start_first_queued(chan);
spin_unlock_irqrestore(&chan->vc.lock, flags);
}

View File

@ -0,0 +1,118 @@
From 0b76dec8dfba8c1a4793dff0c86bf73d088a812e Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Fri, 1 Nov 2024 09:12:01 +0000
Subject: [PATCH] dts: bcm2712-rpi: Add RP1 firmware and mailboxes
Declare the communications channel to RP1.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
.../boot/dts/broadcom/bcm2712-rpi-5-b.dts | 4 +--
.../boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 4 +--
arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 4 +++
arch/arm64/boot/dts/broadcom/rp1.dtsi | 27 +++++++++++++++++++
4 files changed, 35 insertions(+), 4 deletions(-)
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
@@ -195,7 +195,7 @@ i2c_rp1boot: &_i2c3 { };
// This is the RP1 peripheral space
ranges = <0xc0 0x40000000
0x02000000 0x00 0x00000000
- 0x00 0x00400000>;
+ 0x00 0x00410000>;
dma-ranges =
// inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
@@ -207,7 +207,7 @@ i2c_rp1boot: &_i2c3 { };
// This allows the RP1 DMA controller to address RP1 hardware
<0xc0 0x40000000
0x02000000 0x0 0x00000000
- 0x0 0x00400000>,
+ 0x0 0x00410000>,
// inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
<0x00 0x00000000
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
@@ -176,7 +176,7 @@ i2c_rp1boot: &_i2c3 { };
// This is the RP1 peripheral space
ranges = <0xc0 0x40000000
0x02000000 0x00 0x00000000
- 0x00 0x00400000>;
+ 0x00 0x00410000>;
dma-ranges =
// inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
@@ -188,7 +188,7 @@ i2c_rp1boot: &_i2c3 { };
// This allows the RP1 DMA controller to address RP1 hardware
<0xc0 0x40000000
0x02000000 0x0 0x00000000
- 0x0 0x00400000>,
+ 0x0 0x00410000>,
// inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
<0x00 0x00000000
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
@@ -294,6 +294,10 @@ pciex4: &pcie2 { };
status = "okay";
};
+&rp1_mbox {
+ status = "okay";
+};
+
/* Add some gpiomem nodes to make the devices accessible to userspace.
* /dev/gpiomem<n> should expose the registers for the interface with DT alias
* gpio<n>.
--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
@@ -13,6 +13,14 @@
// ranges and dma-ranges must be provided by the includer
+ rp1_mbox: mailbox@8000 {
+ compatible = "raspberrypi,rp1-mbox";
+ status = "disabled";
+ reg = <0xc0 0x40008000 0x0 0x4000>; // SYSCFG
+ interrupts = <RP1_INT_SYSCFG IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ };
+
rp1_clocks: clocks@18000 {
compatible = "raspberrypi,rp1-clocks";
#clock-cells = <1>;
@@ -1183,6 +1191,19 @@
assigned-clocks = <&rp1_clocks RP1_CLK_DPI>;
assigned-clock-parents = <&rp1_clocks RP1_PLL_VIDEO>;
};
+
+ sram: sram@400000 {
+ compatible = "mmio-sram";
+ reg = <0xc0 0x40400000 0x0 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0xc0 0x40400000 0x10000>;
+
+ rp1_fw_shmem: shmem@ff00 {
+ compatible = "raspberrypi,rp1-shmem";
+ reg = <0xff00 0x100>; // firmware mailbox buffer
+ };
+ };
};
};
@@ -1281,6 +1302,12 @@
};
/ {
+ rp1_firmware: rp1_firmware {
+ compatible = "raspberrypi,rp1-firmware", "simple-mfd";
+ mboxes = <&rp1_mbox 0>;
+ shmem = <&rp1_fw_shmem>;
+ };
+
rp1_vdd_3v3: rp1_vdd_3v3 {
compatible = "regulator-fixed";
regulator-name = "vdd-3v3";

View File

@ -0,0 +1,55 @@
From 3e3c1b9922b22d362a4a9133361597ac80b974bb Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Fri, 1 Nov 2024 09:13:53 +0000
Subject: [PATCH] dts: bcm2712-rpi: Add the RP1 PIO device
Declare the device that proxies RP1's PIO hardware.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 5 +++++
arch/arm64/boot/dts/broadcom/rp1.dtsi | 12 ++++++++++++
2 files changed, 17 insertions(+)
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
@@ -97,6 +97,10 @@
};
};
+pio: &rp1_pio {
+ status = "okay";
+};
+
/ {
chosen: chosen {
bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe cgroup_disable=memory numa_policy=interleave";
@@ -129,6 +133,7 @@
i2c12 = &i2c_rp1boot;
mailbox = &mailbox;
mmc0 = &sdio1;
+ pio0 = &pio;
serial0 = &uart0;
serial1 = &uart1;
serial10 = &uart10;
--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
@@ -1028,6 +1028,18 @@
status = "disabled";
};
+ rp1_pio: pio@178000 {
+ reg = <0xc0 0x40178000 0x0 0x20>;
+ compatible = "raspberrypi,rp1-pio";
+ firmware = <&rp1_firmware>;
+ dmas = <&rp1_dma RP1_DMA_PIO_CH0_TX>, <&rp1_dma RP1_DMA_PIO_CH0_RX>,
+ <&rp1_dma RP1_DMA_PIO_CH1_TX>, <&rp1_dma RP1_DMA_PIO_CH1_RX>,
+ <&rp1_dma RP1_DMA_PIO_CH2_TX>, <&rp1_dma RP1_DMA_PIO_CH2_RX>,
+ <&rp1_dma RP1_DMA_PIO_CH3_TX>, <&rp1_dma RP1_DMA_PIO_CH3_RX>;
+ dma-names = "tx0", "rx0", "tx1", "rx1", "tx2", "rx2", "tx3", "rx3";
+ status = "disabled";
+ };
+
rp1_mmc0: mmc@180000 {
reg = <0xc0 0x40180000 0x0 0x100>;
compatible = "raspberrypi,rp1-dwcmshc";

View File

@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -454,6 +454,17 @@ config PWM_PCA9685
@@ -465,6 +465,17 @@ config PWM_PCA9685
To compile this driver as a module, choose M here: the module
will be called pwm-pca9685.
@ -35,7 +35,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
@@ -42,6 +42,7 @@ obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o
obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o

View File

@ -0,0 +1,99 @@
From ba7e2e3d03a432acbc338c6c03e46dcd97cfa1b3 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 7 Nov 2024 11:41:33 +0000
Subject: [PATCH] overlays: Add pwm-pio overlay
Add an overlay to enable a single-channel PIO-assisted PWM interface on any
header pin.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
arch/arm/boot/dts/overlays/Makefile | 1 +
arch/arm/boot/dts/overlays/README | 8 ++++
arch/arm/boot/dts/overlays/overlay_map.dts | 4 ++
.../arm/boot/dts/overlays/pwm-pio-overlay.dts | 39 +++++++++++++++++++
4 files changed, 52 insertions(+)
create mode 100644 arch/arm/boot/dts/overlays/pwm-pio-overlay.dts
--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -219,6 +219,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
pwm-2chan.dtbo \
pwm-gpio.dtbo \
pwm-ir-tx.dtbo \
+ pwm-pio.dtbo \
pwm1.dtbo \
qca7000.dtbo \
qca7000-uart0.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -3926,6 +3926,14 @@ Params: gpio_pin Output G
func Pin function (default 2 = Alt5)
+Name: pwm-pio
+Info: Configures a GPIO pin as PIO-assisted PWM output. Unlike hardware PWM,
+ this can be used on any RP1 GPIO in bank 0 (0-27). Up to 4 are
+ supported, assuming nothing else is using PIO. Pi 5 only.
+Load: dtoverlay=pwm-pio,<param>=<val>
+Params: gpio Output GPIO (0-27, default 4)
+
+
Name: pwm1
Info: Configures one or two PWM channel on PWM1 (BCM2711 only)
N.B.:
--- a/arch/arm/boot/dts/overlays/overlay_map.dts
+++ b/arch/arm/boot/dts/overlays/overlay_map.dts
@@ -240,6 +240,10 @@
bcm2712;
};
+ pwm-pio {
+ bcm2712;
+ };
+
pwm1 {
bcm2711;
};
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/pwm-pio-overlay.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+// Device tree overlay for RP1 PIO PWM.
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2712";
+
+ fragment@0 {
+ target = <&gpio>;
+ __overlay__ {
+ pwm_pio_pins: pwm_pio_pins@4 {
+ brcm,pins = <4>; /* gpio 4 */
+ function = "pio";
+ bias-disable;
+ };
+ };
+ };
+
+ fragment@1 {
+ target-path = "/";
+ __overlay__ {
+ pwm_pio: pwm_pio@4 {
+ compatible = "raspberrypi,pwm-pio-rp1";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pio_pins>;
+ gpios = <&gpio 4 0>;
+ };
+ };
+ };
+
+ __overrides__ {
+ gpio = <&pwm_pio>,"gpios:4",
+ <&pwm_pio_pins>,"brcm,pins:0",
+ /* modify reg values to allow multiple instantiation */
+ <&pwm_pio>,"reg:0",
+ <&pwm_pio_pins>,"reg:0";
+ };
+};

View File

@ -1,7 +1,7 @@
From b4472d09b1ffdafd8132803ffbec62596e559fd8 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Mon, 18 Nov 2024 09:10:52 +0000
Subject: [PATCH 1394/1482] misc: rp1-pio: Add compat_ioctl method
Subject: [PATCH] misc: rp1-pio: Add compat_ioctl method
Provide a compat_ioctl method, to support running a 64-bit kernel with
a 32-bit userland.
@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/misc/rp1-pio.c
+++ b/drivers/misc/rp1-pio.c
@@ -1023,11 +1023,75 @@ static long rp1_pio_ioctl(struct file *f
@@ -996,11 +996,75 @@ static long rp1_pio_ioctl(struct file *f
return ret;
}

View File

@ -1,7 +1,7 @@
From 24cb07b0c0724a22e474d12e7c2d5b834bf3b076 Mon Sep 17 00:00:00 2001
From 0e4968617aad7d0f88e0a630499202eaae407a19 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Tue, 26 Mar 2024 15:57:46 +0000
Subject: [PATCH 0998/1085] i2c: designware: Add support for bus clear feature
Subject: [PATCH] i2c: designware: Add support for bus clear feature
Newer versions of the DesignWare I2C block support the detection of
stuck signals, and a mechanism to recover from them. Add the required
@ -108,7 +108,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
DW_IC_TX_ABRT_10ADDR1_NOACK | \
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -212,6 +212,7 @@ static int i2c_dw_set_timings_master(str
@@ -215,6 +215,7 @@ static int i2c_dw_set_timings_master(str
*/
static int i2c_dw_init_master(struct dw_i2c_dev *dev)
{
@ -116,7 +116,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
int ret;
ret = i2c_dw_acquire_lock(dev);
@@ -235,6 +236,17 @@ static int i2c_dw_init_master(struct dw_
@@ -238,6 +239,17 @@ static int i2c_dw_init_master(struct dw_
regmap_write(dev->map, DW_IC_HS_SCL_LCNT, dev->hs_lcnt);
}
@ -134,7 +134,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
/* Write SDA hold time if supported */
if (dev->sda_hold_time)
regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time);
@@ -1071,6 +1083,7 @@ int i2c_dw_probe_master(struct dw_i2c_de
@@ -1074,6 +1086,7 @@ int i2c_dw_probe_master(struct dw_i2c_de
struct i2c_adapter *adap = &dev->adapter;
unsigned long irq_flags;
unsigned int ic_con;
@ -142,7 +142,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
int ret;
init_completion(&dev->cmd_complete);
@@ -1106,7 +1119,11 @@ int i2c_dw_probe_master(struct dw_i2c_de
@@ -1109,7 +1122,11 @@ int i2c_dw_probe_master(struct dw_i2c_de
if (ret)
return ret;

View File

@ -0,0 +1,108 @@
From dbf12796d1368286672529d7b03f81066a8c36f3 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ikerpedrosam@gmail.com>
Date: Mon, 18 Nov 2024 10:55:33 +0100
Subject: [PATCH] dtoverlays: enable SPI CS active-high
The documentation isn't very clear explaining how to enable SPI CS
active-high and it takes a long time to understand it. Adding a specific
overlay as a simple example on how to invert this signal can help
understand the solution.
Link: https://forums.raspberrypi.com/viewtopic.php?t=378222
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/arm/boot/dts/overlays/Makefile | 1 +
arch/arm/boot/dts/overlays/README | 8 +++
.../overlays/spi0-1cs-inverted-overlay.dts | 59 +++++++++++++++++++
3 files changed, 68 insertions(+)
create mode 100644 arch/arm/boot/dts/overlays/spi0-1cs-inverted-overlay.dts
--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -259,6 +259,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
spi-rtc.dtbo \
spi0-0cs.dtbo \
spi0-1cs.dtbo \
+ spi0-1cs-inverted.dtbo \
spi0-2cs.dtbo \
spi1-1cs.dtbo \
spi1-2cs.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -4438,6 +4438,14 @@ Params: cs0_pin GPIO pin
it for other uses.
+Name: spi0-1cs-inverted
+Info: Only use one CS pin for SPI0 and set to active-high
+Load: dtoverlay=spi0-1cs-inverted,<param>=<val>
+Params: cs0_pin GPIO pin for CS0 (default 8)
+ no_miso Don't claim and use the MISO pin (9), freeing
+ it for other uses.
+
+
Name: spi0-2cs
Info: Change the CS pins for SPI0
Load: dtoverlay=spi0-2cs,<param>=<val>
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/spi0-1cs-inverted-overlay.dts
@@ -0,0 +1,59 @@
+/dts-v1/;
+/plugin/;
+
+/*
+ * There are some devices that need an inverted Chip Select (CS) to select the
+ * device signal, as an example the AZDelivery 12864 display. That means that
+ * the CS polarity is active-high. To invert the CS signal the DT needs to set
+ * the cs-gpio to GPIO_ACTIVE_HIGH (0) in the controller and set the
+ * spi-cs-high in the peripheral property. On top of that, since this is a
+ * display the DT also needs to specify the write-only property.
+*/
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ compatible = "brcm,bcm2835";
+
+ fragment@0 {
+ target = <&spi0_cs_pins>;
+ frag0: __overlay__ {
+ brcm,pins = <8>;
+ };
+ };
+
+ fragment@1 {
+ target = <&spi0>;
+ frag1: __overlay__ {
+ cs-gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+ };
+
+ fragment@2 {
+ target = <&spidev1>;
+ __overlay__ {
+ status = "disabled";
+ };
+ };
+
+ fragment@3 {
+ target = <&spi0_pins>;
+ __dormant__ {
+ brcm,pins = <10 11>;
+ };
+ };
+
+ fragment@4 {
+ target = <&spidev0>;
+ __overlay__ {
+ spi-cs-high;
+ };
+ };
+
+ __overrides__ {
+ cs0_pin = <&frag0>,"brcm,pins:0",
+ <&frag1>,"cs-gpios:4";
+ no_miso = <0>,"=3";
+ };
+};

View File

@ -0,0 +1,64 @@
From 57b528e557890f25e010b6bc7356b5a716c79db2 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Tue, 12 Nov 2024 17:58:52 +0000
Subject: [PATCH] drm/vc4: hvs: Defer updating the enable_bg_fill until vblank
The register to enable/disable background fill was being set
from atomic flush, however that will be applied immediately and
can be a while before the vblank. If it was required for the
current frame but not for the next one, that can result in
corruption for part of the current frame.
Store the state in vc4_hvs, and update it on vblank.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/vc4/vc4_drv.h | 2 ++
drivers/gpu/drm/vc4/vc4_hvs.c | 18 ++++++++++--------
2 files changed, 12 insertions(+), 8 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -339,6 +339,8 @@ struct vc4_hvs {
unsigned int enabled: 1;
} eof_irq[HVS_NUM_CHANNELS];
+ bool bg_fill[HVS_NUM_CHANNELS];
+
unsigned long max_core_rate;
/* Memory manager for CRTCs to allocate space in the display
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -1470,14 +1470,7 @@ void vc4_hvs_atomic_flush(struct drm_crt
/* This sets a black background color fill, as is the case
* with other DRM drivers.
*/
- if (enable_bg_fill)
- HVS_WRITE(SCALER6_DISPX_CTRL1(channel),
- HVS_READ(SCALER6_DISPX_CTRL1(channel)) |
- SCALER6(DISPX_CTRL1_BGENB));
- else
- HVS_WRITE(SCALER6_DISPX_CTRL1(channel),
- HVS_READ(SCALER6_DISPX_CTRL1(channel)) &
- ~SCALER6(DISPX_CTRL1_BGENB));
+ hvs->bg_fill[channel] = enable_bg_fill;
} else {
/* we can actually run with a lower core clock when background
* fill is enabled on VC4_GEN_5 so leave it enabled always.
@@ -1662,6 +1655,15 @@ static irqreturn_t vc6_hvs_eof_irq_handl
if (hvs->eof_irq[i].desc != irq)
continue;
+ if (hvs->bg_fill[i])
+ HVS_WRITE(SCALER6_DISPX_CTRL1(i),
+ HVS_READ(SCALER6_DISPX_CTRL1(i)) |
+ SCALER6(DISPX_CTRL1_BGENB));
+ else
+ HVS_WRITE(SCALER6_DISPX_CTRL1(i),
+ HVS_READ(SCALER6_DISPX_CTRL1(i)) &
+ ~SCALER6(DISPX_CTRL1_BGENB));
+
vc4_hvs_schedule_dlist_sweep(hvs, i);
return IRQ_HANDLED;
}

View File

@ -27,7 +27,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/misc/rp1-pio.c
+++ b/drivers/misc/rp1-pio.c
@@ -479,6 +479,28 @@ int rp1_pio_sm_set_dmactrl(struct rp1_pi
@@ -476,6 +476,28 @@ int rp1_pio_sm_set_dmactrl(struct rp1_pi
}
EXPORT_SYMBOL_GPL(rp1_pio_sm_set_dmactrl);
@ -56,7 +56,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
int rp1_pio_gpio_init(struct rp1_pio_client *client, void *param)
{
struct rp1_gpio_init_args *args = param;
@@ -851,6 +873,8 @@ struct handler_info {
@@ -848,6 +870,8 @@ struct handler_info {
HANDLER(SM_PUT, sm_put),
HANDLER(SM_GET, sm_get),
HANDLER(SM_SET_DMACTRL, sm_set_dmactrl),

View File

@ -0,0 +1,31 @@
From fa6ad4bcad4e8db18493a4af640b4b5c95434e70 Mon Sep 17 00:00:00 2001
From: Just a nerd <157698061+foonerd@users.noreply.github.com>
Date: Wed, 20 Nov 2024 14:08:48 +0000
Subject: [PATCH] overlays: Enable Raspberry Touch 2 rotation with overlay
See: https://github.com/raspberrypi/linux/pull/6480
Signed-off-by: foonerd <foonerd@github.com>
---
arch/arm/boot/dts/overlays/README | 1 +
arch/arm/boot/dts/overlays/vc4-kms-dsi-ili9881-7inch-overlay.dts | 1 +
2 files changed, 2 insertions(+)
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -5249,6 +5249,7 @@ Params: sizex Touchscr
invy Touchscreen inverted y axis
swapxy Touchscreen swapped x y axis
disable_touch Disables the touch screen overlay driver
+ rotation Display rotation {0,90,180,270} (default 0)
dsi0 Use DSI0 and i2c_csi_dsi0 (rather than
the default DSI1 and i2c_csi_dsi).
--- a/arch/arm/boot/dts/overlays/vc4-kms-dsi-ili9881-7inch-overlay.dts
+++ b/arch/arm/boot/dts/overlays/vc4-kms-dsi-ili9881-7inch-overlay.dts
@@ -118,5 +118,6 @@
invy = <0>, "+11";
swapxy = <&gt911>,"touchscreen-swapped-x-y?";
disable_touch = <&gt911>, "status=disabled";
+ rotation = <&dsi_panel>, "rotation:0";
};
};

View File

@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/include/linux/pio_rp1.h
+++ b/include/linux/pio_rp1.h
@@ -245,7 +245,7 @@ static inline bool pio_can_add_program_a
@@ -247,7 +247,7 @@ static inline bool pio_can_add_program_a
return !rp1_pio_can_add_program(client, &args);
}
@ -22,7 +22,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
{
struct rp1_pio_add_program_args args;
int offset;
@@ -365,7 +365,7 @@ static inline int pio_sm_set_config(stru
@@ -367,7 +367,7 @@ static inline int pio_sm_set_config(stru
return rp1_pio_sm_set_config(client, &args);
}
@ -31,7 +31,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
{
struct rp1_pio_sm_exec_args args = { .sm = sm, .instr = instr, .blocking = false };
@@ -375,7 +375,7 @@ int pio_sm_exec(struct rp1_pio_client *c
@@ -377,7 +377,7 @@ int pio_sm_exec(struct rp1_pio_client *c
return rp1_pio_sm_exec(client, &args);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,100 @@
From 75ab92b077602734458f0a77e19a3599be29b93b Mon Sep 17 00:00:00 2001
From: Giedrius <giedrius@blokas.io>
Date: Thu, 21 Nov 2024 08:05:49 +0000
Subject: [PATCH] Adding pimidi-overlay.dts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io>
---
arch/arm/boot/dts/overlays/Makefile | 1 +
arch/arm/boot/dts/overlays/README | 8 +++
arch/arm/boot/dts/overlays/pimidi-overlay.dts | 54 +++++++++++++++++++
3 files changed, 63 insertions(+)
create mode 100644 arch/arm/boot/dts/overlays/pimidi-overlay.dts
--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -203,6 +203,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
pifi-dac-zero.dtbo \
pifi-mini-210.dtbo \
piglow.dtbo \
+ pimidi.dtbo \
pineboards-hat-ai.dtbo \
pineboards-hatdrive-poe-plus.dtbo \
piscreen.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -3701,6 +3701,14 @@ Load: dtoverlay=piglow
Params: <None>
+Name: pimidi
+Info: Configures the Blokas Labs Pimidi card
+Load: dtoverlay=pimidi,<param>=<val>
+Params: sel The position used for the sel rotary switch.
+ Each unit in the stack must be set on a unique
+ position. If param is omitted, sel=0 is assumed.
+
+
Name: pineboards-hat-ai
Info: Pineboards Hat Ai! overlay for the Google Coral Edge TPU
Load: dtoverlay=pineboards-hat-ai
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/pimidi-overlay.dts
@@ -0,0 +1,54 @@
+/*
+ * Pimidi Linux kernel module.
+ * Copyright (C) 2017-2024 Vilniaus Blokas UAB, https://blokas.io/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "brcm,bcm2835";
+
+ fragment@0 {
+ target = <&i2c_arm>;
+ __overlay__ {
+ status = "okay";
+ clock-frequency=<1000000>;
+
+ pimidi_ctrl: pimidi_ctrl@20 {
+ compatible = "blokaslabs,pimidi";
+
+ reg = <0x20>;
+ status = "okay";
+
+ interrupt-parent = <&gpio>;
+ interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "data_ready";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ data-ready-gpios = <&gpio 23 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ reset-gpios = <&gpio 22 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ };
+ };
+ };
+
+ __overrides__ {
+ sel = <&pimidi_ctrl>,"reg:0{0=0x20,1=0x21,2=0x22,3=0x23}",
+ <&pimidi_ctrl>,"data-ready-gpios:4{0=23,1=5,2=6,3=27}",
+ <&pimidi_ctrl>,"interrupts:0{0=23,1=5,2=6,3=27}";
+ };
+};

View File

@ -1,7 +1,7 @@
From fc5ed9d9bf0411523220bab60304da6d23257a64 Mon Sep 17 00:00:00 2001
From a1e4b72997dc3ef423b6f510bfead470475750d4 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 1 Nov 2018 17:31:37 +0000
Subject: [PATCH 0297/1085] staging: vchiq_arm: Add 36-bit address support
Subject: [PATCH] staging: vchiq_arm: Add 36-bit address support
Conditional on a new compatible string, change the pagelist encoding
such that the top 24 bits are the pfn, leaving 8 bits for run length

View File

@ -1,7 +1,7 @@
From d4712f611e6d60dd9cf09df581f5df6fad6a2207 Mon Sep 17 00:00:00 2001
From 1129091b2d95273d930acf2926a569b90512a248 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Tue, 21 Jul 2020 17:34:09 +0100
Subject: [PATCH 0298/1085] staging: vchiq_arm: children inherit DMA config
Subject: [PATCH] staging: vchiq_arm: children inherit DMA config
Although it is no longer necessary for vchiq's children to have a
different DMA configuration to the parent, they do still need to

View File

@ -1,7 +1,7 @@
From 9f328c347fc9a5495b8383aa2bae1d3bc242a2ab Mon Sep 17 00:00:00 2001
From 2d26a598ceceaea8a6837146c741eb742bbd4baa Mon Sep 17 00:00:00 2001
From: detule <ogjoneski@gmail.com>
Date: Tue, 2 Oct 2018 04:10:08 -0400
Subject: [PATCH 0299/1085] staging: vchiq_arm: Usa a DMA pool for small bulks
Subject: [PATCH] staging: vchiq_arm: Usa a DMA pool for small bulks
During a bulk transfer we request a DMA allocation to hold the
scatter-gather list. Most of the time, this allocation is small

View File

@ -1,7 +1,7 @@
From 79f24f7454a416fed9106c75ea9b3be480465dda Mon Sep 17 00:00:00 2001
From 5b29221e96d1ba60a78d5c804a20fa35a6d0517a Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Fri, 29 Apr 2022 09:19:10 +0100
Subject: [PATCH 0365/1085] staging: vchiq_arm: Add log_level module params
Subject: [PATCH] staging: vchiq_arm: Add log_level module params
Add module parameters to control the logging levels for the various
vchiq logging categories.

View File

@ -0,0 +1,25 @@
From 8691544f688bd3ae9b6db0845a75ce230fc9e90f Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Thu, 21 Nov 2024 15:54:58 +0000
Subject: [PATCH] media: i2c: imx477: Fix link frequency menu
"media: i2c: imx477: Add options for slightly modifying the link freq"
created a link frequency menu with 2 items in instead of one.
Correct this.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx477.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/i2c/imx477.c
+++ b/drivers/media/i2c/imx477.c
@@ -2051,7 +2051,7 @@ static int imx477_init_controls(struct i
/* LINK_FREQ is also read only */
imx477->link_freq =
v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx477_ctrl_ops,
- V4L2_CID_LINK_FREQ, 1, 0,
+ V4L2_CID_LINK_FREQ, 0, 0,
&link_freqs[imx477->link_freq_idx]);
if (imx477->link_freq)
imx477->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;

View File

@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/include/linux/pio_rp1.h
+++ b/include/linux/pio_rp1.h
@@ -318,7 +318,7 @@ static inline int pio_sm_unclaim(struct
@@ -320,7 +320,7 @@ static inline int pio_sm_unclaim(struct
if (bad_params_if(client, sm >= NUM_PIO_STATE_MACHINES))
return -EINVAL;

View File

@ -0,0 +1,147 @@
From 008c93b47b9b965368eb5bbfbef60b816931e0ab Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Wed, 20 Nov 2024 13:58:08 +0000
Subject: [PATCH] drm: vc4: dsi: Handle the different command FIFO widths
DSI0 and DSI1 have different widths for the command FIFO (24bit
vs 32bit), but the driver was assuming the 32bit width of DSI1
in all cases.
DSI0 also wants the data packed as 24bit big endian, so the
formatting code needs updating.
Handle the difference via the variant structure.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/vc4/vc4_dsi.c | 64 ++++++++++++++++++++++++-----------
1 file changed, 44 insertions(+), 20 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -44,7 +44,6 @@
#define DSI_CMD_FIFO_DEPTH 16
#define DSI_PIX_FIFO_DEPTH 256
-#define DSI_PIX_FIFO_WIDTH 4
#define DSI0_CTRL 0x00
@@ -170,11 +169,15 @@
#define DSI1_DISP1_CTRL 0x2c
/* Format of the data written to TXPKT_PIX_FIFO. */
# define DSI_DISP1_PFORMAT_MASK VC4_MASK(2, 1)
-# define DSI_DISP1_PFORMAT_SHIFT 1
-# define DSI_DISP1_PFORMAT_16BIT 0
-# define DSI_DISP1_PFORMAT_24BIT 1
-# define DSI_DISP1_PFORMAT_32BIT_LE 2
-# define DSI_DISP1_PFORMAT_32BIT_BE 3
+# define DSI1_DISP1_PFORMAT_SHIFT 1
+# define DSI0_DISP1_PFORMAT_16BIT 0
+# define DSI0_DISP1_PFORMAT_16BIT_ADJ 1
+# define DSI0_DISP1_PFORMAT_24BIT 2
+# define DSI0_DISP1_PFORMAT_32BIT_LE 3 /* NB Invalid, but required for macros to work */
+# define DSI1_DISP1_PFORMAT_16BIT 0
+# define DSI1_DISP1_PFORMAT_24BIT 1
+# define DSI1_DISP1_PFORMAT_32BIT_LE 2
+# define DSI1_DISP1_PFORMAT_32BIT_BE 3
/* DISP1 is always command mode. */
# define DSI_DISP1_ENABLE BIT(0)
@@ -553,6 +556,7 @@ struct vc4_dsi_variant {
unsigned int port;
bool broken_axi_workaround;
+ unsigned int cmd_fifo_width;
const char *debugfs_name;
const struct debugfs_reg32 *regs;
@@ -1151,10 +1155,16 @@ static void vc4_dsi_bridge_pre_enable(st
/* Set up DISP1 for transferring long command payloads through
* the pixfifo.
*/
- DSI_PORT_WRITE(DISP1_CTRL,
- VC4_SET_FIELD(DSI_DISP1_PFORMAT_32BIT_LE,
- DSI_DISP1_PFORMAT) |
- DSI_DISP1_ENABLE);
+ if (dsi->variant->cmd_fifo_width == 4)
+ DSI_PORT_WRITE(DISP1_CTRL,
+ VC4_SET_FIELD(DSI_PORT_BIT(DISP1_PFORMAT_32BIT_LE),
+ DSI_DISP1_PFORMAT) |
+ DSI_DISP1_ENABLE);
+ else
+ DSI_PORT_WRITE(DISP1_CTRL,
+ VC4_SET_FIELD(DSI_PORT_BIT(DISP1_PFORMAT_24BIT),
+ DSI_DISP1_PFORMAT) |
+ DSI_DISP1_ENABLE);
/* Bring AFE out of reset. */
DSI_PORT_WRITE(PHY_AFEC0,
@@ -1235,9 +1245,9 @@ static ssize_t vc4_dsi_transfer(struct v
pix_fifo_len = 0;
} else {
cmd_fifo_len = (packet.payload_length %
- DSI_PIX_FIFO_WIDTH);
+ dsi->variant->cmd_fifo_width);
pix_fifo_len = ((packet.payload_length - cmd_fifo_len) /
- DSI_PIX_FIFO_WIDTH);
+ dsi->variant->cmd_fifo_width);
}
WARN_ON_ONCE(pix_fifo_len >= DSI_PIX_FIFO_DEPTH);
@@ -1255,14 +1265,25 @@ static ssize_t vc4_dsi_transfer(struct v
for (i = 0; i < cmd_fifo_len; i++)
DSI_PORT_WRITE(TXPKT_CMD_FIFO, packet.payload[i]);
- for (i = 0; i < pix_fifo_len; i++) {
- const u8 *pix = packet.payload + cmd_fifo_len + i * 4;
+ if (dsi->variant->cmd_fifo_width == 4) {
+ for (i = 0; i < pix_fifo_len; i++) {
+ const u8 *pix = packet.payload + cmd_fifo_len + i * 4;
+
+ DSI_PORT_WRITE(TXPKT_PIX_FIFO,
+ pix[0] |
+ pix[1] << 8 |
+ pix[2] << 16 |
+ pix[3] << 24);
+ }
+ } else {
+ for (i = 0; i < pix_fifo_len; i++) {
+ const u8 *pix = packet.payload + cmd_fifo_len + i * 3;
- DSI_PORT_WRITE(TXPKT_PIX_FIFO,
- pix[0] |
- pix[1] << 8 |
- pix[2] << 16 |
- pix[3] << 24);
+ DSI_PORT_WRITE(TXPKT_PIX_FIFO,
+ pix[2] |
+ pix[1] << 8 |
+ pix[0] << 16);
+ }
}
if (msg->flags & MIPI_DSI_MSG_USE_LPM)
@@ -1516,6 +1537,7 @@ static const struct drm_encoder_funcs vc
static const struct vc4_dsi_variant bcm2711_dsi1_variant = {
.port = 1,
+ .cmd_fifo_width = 4,
.debugfs_name = "dsi1_regs",
.regs = dsi1_regs,
.nregs = ARRAY_SIZE(dsi1_regs),
@@ -1523,6 +1545,7 @@ static const struct vc4_dsi_variant bcm2
static const struct vc4_dsi_variant bcm2835_dsi0_variant = {
.port = 0,
+ .cmd_fifo_width = 3,
.debugfs_name = "dsi0_regs",
.regs = dsi0_regs,
.nregs = ARRAY_SIZE(dsi0_regs),
@@ -1530,6 +1553,7 @@ static const struct vc4_dsi_variant bcm2
static const struct vc4_dsi_variant bcm2835_dsi1_variant = {
.port = 1,
+ .cmd_fifo_width = 4,
.broken_axi_workaround = true,
.debugfs_name = "dsi1_regs",
.regs = dsi1_regs,

View File

@ -0,0 +1,30 @@
From eafaa6015fc0ed676f6115905e7c4145d23f5b7d Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Tue, 26 Nov 2024 15:53:24 +0000
Subject: [PATCH] dts: bcm2712-rpi: For CM5IO, i2c_csi_dsi needs to be
CAM/DISP1
Noted setting up a display on CM5IO. Add
"dtoverlay=vc4-kms-dsi-ili7881-7inch" fails as it tries to
find the regulator/backlight/touch on i2c_csi_dsi, which pointed
at i2c_csi_dsi0 by default.
Adding the dsi0 override updated to point at dsi0, and pointed
the i2c at i2c_csi_dsi0, which all works.
The default with i2c_csi_dsi needs to be consistent in using
dsi1/csi1 and the corresponding i2c interface (i2c_csi_dsi1).
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5io.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5io.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5io.dtsi
@@ -11,4 +11,4 @@ i2c_csi_dsi0: &i2c6 { // Note: This is f
symlink = "i2c-6";
};
-i2c_csi_dsi: &i2c_csi_dsi0 { }; // The connector that needs no jumper to enable
+i2c_csi_dsi: &i2c_csi_dsi1 { }; // The connector that needs no jumper to enable

View File

@ -0,0 +1,25 @@
From d128c123754e9dd03ad72c16851a1652331d6da1 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 27 Nov 2024 10:24:47 +0000
Subject: [PATCH] dts: bcm2712-rpi-cm5: Remove inaccessible USB_OC_N
Although VBUS_EN on GPIO42 appears on the CM5's 100-way headers,
USB_OC_N on GPIO43 does not. Remove the signal name to avoid further
confusion and disappointment.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
@@ -718,7 +718,7 @@ spi10_cs_pins: &spi10_cs_gpio1 {};
"-", // GPIO40
"-", // GPIO41
"USB_VBUS_EN", // GPIO42
- "USB_OC_N", // GPIO43
+ "-", // GPIO43
"RP1_STAT_LED", // GPIO44
"FAN_PWM", // GPIO45
"-", // GPIO46

View File

@ -0,0 +1,33 @@
From 77389e715039b1feac9c6261727600892cc12fdb Mon Sep 17 00:00:00 2001
From: Michael Heimpold <michael.heimpold@chargebyte.com>
Date: Fri, 29 Nov 2024 14:10:04 +0100
Subject: [PATCH] overlays: qca7000: replace URL with textual hint
The deep link into the website is not that stable, so let's
replace it with a textual description where to find the
product information.
Signed-off-by: Michael Heimpold <michael.heimpold@chargebyte.com>
---
arch/arm/boot/dts/overlays/qca7000-overlay.dts | 2 +-
arch/arm/boot/dts/overlays/qca7000-uart0-overlay.dts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arm/boot/dts/overlays/qca7000-overlay.dts
+++ b/arch/arm/boot/dts/overlays/qca7000-overlay.dts
@@ -1,5 +1,5 @@
// Overlay for the Qualcomm Atheros QCA7000 on PLC Stamp micro EVK
-// Visit: https://chargebyte.com/products/evaluation-tools/plc-stamp-micro-2-evaluation-board for details
+// Visit: https://chargebyte.com -> Controllers & Modules -> Evaluation Tools -> PLC Stamp Micro 2 Evaluation Board for details
/dts-v1/;
/plugin/;
--- a/arch/arm/boot/dts/overlays/qca7000-uart0-overlay.dts
+++ b/arch/arm/boot/dts/overlays/qca7000-uart0-overlay.dts
@@ -1,5 +1,5 @@
// Overlay for the Qualcomm Atheros QCA7000 on PLC Stamp micro EVK
-// Visit: https://in-tech-smartcharging.com/products/evaluation-tools/plc-stamp-micro-2-evaluation-board for details
+// Visit: https://chargebyte.com -> Controllers & Modules -> Evaluation Tools -> PLC Stamp Micro 2 Evaluation Board for details
/dts-v1/;
/plugin/;

View File

@ -0,0 +1,24 @@
From 178f1c2747c3920723242f26ba290785d45bffae Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Mon, 11 Nov 2024 16:38:01 +0000
Subject: [PATCH] dt-bindings: net: cdns,macb: Add compatible for Raspberry Pi
RP1
The Raspberry Pi RP1 chip has the Cadence GEM ethernet
controller, so add a compatible string for it.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
Documentation/devicetree/bindings/net/cdns,macb.yaml | 1 +
1 file changed, 1 insertion(+)
--- a/Documentation/devicetree/bindings/net/cdns,macb.yaml
+++ b/Documentation/devicetree/bindings/net/cdns,macb.yaml
@@ -54,6 +54,7 @@ properties:
- cdns,np4-macb # NP4 SoC devices
- microchip,sama7g5-emac # Microchip SAMA7G5 ethernet interface
- microchip,sama7g5-gem # Microchip SAMA7G5 gigabit ethernet interface
+ - raspberrypi,rp1-gem # Raspberry Pi RP1 gigabit ethernet interface
- sifive,fu540-c000-gem # SiFive FU540-C000 SoC
- cdns,emac # Generic
- cdns,gem # Generic

View File

@ -1,8 +1,8 @@
From f9f0024bd9bf04a58b64bae356be4c04022d23bc Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Mon, 11 Nov 2024 16:40:07 +0000
Subject: [PATCH 1423/1482] net: macb: Add support for Raspberry Pi RP1
ethernet controller
Subject: [PATCH] net: macb: Add support for Raspberry Pi RP1 ethernet
controller
The RP1 chip has the Cadence GEM block, but wants the tx_clock
to always run at 125MHz, in the same way as sama7g5.

View File

@ -1,8 +1,7 @@
From 33c225f622d596034a9261316666089a92aa6834 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Mon, 25 Nov 2024 12:30:06 +0000
Subject: [PATCH 1424/1482] rp1: clk: Only set PLL_SEC_RST in
rp1_pll_divider_off
Subject: [PATCH] rp1: clk: Only set PLL_SEC_RST in rp1_pll_divider_off
Rather than clearing all the bits in rp1_pll_divider_off
and setting PLL_SEC_RST, retain the status of all the other

View File

@ -1,8 +1,7 @@
From eb836a6a299322a8e2b9627cccd23c7a76d068ba Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Fri, 8 Nov 2024 17:36:13 +0000
Subject: [PATCH 1425/1482] rp1: clk: Rationalise the use of the
CLK_IS_CRITICAL flag
Subject: [PATCH] rp1: clk: Rationalise the use of the CLK_IS_CRITICAL flag
The clock setup had been copied from clk-bcm2835 which had to cope
with the firmware having configured clocks, so there were flags

View File

@ -1,7 +1,7 @@
From 0b4af929b7125abd3a262577b380c7c81ee9b1c5 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Mon, 11 Nov 2024 15:18:14 +0000
Subject: [PATCH 1426/1482] dt: arm64: Fixup RP1 ethernet DT configuration
Subject: [PATCH] dt: arm64: Fixup RP1 ethernet DT configuration
Configure RP1's ethernet block to do the correct thing.
clk_eth is intended to be fixed at 125MHz, so use a new compatible,
@ -14,7 +14,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
@@ -24,6 +24,7 @@
@@ -32,6 +32,7 @@
// RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
<&rp1_clocks RP1_PLL_SYS>,
<&rp1_clocks RP1_PLL_SYS_SEC>,
@ -22,7 +22,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
<&rp1_clocks RP1_PLL_AUDIO>,
<&rp1_clocks RP1_PLL_AUDIO_SEC>,
<&rp1_clocks RP1_CLK_SYS>,
@@ -38,6 +39,7 @@
@@ -46,6 +47,7 @@
<1536000000>, // RP1_PLL_AUDIO_CORE
<200000000>, // RP1_PLL_SYS
<125000000>, // RP1_PLL_SYS_SEC
@ -30,7 +30,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
<61440000>, // RP1_PLL_AUDIO
<192000000>, // RP1_PLL_AUDIO_SEC
<200000000>, // RP1_CLK_SYS
@@ -968,12 +970,14 @@
@@ -976,12 +978,14 @@
rp1_eth: ethernet@100000 {
reg = <0xc0 0x40100000 0x0 0x4000>;

View File

@ -1,7 +1,7 @@
From d4e41ed9954fa86c4774f98d393aa401c81a68e7 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Wed, 13 Nov 2024 13:10:27 +0000
Subject: [PATCH 1427/1482] clk: rp1: Add RP1_CLK_DMA.
Subject: [PATCH] clk: rp1: Add RP1_CLK_DMA.
The DMA block has a clock, but wasn't defined in the driver. This
resulted in the parent being disabled as unused, and then DMA

View File

@ -1,7 +1,7 @@
From 9049e4df2c54b5e620f855f66db3a18c9f2e181f Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Fri, 8 Nov 2024 17:37:08 +0000
Subject: [PATCH 1428/1482] rp1: clk: Remove CLK_IGNORE_UNUSED flags
Subject: [PATCH] rp1: clk: Remove CLK_IGNORE_UNUSED flags
There should be no issue in disabling the RP1 clocks as long as
the kernel knows about all consumers.

View File

@ -1,7 +1,7 @@
From 542d0f7f2e9f90fc0f02f8cb141f7c3fbf46081b Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Mon, 11 Nov 2024 17:11:18 +0000
Subject: [PATCH 1429/1482] dt: rp1: Use clk_sys for ethernet hclk and pclk
Subject: [PATCH] dt: rp1: Use clk_sys for ethernet hclk and pclk
hclk and pclk of the MAC are connected to clk_sys, so define
them as being connected accordingly, rather than having fake
@ -14,7 +14,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
@@ -974,7 +974,8 @@
@@ -982,7 +982,8 @@
#address-cells = <1>;
#size-cells = <0>;
interrupts = <RP1_INT_ETH IRQ_TYPE_LEVEL_HIGH>;
@ -24,7 +24,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
&rp1_clocks RP1_CLK_ETH_TSU
&rp1_clocks RP1_CLK_ETH>;
clock-names = "pclk", "hclk", "tsu_clk", "tx_clk";
@@ -1195,18 +1196,6 @@
@@ -1230,18 +1231,6 @@
clock-output-names = "xosc";
clock-frequency = <50000000>;
};

View File

@ -1,7 +1,7 @@
From efecbda4014b490e042c7fd090942b32316f9345 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Wed, 13 Nov 2024 13:11:33 +0000
Subject: [PATCH 1430/1482] dt: rp1: Link RP1 DMA to the associated clock
Subject: [PATCH] dt: rp1: Link RP1 DMA to the associated clock
This makes the kernel representation of the clock structure
match reality.
@ -13,7 +13,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
@@ -1061,7 +1061,7 @@
@@ -1081,7 +1081,7 @@
reg = <0xc0 0x40188000 0x0 0x1000>;
compatible = "snps,axi-dma-1.01a";
interrupts = <RP1_INT_DMA IRQ_TYPE_LEVEL_HIGH>;

View File

@ -0,0 +1,23 @@
From eb035f3ad7da1324d310ef83b42398f47d5bafe7 Mon Sep 17 00:00:00 2001
From: Tim Gover <tim.gover@raspberrypi.com>
Date: Fri, 1 Nov 2024 19:42:17 +0000
Subject: [PATCH] raspberrypi-firmware: Add the RPI firmware UART APIs
Add VideoCore mailbox definitions for the new RPi firmware UART.
Signed-off-by: Tim Gover <tim.gover@raspberrypi.com>
---
include/soc/bcm2835/raspberrypi-firmware.h | 2 ++
1 file changed, 2 insertions(+)
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -98,6 +98,8 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_GET_REBOOT_FLAGS = 0x00030064,
RPI_FIRMWARE_SET_REBOOT_FLAGS = 0x00038064,
RPI_FIRMWARE_NOTIFY_DISPLAY_DONE = 0x00030066,
+ RPI_FIRMWARE_GET_SW_UART = 0x0003008a,
+ RPI_FIRMWARE_SET_SW_UART = 0x0003808a,
/* Dispmanx TAGS */
RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,

View File

@ -0,0 +1,22 @@
From b8a0e563fd181205565a0edaaebc82b1abf0c5be Mon Sep 17 00:00:00 2001
From: Tim Gover <tim.gover@raspberrypi.com>
Date: Fri, 1 Nov 2024 19:43:21 +0000
Subject: [PATCH] serial: core: Add the Raspberry Pi firmware UART id
Assign a new serial core number for the RPi firmware UART.
Signed-off-by: Tim Gover <tim.gover@raspberrypi.com>
---
include/uapi/linux/serial_core.h | 3 +++
1 file changed, 3 insertions(+)
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -245,4 +245,7 @@
/* Sunplus UART */
#define PORT_SUNPLUS 123
+/* RPi firmware UART */
+#define PORT_RPI_FW 124
+
#endif /* _UAPILINUX_SERIAL_CORE_H */

View File

@ -0,0 +1,630 @@
From 2548d954d78bca44c5cf430f8ea6de7c771312d7 Mon Sep 17 00:00:00 2001
From: Tim Gover <tim.gover@raspberrypi.com>
Date: Wed, 28 Aug 2024 09:46:50 +0100
Subject: [PATCH] serial: tty: Add a driver for the RPi firmware UART
On Raspberry Pi 4 and earlier models the firmware provides
a low speed (up to 115200 baud) bit-bashed UART on arbitrary
GPIOs using the second VPU core.
The firmware driver is designed to support 19200 baud. Higher
rates up to 115200 seem to work but there may be more jitter.
This can be useful for debug or managing additional low
speed peripherals if the hardware PL011 and 8250 hardware
UARTs are already used for console / bluetooth.
The firmware driver requires a fixed core clock frequency
and also requires the VPU PWM audio driver to be disabled
(dtparam=audio=off)
Runtime configuration is handled via the vc-mailbox APIs
with the FIFO buffers being allocated in uncached VPU
addressable memory. The FIFO pointers are stored in spare
VideoCore multi-core sync registers in order to reduce the number
of uncached SDRAM accesses thereby reducing jitter.
Signed-off-by: Tim Gover <tim.gover@raspberrypi.com>
---
drivers/tty/serial/Kconfig | 11 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/rpi-fw-uart.c | 563 +++++++++++++++++++++++++++++++
3 files changed, 575 insertions(+)
create mode 100644 drivers/tty/serial/rpi-fw-uart.c
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1578,6 +1578,17 @@ config SERIAL_NUVOTON_MA35D1_CONSOLE
but you can alter that using a kernel command line option such as
"console=ttyNVTx".
+config SERIAL_RPI_FW
+ tristate "Raspberry Pi Firmware software UART support"
+ depends on ARM_AMBA || COMPILE_TEST
+ select SERIAL_CORE
+ help
+ This selects the Raspberry Pi firmware UART. This is a bit-bashed
+ implementation running on the Raspbery Pi VPU core.
+ This is not supported on Raspberry Pi 5 or newer platforms.
+
+ If unsure, say N.
+
endmenu
config SERIAL_MCTRL_GPIO
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += mi
obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o
obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o
obj-$(CONFIG_SERIAL_SUNPLUS) += sunplus-uart.o
+obj-$(CONFIG_SERIAL_RPI_FW) += rpi-fw-uart.o
# GPIOLIB helpers for modem control lines
obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
--- /dev/null
+++ b/drivers/tty/serial/rpi-fw-uart.c
@@ -0,0 +1,563 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024, Raspberry Pi Ltd. All rights reserved.
+ */
+
+#include <linux/console.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/gpio/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+#include <linux/dma-mapping.h>
+
+#define RPI_FW_UART_RX_FIFO_RD 0xb0
+#define RPI_FW_UART_RX_FIFO_WR 0xb4
+#define RPI_FW_UART_TX_FIFO_RD 0xb8
+#define RPI_FW_UART_TX_FIFO_WR 0xbc
+
+#define RPI_FW_UART_FIFO_SIZE 32
+#define RPI_FW_UART_FIFO_SIZE_MASK (RPI_FW_UART_FIFO_SIZE - 1)
+
+#define RPI_FW_UART_MIN_VERSION 3
+
+struct rpi_fw_uart_params {
+ u32 start;
+ u32 baud;
+ u32 data_bits;
+ u32 stop_bits;
+ u32 gpio_rx;
+ u32 gpio_tx;
+ u32 flags;
+ u32 fifosize;
+ u32 rx_buffer;
+ u32 tx_buffer;
+ u32 version;
+ u32 fifo_reg_base;
+};
+
+struct rpi_fw_uart {
+ struct uart_driver driver;
+ struct uart_port port;
+ struct rpi_firmware *firmware;
+ struct gpio_desc *rx_gpiod;
+ struct gpio_desc *tx_gpiod;
+ unsigned int rx_gpio;
+ unsigned int tx_gpio;
+ unsigned int baud;
+ unsigned int data_bits;
+ unsigned int stop_bits;
+ unsigned char __iomem *base;
+ size_t dma_buffer_size;
+
+ struct hrtimer trigger_start_rx;
+ ktime_t rx_poll_delay;
+ void *rx_buffer;
+ dma_addr_t rx_buffer_dma_addr;
+ int rx_stop;
+
+ void *tx_buffer;
+ dma_addr_t tx_buffer_dma_addr;
+};
+
+static unsigned int rpi_fw_uart_tx_is_full(struct uart_port *port)
+{
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+ u32 rd, wr;
+
+ rd = readl(rfu->base + RPI_FW_UART_TX_FIFO_RD);
+ wr = readl(rfu->base + RPI_FW_UART_TX_FIFO_WR);
+ return ((wr + 1) & RPI_FW_UART_FIFO_SIZE_MASK) == rd;
+}
+
+static unsigned int rpi_fw_uart_tx_is_empty(struct uart_port *port)
+{
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+ u32 rd, wr;
+
+ if (!rfu->tx_buffer)
+ return 1;
+
+ rd = readl(rfu->base + RPI_FW_UART_TX_FIFO_RD);
+ wr = readl(rfu->base + RPI_FW_UART_TX_FIFO_WR);
+
+ return rd == wr;
+}
+
+unsigned int rpi_fw_uart_rx_is_empty(struct uart_port *port)
+{
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+ u32 rd, wr;
+
+ if (!rfu->rx_buffer)
+ return 1;
+
+ rd = readl(rfu->base + RPI_FW_UART_RX_FIFO_RD);
+ wr = readl(rfu->base + RPI_FW_UART_RX_FIFO_WR);
+
+ return rd == wr;
+}
+
+static unsigned int rpi_fw_uart_tx_empty(struct uart_port *port)
+{
+ return rpi_fw_uart_tx_is_empty(port) ? TIOCSER_TEMT : 0;
+}
+
+static void rpi_fw_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ /*
+ * No hardware flow control, firmware automatically configures
+ * TX to output high and RX to input low.
+ */
+ dev_dbg(port->dev, "%s mctrl %u\n", __func__, mctrl);
+}
+
+static unsigned int rpi_fw_uart_get_mctrl(struct uart_port *port)
+{
+ /* No hardware flow control */
+ return TIOCM_CTS;
+}
+
+static void rpi_fw_uart_stop(struct uart_port *port)
+{
+ struct rpi_fw_uart_params msg = {.start = 0};
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+
+ hrtimer_cancel(&rfu->trigger_start_rx);
+
+ if (rpi_firmware_property(rfu->firmware,
+ RPI_FIRMWARE_SET_SW_UART,
+ &msg, sizeof(msg)))
+ dev_warn(port->dev,
+ "Failed to shutdown rpi-fw uart. Firmware not configured?");
+}
+
+static void rpi_fw_uart_stop_tx(struct uart_port *port)
+{
+ /* No supported by the current firmware APIs. */
+}
+
+static void rpi_fw_uart_stop_rx(struct uart_port *port)
+{
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+
+ rfu->rx_stop = 1;
+}
+
+static unsigned int rpi_fw_write(struct uart_port *port, const char *s,
+ unsigned int count)
+{
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+ u8 *out = rfu->tx_buffer;
+ unsigned int consumed = 0;
+
+ while (consumed < count && !rpi_fw_uart_tx_is_full(port)) {
+ u32 wp = readl(rfu->base + RPI_FW_UART_TX_FIFO_WR)
+ & RPI_FW_UART_FIFO_SIZE_MASK;
+ out[wp] = s[consumed++];
+ wp = (wp + 1) & RPI_FW_UART_FIFO_SIZE_MASK;
+ writel(wp, rfu->base + RPI_FW_UART_TX_FIFO_WR);
+ }
+ return consumed;
+}
+
+/* Called with port.lock taken */
+static void rpi_fw_uart_start_tx(struct uart_port *port)
+{
+ struct circ_buf *xmit;
+
+ xmit = &port->state->xmit;
+ for (;;) {
+ unsigned int consumed;
+ unsigned long count = CIRC_CNT_TO_END(xmit->head, xmit->tail,
+ UART_XMIT_SIZE);
+ if (!count)
+ break;
+
+ consumed = rpi_fw_write(port, &xmit->buf[xmit->tail], count);
+ uart_xmit_advance(port, consumed);
+ }
+ uart_write_wakeup(port);
+}
+
+/* Called with port.lock taken */
+static void rpi_fw_uart_start_rx(struct uart_port *port)
+{
+ struct tty_port *tty_port = &port->state->port;
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+ int count = 0;
+
+ /*
+ * RX is polled, read up to a full buffer of data before trying again
+ * so that this can be interrupted if the firmware is filling the
+ * buffer too fast
+ */
+ while (!rpi_fw_uart_rx_is_empty(port) && count < port->fifosize) {
+ const u8 *in = rfu->rx_buffer;
+ u32 rp = readl(rfu->base + RPI_FW_UART_RX_FIFO_RD)
+ & RPI_FW_UART_FIFO_SIZE_MASK;
+
+ tty_insert_flip_char(tty_port, in[rp], TTY_NORMAL);
+ rp = (rp + 1) & RPI_FW_UART_FIFO_SIZE_MASK;
+ writel(rp, rfu->base + RPI_FW_UART_RX_FIFO_RD);
+ count++;
+ }
+ if (count)
+ tty_flip_buffer_push(tty_port);
+}
+
+static enum hrtimer_restart rpi_fw_uart_trigger_rx(struct hrtimer *t)
+{
+ unsigned long flags;
+ struct rpi_fw_uart *rfu = container_of(t, struct rpi_fw_uart,
+ trigger_start_rx);
+
+ spin_lock_irqsave(&rfu->port.lock, flags);
+ if (rfu->rx_stop) {
+ spin_unlock_irqrestore(&rfu->port.lock, flags);
+ return HRTIMER_NORESTART;
+ }
+
+ rpi_fw_uart_start_rx(&rfu->port);
+ spin_unlock_irqrestore(&rfu->port.lock, flags);
+ hrtimer_forward_now(t, rfu->rx_poll_delay);
+ return HRTIMER_RESTART;
+}
+
+static void rpi_fw_uart_break_ctl(struct uart_port *port, int ctl)
+{
+ dev_dbg(port->dev, "%s ctl %d\n", __func__, ctl);
+}
+
+static int rpi_fw_uart_configure(struct uart_port *port)
+{
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+ struct rpi_fw_uart_params msg;
+ unsigned long flags;
+ int rc;
+
+ rpi_fw_uart_stop(port);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.start = 1;
+ msg.gpio_rx = rfu->rx_gpio;
+ msg.gpio_tx = rfu->tx_gpio;
+ msg.data_bits = rfu->data_bits;
+ msg.stop_bits = rfu->stop_bits;
+ msg.baud = rfu->baud;
+ msg.fifosize = RPI_FW_UART_FIFO_SIZE;
+ msg.rx_buffer = (u32) rfu->rx_buffer_dma_addr;
+ msg.tx_buffer = (u32) rfu->tx_buffer_dma_addr;
+
+ rfu->rx_poll_delay = ms_to_ktime(50);
+
+ /*
+ * Reconfigures the firmware UART with the new settings. On the first
+ * call retrieve the addresses of the FIFO buffers. The buffers are
+ * allocated at startup and are not de-allocated.
+ * NB rpi_firmware_property can block
+ */
+ rc = rpi_firmware_property(rfu->firmware,
+ RPI_FIRMWARE_SET_SW_UART,
+ &msg, sizeof(msg));
+ if (rc)
+ goto fail;
+
+ rc = rpi_firmware_property(rfu->firmware,
+ RPI_FIRMWARE_GET_SW_UART,
+ &msg, sizeof(msg));
+ if (rc)
+ goto fail;
+
+ dev_dbg(port->dev, "version %08x, reg addr %x\n", msg.version,
+ msg.fifo_reg_base);
+
+ dev_info(port->dev, "started %d baud %u data %u stop %u rx %u tx %u flags %u fifosize %u\n",
+ msg.start, msg.baud, msg.data_bits, msg.stop_bits,
+ msg.gpio_rx, msg.gpio_tx, msg.flags, msg.fifosize);
+
+ if (msg.fifosize != port->fifosize) {
+ dev_err(port->dev, "Expected fifo size %u actual %u",
+ port->fifosize, msg.fifosize);
+ rc = -EINVAL;
+ goto fail;
+ }
+
+ if (!msg.start) {
+ dev_err(port->dev, "Firmware service not running\n");
+ rc = -EINVAL;
+ }
+
+ spin_lock_irqsave(&rfu->port.lock, flags);
+ rfu->rx_stop = 0;
+ hrtimer_start(&rfu->trigger_start_rx,
+ rfu->rx_poll_delay, HRTIMER_MODE_REL);
+ spin_unlock_irqrestore(&rfu->port.lock, flags);
+ return 0;
+fail:
+ dev_err(port->dev, "Failed to configure rpi-fw uart. Firmware not configured?");
+ return rc;
+}
+
+static void rpi_fw_uart_free_buffers(struct uart_port *port)
+{
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+
+ if (rfu->rx_buffer)
+ dma_free_coherent(port->dev, rfu->dma_buffer_size,
+ rfu->rx_buffer, GFP_ATOMIC);
+
+ if (rfu->tx_buffer)
+ dma_free_coherent(port->dev, rfu->dma_buffer_size,
+ rfu->tx_buffer, GFP_ATOMIC);
+
+ rfu->rx_buffer = NULL;
+ rfu->tx_buffer = NULL;
+ rfu->rx_buffer_dma_addr = 0;
+ rfu->tx_buffer_dma_addr = 0;
+}
+
+static int rpi_fw_uart_alloc_buffers(struct uart_port *port)
+{
+ struct rpi_fw_uart *rfu = container_of(port, struct rpi_fw_uart, port);
+
+ if (rfu->tx_buffer)
+ return 0;
+
+ rfu->dma_buffer_size = PAGE_ALIGN(RPI_FW_UART_FIFO_SIZE);
+
+ rfu->rx_buffer = dma_alloc_coherent(port->dev, rfu->dma_buffer_size,
+ &rfu->rx_buffer_dma_addr, GFP_ATOMIC);
+
+ if (!rfu->rx_buffer)
+ goto alloc_fail;
+
+ rfu->tx_buffer = dma_alloc_coherent(port->dev, rfu->dma_buffer_size,
+ &rfu->tx_buffer_dma_addr, GFP_ATOMIC);
+
+ if (!rfu->tx_buffer)
+ goto alloc_fail;
+
+ dev_dbg(port->dev, "alloc-buffers %p %x %p %x\n",
+ rfu->rx_buffer, (u32) rfu->rx_buffer_dma_addr,
+ rfu->tx_buffer, (u32) rfu->tx_buffer_dma_addr);
+ return 0;
+
+alloc_fail:
+ dev_err(port->dev, "%s uart buffer allocation failed\n", __func__);
+ rpi_fw_uart_free_buffers(port);
+ return -ENOMEM;
+}
+
+static int rpi_fw_uart_startup(struct uart_port *port)
+{
+ int rc;
+
+ rc = rpi_fw_uart_alloc_buffers(port);
+ if (rc)
+ dev_err(port->dev, "Failed to start\n");
+ return rc;
+}
+
+static void rpi_fw_uart_shutdown(struct uart_port *port)
+{
+ rpi_fw_uart_stop(port);
+ rpi_fw_uart_free_buffers(port);
+}
+
+static void rpi_fw_uart_set_termios(struct uart_port *port,
+ struct ktermios *new,
+ const struct ktermios *old)
+{
+ struct rpi_fw_uart *rfu =
+ container_of(port, struct rpi_fw_uart, port);
+ rfu->baud = uart_get_baud_rate(port, new, old, 50, 115200);
+ rfu->stop_bits = (new->c_cflag & CSTOPB) ? 2 : 1;
+
+ rpi_fw_uart_configure(port);
+}
+
+static const struct uart_ops rpi_fw_uart_ops = {
+ .tx_empty = rpi_fw_uart_tx_empty,
+ .set_mctrl = rpi_fw_uart_set_mctrl,
+ .get_mctrl = rpi_fw_uart_get_mctrl,
+ .stop_rx = rpi_fw_uart_stop_rx,
+ .stop_tx = rpi_fw_uart_stop_tx,
+ .start_tx = rpi_fw_uart_start_tx,
+ .break_ctl = rpi_fw_uart_break_ctl,
+ .startup = rpi_fw_uart_startup,
+ .shutdown = rpi_fw_uart_shutdown,
+ .set_termios = rpi_fw_uart_set_termios,
+};
+
+static int rpi_fw_uart_get_gpio_offset(struct device *dev, const char *name)
+{
+ struct of_phandle_args of_args = { 0 };
+ bool is_bcm28xx;
+
+ /* This really shouldn't fail, given that we have a gpiod */
+ if (of_parse_phandle_with_args(dev->of_node, name, "#gpio-cells", 0, &of_args))
+ return dev_err_probe(dev, -EINVAL, "can't find gpio declaration\n");
+
+ is_bcm28xx = of_device_is_compatible(of_args.np, "brcm,bcm2835-gpio") ||
+ of_device_is_compatible(of_args.np, "brcm,bcm2711-gpio");
+ of_node_put(of_args.np);
+ if (!is_bcm28xx || of_args.args_count != 2)
+ return dev_err_probe(dev, -EINVAL, "not a BCM28xx gpio\n");
+
+ return of_args.args[0];
+}
+
+static int rpi_fw_uart_probe(struct platform_device *pdev)
+{
+ struct device_node *firmware_node;
+ struct device *dev = &pdev->dev;
+ struct rpi_firmware *firmware;
+ struct uart_port *port;
+ struct rpi_fw_uart *rfu;
+ struct rpi_fw_uart_params msg;
+ int version_major;
+ int err;
+
+ dev_dbg(dev, "%s of_node %p\n", __func__, dev->of_node);
+
+ /*
+ * We can be probed either through the an old-fashioned
+ * platform device registration or through a DT node that is a
+ * child of the firmware node. Handle both cases.
+ */
+ if (dev->of_node)
+ firmware_node = of_parse_phandle(dev->of_node, "firmware", 0);
+ else
+ firmware_node = of_find_compatible_node(NULL, NULL,
+ "raspberrypi,bcm2835-firmware");
+ if (!firmware_node) {
+ dev_err(dev, "Missing firmware node\n");
+ return -ENOENT;
+ }
+
+ firmware = devm_rpi_firmware_get(dev, firmware_node);
+ of_node_put(firmware_node);
+ if (!firmware)
+ return -EPROBE_DEFER;
+
+ rfu = devm_kzalloc(dev, sizeof(*rfu), GFP_KERNEL);
+ if (!rfu)
+ return -ENOMEM;
+
+ rfu->firmware = firmware;
+
+ err = rpi_firmware_property(rfu->firmware, RPI_FIRMWARE_GET_SW_UART,
+ &msg, sizeof(msg));
+ if (err) {
+ dev_err(dev, "VC firmware does not support rpi-fw-uart\n");
+ return err;
+ }
+
+ version_major = msg.version >> 16;
+ if (msg.version < RPI_FW_UART_MIN_VERSION) {
+ dev_err(dev, "rpi-fw-uart fw version %d is too old min version %d\n",
+ version_major, RPI_FW_UART_MIN_VERSION);
+ return -EINVAL;
+ }
+
+ rfu->rx_gpiod = devm_gpiod_get(dev, "rx", GPIOD_IN);
+ if (IS_ERR(rfu->rx_gpiod))
+ return PTR_ERR(rfu->rx_gpiod);
+
+ rfu->tx_gpiod = devm_gpiod_get(dev, "tx", GPIOD_OUT_HIGH);
+ if (IS_ERR(rfu->tx_gpiod))
+ return PTR_ERR(rfu->tx_gpiod);
+
+ rfu->rx_gpio = rpi_fw_uart_get_gpio_offset(dev, "rx-gpios");
+ if (rfu->rx_gpio < 0)
+ return rfu->rx_gpio;
+ rfu->tx_gpio = rpi_fw_uart_get_gpio_offset(dev, "tx-gpios");
+ if (rfu->tx_gpio < 0)
+ return rfu->tx_gpio;
+
+ rfu->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rfu->base))
+ return PTR_ERR(rfu->base);
+
+ /* setup the driver */
+ rfu->driver.owner = THIS_MODULE;
+ rfu->driver.driver_name = "ttyRFU";
+ rfu->driver.dev_name = "ttyRFU";
+ rfu->driver.nr = 1;
+ rfu->data_bits = 8;
+
+ /* RX is polled */
+ hrtimer_init(&rfu->trigger_start_rx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ rfu->trigger_start_rx.function = rpi_fw_uart_trigger_rx;
+
+ err = uart_register_driver(&rfu->driver);
+ if (err) {
+ dev_err(dev, "failed to register UART driver: %d\n",
+ err);
+ return err;
+ }
+
+ /* setup the port */
+ port = &rfu->port;
+ spin_lock_init(&port->lock);
+ port->dev = &pdev->dev;
+ port->type = PORT_RPI_FW;
+ port->ops = &rpi_fw_uart_ops;
+ port->fifosize = RPI_FW_UART_FIFO_SIZE;
+ port->iotype = UPIO_MEM;
+ port->flags = UPF_BOOT_AUTOCONF;
+ port->private_data = rfu;
+
+ err = uart_add_one_port(&rfu->driver, port);
+ if (err) {
+ dev_err(dev, "failed to add UART port: %d\n", err);
+ goto unregister_uart;
+ }
+ platform_set_drvdata(pdev, rfu);
+
+ dev_info(dev, "version %d.%d gpios tx %u rx %u\n",
+ msg.version >> 16, msg.version & 0xffff,
+ rfu->tx_gpio, rfu->rx_gpio);
+ return 0;
+
+unregister_uart:
+ uart_unregister_driver(&rfu->driver);
+
+ return err;
+}
+
+static int rpi_fw_uart_remove(struct platform_device *pdev)
+{
+ struct rpi_fw_uart *rfu = platform_get_drvdata(pdev);
+
+ uart_remove_one_port(&rfu->driver, &rfu->port);
+ uart_unregister_driver(&rfu->driver);
+
+ return 0;
+}
+
+static const struct of_device_id rpi_fw_match[] = {
+ { .compatible = "raspberrypi,firmware-uart" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, rpi_fw_match);
+
+static struct platform_driver rpi_fw_driver = {
+ .driver = {
+ .name = "rpi_fw-uart",
+ .of_match_table = rpi_fw_match,
+ },
+ .probe = rpi_fw_uart_probe,
+ .remove = rpi_fw_uart_remove,
+};
+module_platform_driver(rpi_fw_driver);
+
+MODULE_AUTHOR("Tim Gover <tim.gover@rasberrypi.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Raspberry Pi Firmware Software UART driver");

View File

@ -0,0 +1,95 @@
From b6b126861062020fb50859c5af71d8846ce43d7c Mon Sep 17 00:00:00 2001
From: Tim Gover <tim.gover@raspberrypi.com>
Date: Mon, 4 Nov 2024 13:44:10 +0000
Subject: [PATCH] dtoverlay: Add an overlay for the Raspberry Pi firmware UART
Add a device-tree overlay to configure the GPIOs for the
Raspberry Pi firmware UART.
Example config.txt
dtoverlay=rpi-fw-uart,txd0_pin=20,rxd0_pin=21
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
Signed-off-by: Tim Gover <tim.gover@raspberrypi.com>
---
arch/arm/boot/dts/overlays/Makefile | 1 +
arch/arm/boot/dts/overlays/README | 12 ++++++
.../boot/dts/overlays/rpi-fw-uart-overlay.dts | 41 +++++++++++++++++++
3 files changed, 54 insertions(+)
create mode 100644 arch/arm/boot/dts/overlays/rpi-fw-uart-overlay.dts
--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -233,6 +233,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
rpi-dacpro.dtbo \
rpi-digiampplus.dtbo \
rpi-ft5406.dtbo \
+ rpi-fw-uart.dtbo \
rpi-poe.dtbo \
rpi-poe-plus.dtbo \
rpi-sense.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -4141,6 +4141,18 @@ Params: touchscreen-size-x Touchscr
touchscreen-swapped-x-y Swap X and Y cordinates (default 0);
+Name: rpi-fw-uart
+Info: Configures the firmware software UART driver.
+ This driver requires exclusive usage of the second VPU core. The
+ following config.txt entries should be set when this driver is used.
+ dtparam=audio=off
+ isp_use_vpu0=1
+Load: dtoverlay=rpi-fw-uart,<param>[=<val>]
+Params: txd0_pin GPIO pin for TXD0 (any free - default 20)
+
+ rxd0_pin GPIO pin for RXD0 (any free - default 21)
+
+
Name: rpi-poe
Info: Raspberry Pi PoE HAT fan
Load: dtoverlay=rpi-poe,<param>[=<val>]
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/rpi-fw-uart-overlay.dts
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+// Overlay for the Raspberry Pi Firmware UART driver
+/dts-v1/;
+/plugin/;
+
+/{
+ compatible = "brcm,bcm2835";
+
+ fragment@0 {
+ target = <&gpio>;
+ __overlay__ {
+ rpi_fw_uart_pins: rpi_fw_uart_pins@4 {
+ brcm,pins = <20 21>;
+ brcm,function = <1 0>; /* output input */
+ brcm,pull = <0 2>; /* none pull-up */
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&soc>;
+ __overlay__ {
+ rpi_fw_uart: rpi_fw_uart@7e000000 {
+ compatible = "raspberrypi,firmware-uart";
+ reg = <0x7e000000 0x100>; /* VideoCore MS sync regs */
+ firmware = <&firmware>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rpi_fw_uart_pins>;
+ tx-gpios = <&gpio 20 0>;
+ rx-gpios = <&gpio 21 0>;
+ };
+ };
+ };
+
+ __overrides__ {
+ txd0_pin = <&rpi_fw_uart>,"tx-gpios:4",
+ <&rpi_fw_uart_pins>, "brcm,pins:0";
+ rxd0_pin = <&rpi_fw_uart>,"rx-gpios:4",
+ <&rpi_fw_uart_pins>, "brcm,pins:4";
+ };
+};

View File

@ -0,0 +1,142 @@
From 1993b453dc4a62378e90d91e9e0006a6c085f38a Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 18 Sep 2024 10:23:41 +0100
Subject: [PATCH] ARM: dts: Remove duplicate tags
A dts file should have exactly one /dts-v1/ tag, and overlays should
also have one /plugin/ tag. Through careless inclusion of other files,
some Device Trees and overlays end up with duplicated tags - this
commit removes them.
The change is largely cosmetic, unless using an old version of dtc.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts | 1 -
arch/arm/boot/dts/overlays/i2c-sensor-common.dtsi | 3 ---
arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi | 2 --
arch/arm/boot/dts/overlays/pisound-pi5-overlay.dts | 3 ---
arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts | 3 ---
arch/arm/boot/dts/overlays/vc4-fkms-v3d-pi4-overlay.dts | 3 ---
arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 3 ---
arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 3 ---
arch/arm/boot/dts/overlays/w1-gpio-pi5-overlay.dts | 3 ---
arch/arm/boot/dts/overlays/w1-gpio-pullup-pi5-overlay.dts | 3 ---
arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi | 1 -
11 files changed, 28 deletions(-)
--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts
+++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-/dts-v1/;
#include "bcm2711-rpi-4-b.dts"
/ {
--- a/arch/arm/boot/dts/overlays/i2c-sensor-common.dtsi
+++ b/arch/arm/boot/dts/overlays/i2c-sensor-common.dtsi
@@ -1,7 +1,4 @@
// Definitions for I2C based sensors using the Industrial IO or HWMON interface.
-/dts-v1/;
-/plugin/;
-
#include <dt-bindings/gpio/gpio.h>
/ {
--- a/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi
+++ b/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
// Partial definitions for IMX290 or IMX327 camera module on VC I2C bus
// The compatible string should be set in an overlay that then includes this one
-/dts-v1/;
-/plugin/;
#include <dt-bindings/gpio/gpio.h>
--- a/arch/arm/boot/dts/overlays/pisound-pi5-overlay.dts
+++ b/arch/arm/boot/dts/overlays/pisound-pi5-overlay.dts
@@ -17,9 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-/dts-v1/;
-/plugin/;
-
#include "pisound-overlay.dts"
&pisound_spi {
--- a/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts
+++ b/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts
@@ -2,9 +2,6 @@
* vc4-fkms-v3d-overlay.dts
*/
-/dts-v1/;
-/plugin/;
-
#include "cma-overlay.dts"
/ {
--- a/arch/arm/boot/dts/overlays/vc4-fkms-v3d-pi4-overlay.dts
+++ b/arch/arm/boot/dts/overlays/vc4-fkms-v3d-pi4-overlay.dts
@@ -2,9 +2,6 @@
* vc4-fkms-v3d-overlay.dts
*/
-/dts-v1/;
-/plugin/;
-
#include "cma-overlay.dts"
&frag0 {
--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
@@ -2,9 +2,6 @@
* vc4-kms-v3d-overlay.dts
*/
-/dts-v1/;
-/plugin/;
-
#include <dt-bindings/clock/bcm2835.h>
#include "cma-overlay.dts"
--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts
@@ -2,9 +2,6 @@
* vc4-kms-v3d-pi4-overlay.dts
*/
-/dts-v1/;
-/plugin/;
-
#include <dt-bindings/clock/bcm2835.h>
#include "cma-overlay.dts"
--- a/arch/arm/boot/dts/overlays/w1-gpio-pi5-overlay.dts
+++ b/arch/arm/boot/dts/overlays/w1-gpio-pi5-overlay.dts
@@ -1,6 +1,3 @@
-/dts-v1/;
-/plugin/;
-
#include "w1-gpio-overlay.dts"
/ {
--- a/arch/arm/boot/dts/overlays/w1-gpio-pullup-pi5-overlay.dts
+++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-pi5-overlay.dts
@@ -1,6 +1,3 @@
-/dts-v1/;
-/plugin/;
-
#include "w1-gpio-pullup-overlay.dts"
/ {
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-/dts-v1/;
#include "bcm2712-rpi-cm5.dtsi"

View File

@ -0,0 +1,25 @@
From e33702e5e5fe9fef6ec967961e2e5e1c2285ba36 Mon Sep 17 00:00:00 2001
From: gtrainavicius <gtrainavicius@users.noreply.github.com>
Date: Wed, 4 Dec 2024 11:18:14 +0200
Subject: [PATCH] =?UTF-8?q?Allow=20setting=20I=C2=B2C=20clock=20frequency?=
=?UTF-8?q?=20via=20i2c=5Farm=5Fbaudrate=20dtparam=20when=20using=20pimidi?=
=?UTF-8?q?=20overlay.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This change removes the forced 1MHz clock frequency, so it can be overridden using `i2c_arm_baudrate`.
---
arch/arm/boot/dts/overlays/pimidi-overlay.dts | 1 -
1 file changed, 1 deletion(-)
--- a/arch/arm/boot/dts/overlays/pimidi-overlay.dts
+++ b/arch/arm/boot/dts/overlays/pimidi-overlay.dts
@@ -26,7 +26,6 @@
target = <&i2c_arm>;
__overlay__ {
status = "okay";
- clock-frequency=<1000000>;
pimidi_ctrl: pimidi_ctrl@20 {
compatible = "blokaslabs,pimidi";

View File

@ -0,0 +1,48 @@
From fda47c026dee7acd975ee2c0f7a440d4038cfaa3 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Tue, 3 Dec 2024 15:57:01 +0000
Subject: [PATCH] nvme-pci: Disable Host Memory Buffer usage
Some NVME drives seem to request significant amounts of DMA coherent
memory - enough to exhaust our standard 64MB CMA allocation.
Try disabling the feature to see what effect it has - drives should
continue to function without it.
Link: https://github.com/raspberrypi/linux/issues/6504
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/nvme/host/pci.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1932,6 +1932,7 @@ static void nvme_free_host_mem(struct nv
dev->nr_host_mem_descs = 0;
}
+#if 0
static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
u32 chunk_size)
{
@@ -2000,9 +2001,11 @@ out:
dev->host_mem_descs = NULL;
return -ENOMEM;
}
+#endif
static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred)
{
+#if 0
u64 min_chunk = min_t(u64, preferred, PAGE_SIZE * MAX_ORDER_NR_PAGES);
u64 hmminds = max_t(u32, dev->ctrl.hmminds * 4096, PAGE_SIZE * 2);
u64 chunk_size;
@@ -2015,6 +2018,7 @@ static int nvme_alloc_host_mem(struct nv
nvme_free_host_mem(dev);
}
}
+#endif
return -ENOMEM;
}

View File

@ -0,0 +1,23 @@
From 0313a0961b685973f7833017479a277e3a4c05a4 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 4 Dec 2024 14:40:59 +0000
Subject: [PATCH] fixup! serial: tty: Add a driver for the RPi firmware UART
Make SERIAL_RPI_FW depend on RASPBERRYPI_FIRMWARE.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/tty/serial/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1580,7 +1580,7 @@ config SERIAL_NUVOTON_MA35D1_CONSOLE
config SERIAL_RPI_FW
tristate "Raspberry Pi Firmware software UART support"
- depends on ARM_AMBA || COMPILE_TEST
+ depends on RASPBERRYPI_FIRMWARE || COMPILE_TEST
select SERIAL_CORE
help
This selects the Raspberry Pi firmware UART. This is a bit-bashed

View File

@ -0,0 +1,28 @@
From 0a5be0fe6ba3a981508421131def7eab55d6d75c Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 5 Dec 2024 12:08:23 +0000
Subject: [PATCH] serial: rpi-fw-uart: Demote debug log messages
A dev_info call in rpi_fw_uart_configure causes kernel log output every
time one opens the UART. Demote it to dev_dbg.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/tty/serial/rpi-fw-uart.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/tty/serial/rpi-fw-uart.c
+++ b/drivers/tty/serial/rpi-fw-uart.c
@@ -277,9 +277,9 @@ static int rpi_fw_uart_configure(struct
dev_dbg(port->dev, "version %08x, reg addr %x\n", msg.version,
msg.fifo_reg_base);
- dev_info(port->dev, "started %d baud %u data %u stop %u rx %u tx %u flags %u fifosize %u\n",
- msg.start, msg.baud, msg.data_bits, msg.stop_bits,
- msg.gpio_rx, msg.gpio_tx, msg.flags, msg.fifosize);
+ dev_dbg(port->dev, "started %d baud %u data %u stop %u rx %u tx %u flags %u fifosize %u\n",
+ msg.start, msg.baud, msg.data_bits, msg.stop_bits,
+ msg.gpio_rx, msg.gpio_tx, msg.flags, msg.fifosize);
if (msg.fifosize != port->fifosize) {
dev_err(port->dev, "Expected fifo size %u actual %u",

View File

@ -0,0 +1,55 @@
From 02dee262a9c7295ea514e9db7b9aa4b239922cb3 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Mon, 2 Dec 2024 15:41:21 +0000
Subject: [PATCH] dtoverlays: Add Arducam override for ov9281
The Arducam module is slow starting up, so add an override
to slow the regulator down.
https://forums.raspberrypi.com/viewtopic.php?t=380236
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
arch/arm/boot/dts/overlays/README | 2 ++
arch/arm/boot/dts/overlays/ov9281-overlay.dts | 13 ++++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -3538,6 +3538,8 @@ Params: rotation Mounting
configuring the sensor (default on)
cam0 Adopt the default configuration for CAM0 on a
Compute Module (CSI0, i2c_vc, and cam0_reg).
+ arducam Slow down the regulator for slow Arducam
+ modules.
Name: papirus
--- a/arch/arm/boot/dts/overlays/ov9281-overlay.dts
+++ b/arch/arm/boot/dts/overlays/ov9281-overlay.dts
@@ -57,6 +57,14 @@
};
};
+ reg_frag: fragment@5 {
+ target = <&cam1_reg>;
+ __dormant__ {
+ startup-delay-us = <20000>;
+ off-on-delay-us = <30000>;
+ };
+ };
+
__overrides__ {
rotation = <&cam_node>,"rotation:0";
orientation = <&cam_node>,"orientation:0";
@@ -65,7 +73,10 @@
<&csi_frag>, "target:0=",<&csi0>,
<&clk_frag>, "target:0=",<&cam0_clk>,
<&cam_node>, "clocks:0=",<&cam0_clk>,
- <&cam_node>, "avdd-supply:0=",<&cam0_reg>;
+ <&cam_node>, "avdd-supply:0=",<&cam0_reg>,
+ <&reg_frag>, "target:0=",<&cam0_reg>;
+ arducam = <0>, "+5";
+
};
};

View File

@ -0,0 +1,118 @@
From 97638920f1a40e2e0cab363d1e03837ff50c5478 Mon Sep 17 00:00:00 2001
From: eng33 <eng33@waveshare.com>
Date: Thu, 5 Dec 2024 17:19:23 +0800
Subject: [PATCH] drivers:input:touchscreen: Add support for no irq to ili210x
driver
Signed-off-by: eng33 <eng33@waveshare.com>
---
drivers/input/touchscreen/ili210x.c | 63 ++++++++++++++++++++++++-----
1 file changed, 52 insertions(+), 11 deletions(-)
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -67,6 +67,8 @@ struct ili210x {
u8 version_proto[2];
u8 ic_mode[2];
bool stop;
+ struct timer_list poll_timer;
+ struct work_struct poll_work;
};
static int ili210x_read_reg(struct i2c_client *client,
@@ -360,6 +362,34 @@ static irqreturn_t ili210x_irq(int irq,
return IRQ_HANDLED;
}
+static void ili210x_poll_work(struct work_struct *work)
+{
+ struct ili210x *priv = container_of(work, struct ili210x, poll_work);
+ struct i2c_client *client = priv->client;
+ const struct ili2xxx_chip *chip = priv->chip;
+ u8 touchdata[ILI210X_DATA_SIZE] = { 0 };
+ bool touch;
+ int error;
+
+ error = chip->get_touch_data(client, touchdata);
+ if (error) {
+ dev_err(&client->dev, "Unable to get touch data: %d\n", error);
+ return;
+ }
+
+ touch = ili210x_report_events(priv, touchdata);
+}
+
+static void ili210x_poll_timer_callback(struct timer_list *t)
+{
+ struct ili210x *priv = from_timer(priv, t, poll_timer);
+
+ schedule_work(&priv->poll_work);
+
+ if (!priv->stop)
+ mod_timer(&priv->poll_timer, jiffies + msecs_to_jiffies(ILI2XXX_POLL_PERIOD));
+}
+
static int ili251x_firmware_update_resolution(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -945,11 +975,6 @@ static int ili210x_i2c_probe(struct i2c_
return -ENODEV;
}
- if (client->irq <= 0) {
- dev_err(dev, "No IRQ!\n");
- return -EINVAL;
- }
-
reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(reset_gpio))
return PTR_ERR(reset_gpio);
@@ -1001,12 +1026,17 @@ static int ili210x_i2c_probe(struct i2c_
return error;
}
- error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq,
- IRQF_ONESHOT, client->name, priv);
- if (error) {
- dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
- error);
- return error;
+ if (client->irq) {
+ error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq,
+ IRQF_ONESHOT, client->name, priv);
+ if (error) {
+ dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", error);
+ return error;
+ }
+ } else {
+ timer_setup(&priv->poll_timer, ili210x_poll_timer_callback, 0);
+ mod_timer(&priv->poll_timer, jiffies + msecs_to_jiffies(ILI2XXX_POLL_PERIOD));
+ INIT_WORK(&priv->poll_work, ili210x_poll_work);
}
error = devm_add_action_or_reset(dev, ili210x_stop, priv);
@@ -1029,6 +1059,16 @@ static int ili210x_i2c_probe(struct i2c_
return 0;
}
+static void ili210x_i2c_remove(struct i2c_client *client)
+{
+ struct ili210x *tsdata = i2c_get_clientdata(client);
+
+ if (!client->irq) {
+ del_timer(&tsdata->poll_timer);
+ cancel_work_sync(&tsdata->poll_work);
+ }
+}
+
static const struct i2c_device_id ili210x_i2c_id[] = {
{ "ili210x", (long)&ili210x_chip },
{ "ili2117", (long)&ili211x_chip },
@@ -1054,6 +1094,7 @@ static struct i2c_driver ili210x_ts_driv
},
.id_table = ili210x_i2c_id,
.probe = ili210x_i2c_probe,
+ .remove = ili210x_i2c_remove,
};
module_i2c_driver(ili210x_ts_driver);

View File

@ -0,0 +1,309 @@
From 4a89fda8f73df89e009a6188ef07ab97b1d03c7f Mon Sep 17 00:00:00 2001
From: eng33 <eng33@waveshare.com>
Date: Thu, 5 Dec 2024 17:20:22 +0800
Subject: [PATCH] drivers:gpu:drm:panel: Added waveshare 13.3inch panel(support
2/4lane)
Signed-off-by: eng33 <eng33@waveshare.com>
---
drivers/gpu/drm/panel/panel-waveshare-dsi.c | 155 +++++++++++++++++---
1 file changed, 138 insertions(+), 17 deletions(-)
--- a/drivers/gpu/drm/panel/panel-waveshare-dsi.c
+++ b/drivers/gpu/drm/panel/panel-waveshare-dsi.c
@@ -32,6 +32,12 @@ struct ws_panel {
enum drm_panel_orientation orientation;
};
+struct ws_panel_data {
+ const struct drm_display_mode *mode;
+ int lanes;
+ unsigned long mode_flags;
+};
+
/* 2.8inch 480x640
* https://www.waveshare.com/product/raspberry-pi/displays/2.8inch-dsi-lcd.htm
*/
@@ -47,6 +53,12 @@ static const struct drm_display_mode ws_
.vtotal = 640 + 150 + 50 + 150,
};
+static const struct ws_panel_data ws_panel_2_8_data = {
+ .mode = &ws_panel_2_8_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 3.4inch 800x800 Round
* https://www.waveshare.com/product/displays/lcd-oled/3.4inch-dsi-lcd-c.htm
*/
@@ -62,6 +74,12 @@ static const struct drm_display_mode ws_
.vtotal = 800 + 8 + 4 + 16,
};
+static const struct ws_panel_data ws_panel_3_4_data = {
+ .mode = &ws_panel_3_4_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 4.0inch 480x800
* https://www.waveshare.com/product/raspberry-pi/displays/4inch-dsi-lcd.htm
*/
@@ -77,6 +95,12 @@ static const struct drm_display_mode ws_
.vtotal = 800 + 20 + 100 + 20,
};
+static const struct ws_panel_data ws_panel_4_0_data = {
+ .mode = &ws_panel_4_0_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 7.0inch C 1024x600
* https://www.waveshare.com/product/raspberry-pi/displays/lcd-oled/7inch-dsi-lcd-c-with-case-a.htm
*/
@@ -92,6 +116,12 @@ static const struct drm_display_mode ws_
.vtotal = 600 + 10 + 10 + 10,
};
+static const struct ws_panel_data ws_panel_7_0_c_data = {
+ .mode = &ws_panel_7_0_c_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 7.9inch 400x1280
* https://www.waveshare.com/product/raspberry-pi/displays/7.9inch-dsi-lcd.htm
*/
@@ -107,6 +137,12 @@ static const struct drm_display_mode ws_
.vtotal = 1280 + 20 + 10 + 20,
};
+static const struct ws_panel_data ws_panel_7_9_data = {
+ .mode = &ws_panel_7_9_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 8.0inch or 10.1inch 1280x800
* https://www.waveshare.com/product/raspberry-pi/displays/8inch-dsi-lcd-c.htm
* https://www.waveshare.com/product/raspberry-pi/displays/10.1inch-dsi-lcd-c.htm
@@ -123,6 +159,12 @@ static const struct drm_display_mode ws_
.vtotal = 800 + 40 + 48 + 40,
};
+static const struct ws_panel_data ws_panel_10_1_data = {
+ .mode = &ws_panel_10_1_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 11.9inch 320x1480
* https://www.waveshare.com/product/raspberry-pi/displays/11.9inch-dsi-lcd.htm
*/
@@ -138,6 +180,12 @@ static const struct drm_display_mode ws_
.vtotal = 1480 + 60 + 60 + 60,
};
+static const struct ws_panel_data ws_panel_11_9_data = {
+ .mode = &ws_panel_11_9_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
static const struct drm_display_mode ws_panel_4_mode = {
.clock = 50000,
.hdisplay = 720,
@@ -150,6 +198,12 @@ static const struct drm_display_mode ws_
.vtotal = 720 + 8 + 4 + 16,
};
+static const struct ws_panel_data ws_panel_4_data = {
+ .mode = &ws_panel_4_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 5.0inch 720x1280
* https://www.waveshare.com/5inch-dsi-lcd-d.htm
*/
@@ -165,6 +219,12 @@ static const struct drm_display_mode ws_
.vtotal = 1280 + 20 + 20 + 20,
};
+static const struct ws_panel_data ws_panel_5_0_data = {
+ .mode = &ws_panel_5_0_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 6.25inch 720x1560
* https://www.waveshare.com/6.25inch-dsi-lcd.htm
*/
@@ -180,6 +240,12 @@ static const struct drm_display_mode ws_
.vtotal = 1560 + 20 + 20 + 20,
};
+static const struct ws_panel_data ws_panel_6_25_data = {
+ .mode = &ws_panel_6_25_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
/* 8.8inch 480x1920
* https://www.waveshare.com/8.8inch-dsi-lcd.htm
*/
@@ -195,6 +261,48 @@ static const struct drm_display_mode ws_
.vtotal = 1920 + 20 + 20 + 20,
};
+static const struct ws_panel_data ws_panel_8_8_data = {
+ .mode = &ws_panel_8_8_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+};
+
+static const struct drm_display_mode ws_panel_13_3_4lane_mode = {
+ .clock = 148500,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 88,
+ .hsync_end = 1920 + 88 + 44,
+ .htotal = 1920 + 88 + 44 + 148,
+ .vdisplay = 1080,
+ .vsync_start = 1080 + 4,
+ .vsync_end = 1080 + 4 + 5,
+ .vtotal = 1080 + 4 + 5 + 36,
+};
+
+static const struct ws_panel_data ws_panel_13_3_4lane_data = {
+ .mode = &ws_panel_13_3_4lane_mode,
+ .lanes = 4,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM,
+};
+
+static const struct drm_display_mode ws_panel_13_3_2lane_mode = {
+ .clock = 83333,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 88,
+ .hsync_end = 1920 + 88 + 44,
+ .htotal = 1920 + 88 + 44 + 148,
+ .vdisplay = 1080,
+ .vsync_start = 1080 + 4,
+ .vsync_end = 1080 + 4 + 5,
+ .vtotal = 1080 + 4 + 5 + 36,
+};
+
+static const struct ws_panel_data ws_panel_13_3_2lane_data = {
+ .mode = &ws_panel_13_3_2lane_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM,
+};
+
static struct ws_panel *panel_to_ts(struct drm_panel *panel)
{
return container_of(panel, struct ws_panel, base);
@@ -232,7 +340,10 @@ static int ws_panel_enable(struct drm_pa
{
struct ws_panel *ts = panel_to_ts(panel);
- ws_panel_i2c_write(ts, 0xad, 0x01);
+ if (ts->mode == &ws_panel_13_3_2lane_mode)
+ ws_panel_i2c_write(ts, 0xad, 0x02);
+ else
+ ws_panel_i2c_write(ts, 0xad, 0x01);
return 0;
}
@@ -328,13 +439,18 @@ static int ws_panel_probe(struct i2c_cli
.channel = 0,
.node = NULL,
};
+ const struct ws_panel_data *_ws_panel_data;
int ret;
ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
if (!ts)
return -ENOMEM;
- ts->mode = of_device_get_match_data(dev);
+ _ws_panel_data = of_device_get_match_data(dev);
+ if (!_ws_panel_data)
+ return -EINVAL;
+
+ ts->mode = _ws_panel_data->mode;
if (!ts->mode)
return -EINVAL;
@@ -396,10 +512,9 @@ static int ws_panel_probe(struct i2c_cli
*/
drm_panel_add(&ts->base);
- ts->dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
- MIPI_DSI_CLOCK_NON_CONTINUOUS;
+ ts->dsi->mode_flags = _ws_panel_data->mode_flags;
ts->dsi->format = MIPI_DSI_FMT_RGB888;
- ts->dsi->lanes = 2;
+ ts->dsi->lanes = _ws_panel_data->lanes;
ret = devm_mipi_dsi_attach(dev, ts->dsi);
@@ -432,40 +547,46 @@ static void ws_panel_shutdown(struct i2c
static const struct of_device_id ws_panel_of_ids[] = {
{
.compatible = "waveshare,2.8inch-panel",
- .data = &ws_panel_2_8_mode,
+ .data = &ws_panel_2_8_data,
}, {
.compatible = "waveshare,3.4inch-panel",
- .data = &ws_panel_3_4_mode,
+ .data = &ws_panel_3_4_data,
}, {
.compatible = "waveshare,4.0inch-panel",
- .data = &ws_panel_4_0_mode,
+ .data = &ws_panel_4_0_data,
}, {
.compatible = "waveshare,7.0inch-c-panel",
- .data = &ws_panel_7_0_c_mode,
+ .data = &ws_panel_7_0_c_data,
}, {
.compatible = "waveshare,7.9inch-panel",
- .data = &ws_panel_7_9_mode,
+ .data = &ws_panel_7_9_data,
}, {
.compatible = "waveshare,8.0inch-panel",
- .data = &ws_panel_10_1_mode,
+ .data = &ws_panel_10_1_data,
}, {
.compatible = "waveshare,10.1inch-panel",
- .data = &ws_panel_10_1_mode,
+ .data = &ws_panel_10_1_data,
}, {
.compatible = "waveshare,11.9inch-panel",
- .data = &ws_panel_11_9_mode,
+ .data = &ws_panel_11_9_data,
}, {
.compatible = "waveshare,4inch-panel",
- .data = &ws_panel_4_mode,
+ .data = &ws_panel_4_data,
}, {
.compatible = "waveshare,5.0inch-panel",
- .data = &ws_panel_5_0_mode,
+ .data = &ws_panel_5_0_data,
}, {
.compatible = "waveshare,6.25inch-panel",
- .data = &ws_panel_6_25_mode,
+ .data = &ws_panel_6_25_data,
}, {
.compatible = "waveshare,8.8inch-panel",
- .data = &ws_panel_8_8_mode,
+ .data = &ws_panel_8_8_data,
+ }, {
+ .compatible = "waveshare,13.3inch-4lane-panel",
+ .data = &ws_panel_13_3_4lane_data,
+ }, {
+ .compatible = "waveshare,13.3inch-2lane-panel",
+ .data = &ws_panel_13_3_2lane_data,
}, {
/* sentinel */
}

View File

@ -0,0 +1,46 @@
From e442e5c1ab6bff5b5460b4fc949beb72aaf77970 Mon Sep 17 00:00:00 2001
From: eng33 <eng33@waveshare.com>
Date: Thu, 5 Dec 2024 18:11:26 +0800
Subject: [PATCH] arch:arm:boot:dts:overlays: Added waveshare 13.3inch panel
support
Signed-off-by: eng33 <eng33@waveshare.com>
---
arch/arm/boot/dts/overlays/README | 2 ++
.../dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts | 7 +++++++
2 files changed, 9 insertions(+)
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -5338,6 +5338,8 @@ Params: 2_8_inch 2.8" 480
8_0_inch 8.0" 1280x800
10_1_inch 10.1" 1280x800
11_9_inch 11.9" 320x1480
+ 13_3_inch_4lane 13.3" 1920x1080 4lane
+ 13_3_inch_2lane 13.3" 1920x1080 2lane
i2c1 Use i2c-1 with jumper wires from GPIOs 2&3
disable_touch Disable the touch controller
rotation Set the panel orientation property
--- a/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts
+++ b/arch/arm/boot/dts/overlays/vc4-kms-dsi-waveshare-panel-overlay.dts
@@ -51,6 +51,11 @@
reg = <0x14>;
compatible = "goodix,gt911";
};
+
+ touch2: ilitek@41 {
+ compatible = "ilitek,ili251x";
+ reg = <0x41>;
+ };
};
};
@@ -120,6 +125,8 @@
<&touch>, "touchscreen-inverted-x?",
<&touch>, "touchscreen-inverted-y?";
8_8_inch = <&panel>, "compatible=waveshare,8.8inch-panel";
+ 13_3_inch_4lane = <&panel>, "compatible=waveshare,13.3inch-4lane-panel";
+ 13_3_inch_2lane = <&panel>, "compatible=waveshare,13.3inch-2lane-panel";
i2c1 = <&i2c_frag>, "target:0=",<&i2c1>,
<0>, "-3-4+5";
disable_touch = <&touch>, "status=disabled";

View File

@ -0,0 +1,37 @@
From 166dfc4399643681f2e4277bf7b7407e926861e5 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Mon, 9 Dec 2024 14:58:16 +0000
Subject: [PATCH] fixup! cgroup: Use kernel command line to disable memory
cgroup
cgroup features are distinct from cgroup subsystems - handle them
correctly.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
kernel/cgroup/cgroup.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -6769,11 +6769,19 @@ static int __init cgroup_enable(char *st
strcmp(token, ss->legacy_name))
continue;
- cgroup_feature_disable_mask &= ~(1 << i);
static_branch_enable(cgroup_subsys_enabled_key[i]);
pr_info("Enabling %s control group subsystem\n",
ss->name);
}
+
+ for (i = 0; i < OPT_FEATURE_COUNT; i++) {
+ if (strcmp(token, cgroup_opt_feature_names[i]))
+ continue;
+ cgroup_feature_disable_mask &= ~(1 << i);
+ pr_info("Enabling %s control group feature\n",
+ cgroup_opt_feature_names[i]);
+ break;
+ }
}
return 1;
}

View File

@ -0,0 +1,31 @@
From e23afbf2c7aae9264322eee8e5c72ca1887606df Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Mon, 9 Dec 2024 10:43:18 +0000
Subject: [PATCH] media: i2c: ov9282: Correct the exposure offset
The datasheet lists that "Maximum exposure time is frame
length -25 row periods, where frame length is set by
registers {0x380E, 0x380F}".
However this driver had OV9282_EXPOSURE_OFFSET set to 12
which allowed that restriction to be violated, and would
result in very under-exposed images.
Correct the offset.
Fixes: 14ea315bbeb7 ("media: i2c: Add ov9282 camera sensor driver")
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/ov9282.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -40,7 +40,7 @@
/* Exposure control */
#define OV9282_REG_EXPOSURE 0x3500
#define OV9282_EXPOSURE_MIN 1
-#define OV9282_EXPOSURE_OFFSET 12
+#define OV9282_EXPOSURE_OFFSET 25
#define OV9282_EXPOSURE_STEP 1
#define OV9282_EXPOSURE_DEFAULT 0x0282

View File

@ -0,0 +1,22 @@
From 448a2db3990534810b45d3e4202df96ab2dc5815 Mon Sep 17 00:00:00 2001
From: Dom Cobley <popcornmix@gmail.com>
Date: Tue, 10 Dec 2024 15:28:28 +0000
Subject: [PATCH] Revert "drm/vc4: hvs: Don't write gamma luts on 2711"
This reverts commit 40c77e93cfdda320f47fc1a00a76ce466d20e976.
---
drivers/gpu/drm/vc4/vc4_hvs.c | 3 ---
1 file changed, 3 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -521,9 +521,6 @@ static void vc4_hvs_lut_load(struct vc4_
if (!drm_dev_enter(drm, &idx))
return;
- if (hvs->vc4->gen == VC4_GEN_5)
- return;
-
/* The LUT memory is laid out with each HVS channel in order,
* each of which takes 256 writes for R, 256 for G, then 256
* for B.

View File

@ -0,0 +1,29 @@
From 746662562995125ef7fb2c294300b0bd061b1251 Mon Sep 17 00:00:00 2001
From: Dom Cobley <popcornmix@gmail.com>
Date: Tue, 10 Dec 2024 16:39:31 +0000
Subject: [PATCH] Revert "PCI: Warn if no host bridge NUMA node info"
This warning doesn't mean anyting on our platform and
the warning causes confusion.
See: https://forums.raspberrypi.com/viewtopic.php?p=2276125#p2276125
This reverts commit ad5086108b9f0361929aa9a79cf959ab5681d249.
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
---
drivers/pci/probe.c | 3 ---
1 file changed, 3 deletions(-)
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -968,9 +968,6 @@ static int pci_register_host_bridge(stru
else
pr_info("PCI host bridge to bus %s\n", name);
- if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE)
- dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n");
-
/* Coalesce contiguous windows */
resource_list_for_each_entry_safe(window, n, &resources) {
if (list_is_last(&window->node, &resources))

View File

@ -0,0 +1,25 @@
From 7d294fbff4863e53a64685335b30aed9604cae49 Mon Sep 17 00:00:00 2001
From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Date: Tue, 19 Nov 2024 16:11:32 +0000
Subject: [PATCH] drm: bridge: panel: Connector to allow interlaced modes
When initialized from panel_bridge_attach(), connector should
allow interlaced modes rather than invariably rejecting them,
so that other components can validate them.
Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
---
drivers/gpu/drm/bridge/panel.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -82,6 +82,8 @@ static int panel_bridge_attach(struct dr
return ret;
}
+ connector->interlace_allowed = true;
+
drm_panel_bridge_set_orientation(connector, bridge);
drm_connector_attach_encoder(&panel_bridge->connector,

View File

@ -0,0 +1,34 @@
From 2b0acbe8fd008e09a904b7a3c796a2dc79bf10ea Mon Sep 17 00:00:00 2001
From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Date: Tue, 19 Nov 2024 16:17:40 +0000
Subject: [PATCH] dts: overlays: vc4-kms-dpi-generic-overlay: Add "interlaced"
property
Almost no DPI hardware supports it, but it's useful for RP1 video out.
Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
---
arch/arm/boot/dts/overlays/README | 1 +
arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts | 1 +
2 files changed, 2 insertions(+)
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -5099,6 +5099,7 @@ Params: clock-frequency Display
vsync-invert Vertical sync active low
de-invert Data Enable active low
pixclk-invert Negative edge pixel clock
+ interlaced Use an interlaced mode (where supported)
width-mm Define the screen width in mm
height-mm Define the screen height in mm
rgb565 Change to RGB565 output on GPIOs 0-19
--- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts
+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts
@@ -59,6 +59,7 @@
vsync-invert = <&timing>, "vsync-active:0=0";
de-invert = <&timing>, "de-active:0=0";
pixclk-invert = <&timing>, "pixelclk-active:0=0";
+ interlaced = <&timing>, "interlaced?";
width-mm = <&panel_generic>, "width-mm:0";
height-mm = <&panel_generic>, "height-mm:0";

View File

@ -1,8 +1,8 @@
From 7735dd0736322cff23aff95490bae1d69937a9bf Mon Sep 17 00:00:00 2001
From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Date: Tue, 10 Dec 2024 13:23:09 +0000
Subject: [PATCH 1456/1482] drm: rp1: rp1-dpi: Add interlaced modes and PIO
program to fix VSYNC
Subject: [PATCH] drm: rp1: rp1-dpi: Add interlaced modes and PIO program to
fix VSYNC
Implement interlaced modes by wobbling the base pointer and VFP width
for every field. This results in correct pixels but incorrect VSYNC.

View File

@ -1,22 +0,0 @@
From f85f3509692f966ec32e4db499f7e64dc6b6b952 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 12 Dec 2024 10:09:13 +0000
Subject: [PATCH 1457/1482] pwm: Improve PWM_PIO_RP1 dependencies
PWM_PIO_RP1 should select RP1_PIO, as it is useless without it.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/pwm/Kconfig | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -457,6 +457,7 @@ config PWM_PCA9685
config PWM_PIO_RP1
tristate "RP1 PIO PWM support"
depends on FIRMWARE_RP1 || COMPILE_TEST
+ select RP1_PIO
help
This is a PWM framework driver for Raspberry Pi 5, using the PIO
hardware of RP1 to provide PWM functionality. Supports up to 4

View File

@ -1,20 +0,0 @@
From 73fb1e979a210094935f4af4c3d6e700fba30c5f Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 12 Dec 2024 10:28:54 +0000
Subject: [PATCH 1458/1482] Revert "pwm: Improve PWM_PIO_RP1 dependencies"
This reverts commit f85f3509692f966ec32e4db499f7e64dc6b6b952.
---
drivers/pwm/Kconfig | 1 -
1 file changed, 1 deletion(-)
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -457,7 +457,6 @@ config PWM_PCA9685
config PWM_PIO_RP1
tristate "RP1 PIO PWM support"
depends on FIRMWARE_RP1 || COMPILE_TEST
- select RP1_PIO
help
This is a PWM framework driver for Raspberry Pi 5, using the PIO
hardware of RP1 to provide PWM functionality. Supports up to 4

View File

@ -0,0 +1,79 @@
From ac0cd73932aa1e371ffaf0b974855ed3cd22937f Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 11 Dec 2024 13:47:30 +0000
Subject: [PATCH] ASoC: allo-piano-dac-plus: Fix volume limit locking
Calling snd_soc_limit_volume from within a kcontrol put handler seems
to cause a deadlock as it attempts to claim a write lock that is already
held. Call snd_soc_limit_volume from the main initialisation code
instead, to avoid the recursive locking.
See: https://github.com/raspberrypi/linux/issues/6527
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
sound/soc/bcm/allo-piano-dac-plus.c | 32 +++++++++++++----------------
1 file changed, 14 insertions(+), 18 deletions(-)
--- a/sound/soc/bcm/allo-piano-dac-plus.c
+++ b/sound/soc/bcm/allo-piano-dac-plus.c
@@ -452,14 +452,6 @@ static int pcm512x_set_reg_sub(struct sn
rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
- if (digital_gain_0db_limit) {
- ret = snd_soc_limit_volume(card, "Subwoofer Playback Volume",
- 207);
- if (ret < 0)
- dev_warn(card->dev, "Failed to set volume limit: %d\n",
- ret);
- }
-
// When in Dual Mono, Sub vol control should not set anything.
if (glb_ptr->dual_mode != 1) { //Not in Dual Mono mode
@@ -562,14 +554,6 @@ static int pcm512x_set_reg_master(struct
rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
- if (digital_gain_0db_limit) {
- ret = snd_soc_limit_volume(card, "Master Playback Volume",
- 207);
- if (ret < 0)
- dev_warn(card->dev, "Failed to set volume limit: %d\n",
- ret);
- }
-
if (glb_ptr->dual_mode == 1) { //in Dual Mono Mode
ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 0)->component,
@@ -750,6 +734,18 @@ static int snd_allo_piano_dac_init(struc
if (digital_gain_0db_limit) {
int ret;
+ ret = snd_soc_limit_volume(card, "Master Playback Volume",
+ 207);
+ if (ret < 0)
+ dev_warn(card->dev, "Failed to set master volume limit: %d\n",
+ ret);
+
+ ret = snd_soc_limit_volume(card, "Subwoofer Playback Volume",
+ 207);
+ if (ret < 0)
+ dev_warn(card->dev, "Failed to set subwoofer volume limit: %d\n",
+ ret);
+
//Set volume limit on both dacs
for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) {
char cname[256];
@@ -757,8 +753,8 @@ static int snd_allo_piano_dac_init(struc
sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[0]);
ret = snd_soc_limit_volume(card, cname, 207);
if (ret < 0)
- dev_warn(card->dev, "Failed to set volume limit: %d\n",
- ret);
+ dev_warn(card->dev, "Failed to set %s volume limit: %d\n",
+ cname, ret);
}
}

View File

@ -0,0 +1,30 @@
From af4ab4fb77dfc697c8ae068b18f27de1ee5d609f Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Wed, 11 Dec 2024 16:30:43 +0000
Subject: [PATCH] drm: vc4: txp: Do not allow 24bpp formats when transposing
The hardware doesn't support transposing to 24bpp (RGB888/BGR888)
formats. There's no way to advertise this through DRM, so block
it from atomic_check instead.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/vc4/vc4_txp.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -272,6 +272,13 @@ static int vc4_txp_connector_atomic_chec
return -EINVAL;
}
+ if (conn_state->rotation & DRM_MODE_TRANSPOSE &&
+ (fb->format->format == DRM_FORMAT_RGB888 ||
+ fb->format->format == DRM_FORMAT_BGR888)) {
+ DRM_DEBUG_KMS("24bpp formats not supported when transposing\n");
+ return -EINVAL;
+ }
+
for (i = 0; i < ARRAY_SIZE(drm_fmts); i++) {
if (fb->format->format == drm_fmts[i])
break;

View File

@ -0,0 +1,29 @@
From 0b216b3988e5b7035cd5ed8a9910eacbb3420ce0 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Thu, 12 Dec 2024 11:59:52 +0000
Subject: [PATCH] drm: Validate connector rotation has one bit set in the
rotation property
Copy the same validation logic as from the plane rotation property.
Fixes: 8fec3ff87049 ("drm: Add a rotation parameter to connectors.")
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/gpu/drm/drm_atomic_uapi.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -812,6 +812,12 @@ static int drm_atomic_connector_set_prop
} else if (property == connector->privacy_screen_sw_state_property) {
state->privacy_screen_sw_state = val;
} else if (property == connector->rotation_property) {
+ if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) {
+ drm_dbg_atomic(connector->dev,
+ "[CONNECTOR:%d:%s] bad rotation bitmask: 0x%llx\n",
+ connector->base.id, connector->name, val);
+ return -EINVAL;
+ }
state->rotation = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,

View File

@ -0,0 +1,73 @@
From 61494a7aa2ea887fa1cd1399a8db1317c87f661b Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Thu, 12 Dec 2024 13:05:41 +0000
Subject: [PATCH] ASoC: allo-piano-dac-plus: Suppress -517 errors
Use dev_err_probe to simplify the code and suppress EPROBE_DEFER errors.
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
sound/soc/bcm/allo-piano-dac-plus.c | 37 ++++++++---------------------
1 file changed, 10 insertions(+), 27 deletions(-)
--- a/sound/soc/bcm/allo-piano-dac-plus.c
+++ b/sound/soc/bcm/allo-piano-dac-plus.c
@@ -974,48 +974,31 @@ static int snd_allo_piano_dac_probe(stru
allo_piano_2_1_codecs[0].of_node =
of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
- if (!allo_piano_2_1_codecs[0].of_node) {
- dev_err(&pdev->dev,
- "Property 'audio-codec' missing or invalid\n");
- return -EINVAL;
- }
-
allo_piano_2_1_codecs[1].of_node =
of_parse_phandle(pdev->dev.of_node, "audio-codec", 1);
- if (!allo_piano_2_1_codecs[1].of_node) {
- dev_err(&pdev->dev,
+ if (!allo_piano_2_1_codecs[0].of_node || !allo_piano_2_1_codecs[1].of_node)
+ return dev_err_probe(&pdev->dev, -EINVAL,
"Property 'audio-codec' missing or invalid\n");
- return -EINVAL;
- }
mute_gpio[0] = devm_gpiod_get_optional(&pdev->dev, "mute1",
GPIOD_OUT_LOW);
- if (IS_ERR(mute_gpio[0])) {
- ret = PTR_ERR(mute_gpio[0]);
- dev_err(&pdev->dev,
- "failed to get mute1 gpio6: %d\n", ret);
- return ret;
- }
+ if (IS_ERR(mute_gpio[0]))
+ return dev_err_probe(&pdev->dev, PTR_ERR(mute_gpio[0]),
+ "failed to get mute1 gpio\n");
mute_gpio[1] = devm_gpiod_get_optional(&pdev->dev, "mute2",
GPIOD_OUT_LOW);
- if (IS_ERR(mute_gpio[1])) {
- ret = PTR_ERR(mute_gpio[1]);
- dev_err(&pdev->dev,
- "failed to get mute2 gpio25: %d\n", ret);
- return ret;
- }
+ if (IS_ERR(mute_gpio[1]))
+ return dev_err_probe(&pdev->dev, PTR_ERR(mute_gpio[1]),
+ "failed to get mute2 gpio\n");
if (mute_gpio[0] && mute_gpio[1])
snd_allo_piano_dac.set_bias_level =
snd_allo_piano_set_bias_level;
ret = snd_soc_register_card(&snd_allo_piano_dac);
- if (ret < 0) {
- dev_err(&pdev->dev,
- "snd_soc_register_card() failed: %d\n", ret);
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret, "snd_soc_register_card() failed\n");
if ((mute_gpio[0]) && (mute_gpio[1]))
snd_allo_piano_gpio_mute(&snd_allo_piano_dac);

View File

@ -1,8 +1,7 @@
From 80533a952218696c0ef1b346bab50dc401e6b74c Mon Sep 17 00:00:00 2001
From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Date: Thu, 12 Dec 2024 11:58:12 +0000
Subject: [PATCH 1463/1482] drm: rp1: rp1-dpi: Fix optional dependency on
RP1_PIO
Subject: [PATCH] drm: rp1: rp1-dpi: Fix optional dependency on RP1_PIO
Add optional dependency to Kconfig, and conditionally compile
PIO-dependent code. Add a mode validation function to reject

Some files were not shown because too many files have changed in this diff Show More