[packages/kernel] add fixes for pinebook pro
atler
atler at pld-linux.org
Sun Feb 14 12:24:58 CET 2021
commit 8c9054aff253529737edf2127a16afcfcf45b0a8
Author: Jan Palus <atler at pld-linux.org>
Date: Sun Feb 14 12:21:41 2021 +0100
add fixes for pinebook pro
selected commits from:
https://gitlab.manjaro.org/tsys/linux-pinebook-pro
patch from:
http://lists.infradead.org/pipermail/linux-rockchip/2020-August/021780.html
kernel-pinebook-pro.patch | 1074 ++++++++++++++++++++++++++++++++++++++++++
kernel-rk3399-afbc-ytr.patch | 50 ++
kernel.spec | 4 +
3 files changed, 1128 insertions(+)
---
diff --git a/kernel.spec b/kernel.spec
index 15c4e6af..600a25a6 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -227,6 +227,8 @@ Patch7000: kernel-inittmpfs.patch
# ARM only
Patch8000: rpi-wm8804.patch
+Patch8001: kernel-pinebook-pro.patch
+Patch8002: kernel-rk3399-afbc-ytr.patch
# Do not remove this line, please. It is easier for me to uncomment two lines, then patch
# kernel.spec every time.
@@ -697,6 +699,8 @@ cd linux-%{basever}
%ifarch %{arm} aarch64
%patch8000 -p1
+%patch8001 -p1
+%patch8002 -p1
%endif
%if %{with rt}
diff --git a/kernel-pinebook-pro.patch b/kernel-pinebook-pro.patch
new file mode 100644
index 00000000..8bfd20c6
--- /dev/null
+++ b/kernel-pinebook-pro.patch
@@ -0,0 +1,1074 @@
+From c223fa5f3cded17156fb781c1861a92349c4c5be Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:01:59 +0200
+Subject: [PATCH] leds: Add support for inverted LED triggers
+
+Needs to be changed for upstream, invert via sysfs not trigger duplication
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ drivers/leds/led-core.c | 1 +
+ drivers/leds/led-triggers.c | 149 +++++++++++++++++++++++++++---------
+ include/linux/leds.h | 1 +
+ 3 files changed, 113 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
+index c4e780bdb385..3973676d6f1e 100644
+--- a/drivers/leds/led-core.c
++++ b/drivers/leds/led-core.c
+@@ -177,6 +177,7 @@ static void led_blink_setup(struct led_classdev *led_cdev,
+ unsigned long *delay_off)
+ {
+ if (!test_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags) &&
++ !test_bit(LED_BLINK_INVERT, &led_cdev->work_flags) &&
+ led_cdev->blink_set &&
+ !led_cdev->blink_set(led_cdev, delay_on, delay_off))
+ return;
+diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
+index 91da90cfb11d..7f2898a0e1e3 100644
+--- a/drivers/leds/led-triggers.c
++++ b/drivers/leds/led-triggers.c
+@@ -27,20 +27,89 @@ LIST_HEAD(trigger_list);
+
+ /* Used by LED Class */
+
++
+ static inline bool
+ trigger_relevant(struct led_classdev *led_cdev, struct led_trigger *trig)
+ {
+ return !trig->trigger_type || trig->trigger_type == led_cdev->trigger_type;
+ }
+
++
++#define TRIGGER_INVERT_SUFFIX "-inverted"
++
++/*
++ * Check suffix of trigger name agains TRIGGER_INVERT_SUFFIX
++ */
++static bool led_trigger_is_inverted(const char *trigname)
++{
++ if (strlen(trigname) >= strlen(TRIGGER_INVERT_SUFFIX)) {
++ return !strcmp(trigname + strlen(trigname) -
++ strlen(TRIGGER_INVERT_SUFFIX),
++ TRIGGER_INVERT_SUFFIX);
++ }
++
++ return false;
++}
++
++/*
++ * Get length of trigger name name without TRIGGER_INVERT_SUFFIX
++ */
++static size_t led_trigger_get_name_len(const char *trigname)
++{
++ // Subtract length of TRIGGER_INVERT_SUFFIX if trigger is inverted
++ if (led_trigger_is_inverted(trigname))
++ return strlen(trigname) - strlen(TRIGGER_INVERT_SUFFIX);
++ return strlen(trigname);
++}
++
++/*
++ * Find and set led trigger by name
++ */
++static int led_trigger_set_str_(struct led_classdev *led_cdev,
++ const char *trigname, bool lock)
++{
++ struct led_trigger *trig;
++ bool inverted = led_trigger_is_inverted(trigname);
++ size_t len = led_trigger_get_name_len(trigname);
++
++ down_read(&triggers_list_lock);
++ list_for_each_entry(trig, &trigger_list, next_trig) {
++ /* Compare trigger name without inversion suffix */
++ if (strlen(trig->name) == len &&
++ !strncmp(trigname, trig->name, len) &&
++ trigger_relevant(led_cdev, trig)) {
++ if (lock)
++ down_write(&led_cdev->trigger_lock);
++ led_trigger_set(led_cdev, trig);
++ if (inverted)
++ led_cdev->flags |= LED_INVERT_TRIGGER;
++ else
++ led_cdev->flags &= ~LED_INVERT_TRIGGER;
++ if (lock)
++ up_write(&led_cdev->trigger_lock);
++
++ up_read(&triggers_list_lock);
++ return 0;
++ }
++ }
++ /* we come here only if trigname matches no trigger */
++ up_read(&triggers_list_lock);
++ return -EINVAL;
++}
++
++#define led_trigger_set_str(cdev, name) led_trigger_set_str_(cdev, name, true)
++#define led_trigger_set_str_unlocked(cdev, name) \
++ led_trigger_set_str_(cdev, name, false)
++
++
+ ssize_t led_trigger_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t pos, size_t count)
+ {
+ struct device *dev = kobj_to_dev(kobj);
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+- struct led_trigger *trig;
+ int ret = count;
++ char *name;
+
+ mutex_lock(&led_cdev->led_access);
+
+@@ -54,20 +123,10 @@ ssize_t led_trigger_write(struct file *filp, struct kobject *kobj,
+ goto unlock;
+ }
+
+- down_read(&triggers_list_lock);
+- list_for_each_entry(trig, &trigger_list, next_trig) {
+- if (sysfs_streq(buf, trig->name) && trigger_relevant(led_cdev, trig)) {
+- down_write(&led_cdev->trigger_lock);
+- led_trigger_set(led_cdev, trig);
+- up_write(&led_cdev->trigger_lock);
+-
+- up_read(&triggers_list_lock);
+- goto unlock;
+- }
+- }
+- /* we come here only if buf matches no trigger */
+- ret = -EINVAL;
+- up_read(&triggers_list_lock);
++ name = strim(buf);
++ ret = led_trigger_set_str(led_cdev, name);
++ if (!ret)
++ ret = count;
+
+ unlock:
+ mutex_unlock(&led_cdev->led_access);
+@@ -99,16 +158,25 @@ static int led_trigger_format(char *buf, size_t size,
+ led_cdev->trigger ? "none" : "[none]");
+
+ list_for_each_entry(trig, &trigger_list, next_trig) {
+- bool hit;
++ bool hit = led_cdev->trigger == trig;
++ bool inverted = led_cdev->flags & LED_INVERT_TRIGGER;
+
+ if (!trigger_relevant(led_cdev, trig))
+ continue;
+
+- hit = led_cdev->trigger && !strcmp(led_cdev->trigger->name, trig->name);
++ /* print non-inverted trigger */
++ len += led_trigger_snprintf(buf + len, size - len,
++ " %s%s%s",
++ hit && !inverted ? "[" : "",
++ trig->name,
++ hit && !inverted ? "]" : "");
+
++ /* print inverted trigger */
+ len += led_trigger_snprintf(buf + len, size - len,
+- " %s%s%s", hit ? "[" : "",
+- trig->name, hit ? "]" : "");
++ " %s%s"TRIGGER_INVERT_SUFFIX"%s",
++ hit && inverted ? "[" : "",
++ trig->name,
++ hit && inverted ? "]" : "");
+ }
+
+ len += led_trigger_snprintf(buf + len, size - len, "\n");
+@@ -245,22 +313,15 @@ EXPORT_SYMBOL_GPL(led_trigger_remove);
+
+ void led_trigger_set_default(struct led_classdev *led_cdev)
+ {
+- struct led_trigger *trig;
++ bool found;
+
+ if (!led_cdev->default_trigger)
+ return;
+
+ down_read(&triggers_list_lock);
+- down_write(&led_cdev->trigger_lock);
+- list_for_each_entry(trig, &trigger_list, next_trig) {
+- if (!strcmp(led_cdev->default_trigger, trig->name) &&
+- trigger_relevant(led_cdev, trig)) {
+- led_cdev->flags |= LED_INIT_DEFAULT_TRIGGER;
+- led_trigger_set(led_cdev, trig);
+- break;
+- }
+- }
+- up_write(&led_cdev->trigger_lock);
++ found = !led_trigger_set_str(led_cdev, led_cdev->default_trigger);
++ if (found)
++ led_cdev->flags |= LED_INIT_DEFAULT_TRIGGER;
+ up_read(&triggers_list_lock);
+ }
+ EXPORT_SYMBOL_GPL(led_trigger_set_default);
+@@ -305,12 +366,15 @@ int led_trigger_register(struct led_trigger *trig)
+ /* Register with any LEDs that have this as a default trigger */
+ down_read(&leds_list_lock);
+ list_for_each_entry(led_cdev, &leds_list, node) {
++ bool found;
++
+ down_write(&led_cdev->trigger_lock);
+ if (!led_cdev->trigger && led_cdev->default_trigger &&
+- !strcmp(led_cdev->default_trigger, trig->name) &&
+ trigger_relevant(led_cdev, trig)) {
+- led_cdev->flags |= LED_INIT_DEFAULT_TRIGGER;
+- led_trigger_set(led_cdev, trig);
++ found = !led_trigger_set_str_unlocked(led_cdev,
++ led_cdev->default_trigger);
++ if (found)
++ led_cdev->flags |= LED_INIT_DEFAULT_TRIGGER;
+ }
+ up_write(&led_cdev->trigger_lock);
+ }
+@@ -383,8 +447,14 @@ void led_trigger_event(struct led_trigger *trig,
+ return;
+
+ read_lock_irqsave(&trig->leddev_list_lock, flags);
+- list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list)
+- led_set_brightness(led_cdev, brightness);
++ list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) {
++ /* Reverse brightness if LED is inverted */
++ if (led_cdev->flags & LED_INVERT_TRIGGER)
++ led_set_brightness(led_cdev,
++ led_cdev->max_brightness - brightness);
++ else
++ led_set_brightness(led_cdev, brightness);
++ }
+ read_unlock_irqrestore(&trig->leddev_list_lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(led_trigger_event);
+@@ -402,10 +472,13 @@ static void led_trigger_blink_setup(struct led_trigger *trig,
+
+ read_lock(&trig->leddev_list_lock);
+ list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) {
+- if (oneshot)
++ bool trigger_inverted =
++ !!(led_cdev->flags & LED_INVERT_TRIGGER);
++ if (oneshot) {
++ /* use logical xnor to determine inversion parameter */
+ led_blink_set_oneshot(led_cdev, delay_on, delay_off,
+- invert);
+- else
++ (!!invert) == trigger_inverted);
++ } else
+ led_blink_set(led_cdev, delay_on, delay_off);
+ }
+ read_unlock(&trig->leddev_list_lock);
+diff --git a/include/linux/leds.h b/include/linux/leds.h
+index 6a8d6409c993..9cbf42cf08e8 100644
+--- a/include/linux/leds.h
++++ b/include/linux/leds.h
+@@ -79,6 +79,7 @@ struct led_classdev {
+ #define LED_BRIGHT_HW_CHANGED BIT(21)
+ #define LED_RETAIN_AT_SHUTDOWN BIT(22)
+ #define LED_INIT_DEFAULT_TRIGGER BIT(23)
++#define LED_INVERT_TRIGGER BIT(24)
+
+ /* set_brightness_work / blink_timer flags, atomic, private. */
+ unsigned long work_flags;
+--
+GitLab
+
+From 90a117ec260f54078aabcf2c1cde72f4425116ba Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:12:56 +0200
+Subject: [PATCH] tty: serdev: support shutdown op
+
+Allow serdev drivers to register a shutdown handler
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ drivers/tty/serdev/core.c | 11 +++++++++++
+ include/linux/serdev.h | 1 +
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
+index c5f0d936b003..37e45c356540 100644
+--- a/drivers/tty/serdev/core.c
++++ b/drivers/tty/serdev/core.c
+@@ -432,11 +432,22 @@ static int serdev_drv_remove(struct device *dev)
+ return 0;
+ }
+
++static void serdev_drv_shutdown(struct device *dev)
++{
++ const struct serdev_device_driver *sdrv;
++ if (dev->driver) {
++ sdrv = to_serdev_device_driver(dev->driver);
++ if (sdrv->shutdown)
++ sdrv->shutdown(to_serdev_device(dev));
++ }
++}
++
+ static struct bus_type serdev_bus_type = {
+ .name = "serial",
+ .match = serdev_device_match,
+ .probe = serdev_drv_probe,
+ .remove = serdev_drv_remove,
++ .shutdown = serdev_drv_shutdown,
+ };
+
+ /**
+diff --git a/include/linux/serdev.h b/include/linux/serdev.h
+index 9f14f9c12ec4..94050561325c 100644
+--- a/include/linux/serdev.h
++++ b/include/linux/serdev.h
+@@ -63,6 +63,7 @@ struct serdev_device_driver {
+ struct device_driver driver;
+ int (*probe)(struct serdev_device *);
+ void (*remove)(struct serdev_device *);
++ void (*shutdown)(struct serdev_device *);
+ };
+
+ static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d)
+--
+GitLab
+
+From 4381cb3400bd61288d2122f3eb74711963885323 Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:14:06 +0200
+Subject: [PATCH] bluetooth: hci_serdev: Clear registered bit on unregister
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ drivers/bluetooth/hci_serdev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
+index ef96ad06fa54..95c723c0ea01 100644
+--- a/drivers/bluetooth/hci_serdev.c
++++ b/drivers/bluetooth/hci_serdev.c
+@@ -395,5 +395,7 @@ void hci_uart_unregister_device(struct hci_uart *hu)
+ clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+ serdev_device_close(hu->serdev);
+ }
++
++ clear_bit(HCI_UART_REGISTERED, &hu->flags);
+ }
+ EXPORT_SYMBOL_GPL(hci_uart_unregister_device);
+--
+GitLab
+
+From 4065c5018d7d4fc7d6ea51056a954f23320688ca Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:15:08 +0200
+Subject: [PATCH] bluetooth: hci_bcm: disable power on shutdown
+
+Firmware behaves wonky when not power cycled over reboots
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ drivers/bluetooth/hci_bcm.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
+index 8ea5ca8d71d6..6d5871992f79 100644
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -1469,6 +1469,23 @@ static void bcm_serdev_remove(struct serdev_device *serdev)
+ hci_uart_unregister_device(&bcmdev->serdev_hu);
+ }
+
++static void bcm_serdev_shutdown(struct serdev_device *serdev)
++{
++ struct bcm_device *bcmdev = serdev_device_get_drvdata(serdev);
++
++/*
++ if (test_bit(HCI_UART_REGISTERED, &bcmdev->hu->flags)) {
++ hci_uart_unregister_device(&bcmdev->serdev_hu);
++ }
++*/
++ dev_info(bcmdev->dev, "Cutting power to bluetooth module\n");
++ if (bcm_gpio_set_power(bcmdev, false)) {
++ dev_err(bcmdev->dev, "Failed to power down\n");
++ }
++ usleep_range(500000, 1000000);
++}
++
++
+ #ifdef CONFIG_OF
+ static struct bcm_device_data bcm4354_device_data = {
+ .no_early_set_baudrate = true,
+@@ -1494,6 +1511,7 @@ MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match);
+ static struct serdev_device_driver bcm_serdev_driver = {
+ .probe = bcm_serdev_probe,
+ .remove = bcm_serdev_remove,
++ .shutdown = bcm_serdev_shutdown,
+ .driver = {
+ .name = "hci_uart_bcm",
+ .of_match_table = of_match_ptr(bcm_bluetooth_of_match),
+--
+GitLab
+
+From f6419edc62979c1e67202b5dc10abd7b22bdedcf Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:16:52 +0200
+Subject: [PATCH] mmc: core: pwrseq_simple: disable mmc power on shutdown
+
+Fix for Broadcom SDIO WiFi modules. They misbehave if reinitialized
+without a power cycle.
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ drivers/mmc/core/pwrseq_simple.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
+index ea4d3670560e..38fe7e29aba6 100644
+--- a/drivers/mmc/core/pwrseq_simple.c
++++ b/drivers/mmc/core/pwrseq_simple.c
+@@ -80,10 +80,8 @@ static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
+ msleep(pwrseq->post_power_on_delay_ms);
+ }
+
+-static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
++static void __mmc_pwrseq_simple_power_off(struct mmc_pwrseq_simple *pwrseq)
+ {
+- struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
+-
+ mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
+
+ if (pwrseq->power_off_delay_us)
+@@ -96,6 +94,12 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
+ }
+ }
+
++static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
++{
++ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
++ __mmc_pwrseq_simple_power_off(pwrseq);
++}
++
+ static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
+ .pre_power_on = mmc_pwrseq_simple_pre_power_on,
+ .post_power_on = mmc_pwrseq_simple_post_power_on,
+@@ -151,9 +155,18 @@ static int mmc_pwrseq_simple_remove(struct platform_device *pdev)
+ return 0;
+ }
+
++static void mmc_pwrseq_simple_shutdown(struct platform_device *pdev)
++{
++ struct mmc_pwrseq_simple *pwrseq = platform_get_drvdata(pdev);
++
++ dev_info(&pdev->dev, "Turning off mmc\n");
++ __mmc_pwrseq_simple_power_off(pwrseq);
++}
++
+ static struct platform_driver mmc_pwrseq_simple_driver = {
+ .probe = mmc_pwrseq_simple_probe,
+ .remove = mmc_pwrseq_simple_remove,
++ .shutdown = mmc_pwrseq_simple_shutdown,
+ .driver = {
+ .name = "pwrseq_simple",
+ .of_match_table = mmc_pwrseq_simple_of_match,
+--
+GitLab
+
+From b0452434e75ecf257bc2ea9a5eb86be68bb56f71 Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:23:54 +0200
+Subject: [PATCH] usb: typec: tcpm: add hacky generic altmode support
+
+This is a hack and it is based on extcon. Do not try to mainline
+unless you are in need for some retroactive abortion by the
+maintainers.
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 139 +++++++++++++++++++++++++++++++++-
+ 1 file changed, 138 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index a6fae1f86505..2908771f4d4e 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -9,6 +9,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/device.h>
+ #include <linux/hrtimer.h>
++#include <linux/extcon-provider.h>
+ #include <linux/jiffies.h>
+ #include <linux/kernel.h>
+ #include <linux/kthread.h>
+@@ -369,6 +370,11 @@ struct tcpm_port {
+ /* Sink caps have been queried */
+ bool sink_cap_done;
+
++#ifdef CONFIG_EXTCON
++ struct extcon_dev *extcon;
++ unsigned int *extcon_cables;
++#endif
++
+ #ifdef CONFIG_DEBUG_FS
+ struct dentry *dentry;
+ struct mutex logbuffer_lock; /* log buffer access lock */
+@@ -654,6 +660,35 @@ static void tcpm_debugfs_exit(const struct tcpm_port *port) { }
+
+ #endif
+
++static void tcpm_update_extcon_data(struct tcpm_port *port, bool attached) {
++#ifdef CONFIG_EXTCON
++ unsigned int *capability = port->extcon_cables;
++ if (port->data_role == TYPEC_HOST) {
++ extcon_set_state(port->extcon, EXTCON_USB, false);
++ extcon_set_state(port->extcon, EXTCON_USB_HOST, attached);
++ } else {
++ extcon_set_state(port->extcon, EXTCON_USB, true);
++ extcon_set_state(port->extcon, EXTCON_USB_HOST, attached);
++ }
++ while (*capability != EXTCON_NONE) {
++ if (attached) {
++ union extcon_property_value val;
++ val.intval = (port->polarity == TYPEC_POLARITY_CC2);
++ extcon_set_property(port->extcon, *capability,
++ EXTCON_PROP_USB_TYPEC_POLARITY, val);
++ } else {
++ extcon_set_state(port->extcon, *capability, false);
++ }
++ extcon_sync(port->extcon, *capability);
++ capability++;
++ }
++ tcpm_log(port, "Extcon update (%s): %s, %s",
++ attached ? "attached" : "detached",
++ port->data_role == TYPEC_HOST ? "host" : "device",
++ port->polarity == TYPEC_POLARITY_CC1 ? "normal" : "flipped");
++#endif
++}
++
+ static int tcpm_pd_transmit(struct tcpm_port *port,
+ enum tcpm_transmit_type type,
+ const struct pd_message *msg)
+@@ -881,6 +916,8 @@ static int tcpm_set_roles(struct tcpm_port *port, bool attached,
+ typec_set_data_role(port->typec_port, data);
+ typec_set_pwr_role(port->typec_port, role);
+
++ tcpm_update_extcon_data(port, attached);
++
+ return 0;
+ }
+
+@@ -1132,7 +1169,7 @@ static void svdm_consume_modes(struct tcpm_port *port, const u32 *p, int cnt)
+ paltmode->mode = i;
+ paltmode->vdo = p[i];
+
+- tcpm_log(port, " Alternate mode %d: SVID 0x%04x, VDO %d: 0x%08x",
++ tcpm_log(port, "Alternate mode %d: SVID 0x%04x, VDO %d: 0x%08x",
+ pmdata->altmodes, paltmode->svid,
+ paltmode->mode, paltmode->vdo);
+
+@@ -1154,6 +1191,9 @@ static void tcpm_register_partner_altmodes(struct tcpm_port *port)
+ modep->altmode_desc[i].svid);
+ altmode = NULL;
+ }
++ else
++ tcpm_log(port, "Registered altmode 0x%04x", modep->altmode_desc[i].svid);
++
+ port->partner_altmode[i] = altmode;
+ }
+ }
+@@ -1249,9 +1289,11 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
+ modep->svid_index++;
+ if (modep->svid_index < modep->nsvids) {
+ u16 svid = modep->svids[modep->svid_index];
++ tcpm_log(port, "More modes available, sending discover");
+ response[0] = VDO(svid, 1, CMD_DISCOVER_MODES);
+ rlen = 1;
+ } else {
++ tcpm_log(port, "Got all patner modes, registering");
+ tcpm_register_partner_altmodes(port);
+ }
+ break;
+@@ -2836,6 +2878,7 @@ static int tcpm_src_attach(struct tcpm_port *port)
+ static void tcpm_typec_disconnect(struct tcpm_port *port)
+ {
+ if (port->connected) {
++ tcpm_update_extcon_data(port, false);
+ typec_unregister_partner(port->partner);
+ port->partner = NULL;
+ port->connected = false;
+@@ -2902,6 +2945,8 @@ static void tcpm_detach(struct tcpm_port *port)
+ }
+
+ tcpm_reset_port(port);
++
++ tcpm_update_extcon_data(port, false);
+ }
+
+ static void tcpm_src_detach(struct tcpm_port *port)
+@@ -4732,6 +4777,64 @@ void tcpm_tcpc_reset(struct tcpm_port *port)
+ }
+ EXPORT_SYMBOL_GPL(tcpm_tcpc_reset);
+
++unsigned int default_supported_cables[] = {
++ EXTCON_NONE
++};
++
++static int tcpm_fw_get_caps_late(struct tcpm_port *port,
++ struct fwnode_handle *fwnode)
++{
++ int ret, i;
++ ret = fwnode_property_count_u32(fwnode, "typec-altmodes");
++ if (ret > 0) {
++ u32 *props;
++ if (ret % 4) {
++ dev_err(port->dev, "Length of typec altmode array must be divisible by 4");
++ return -EINVAL;
++ }
++
++ props = devm_kzalloc(port->dev, sizeof(u32) * ret, GFP_KERNEL);
++ if (!props) {
++ dev_err(port->dev, "Failed to allocate memory for altmode properties");
++ return -ENOMEM;
++ }
++
++ if(fwnode_property_read_u32_array(fwnode, "typec-altmodes", props, ret) < 0) {
++ dev_err(port->dev, "Failed to read altmodes from port");
++ return -EINVAL;
++ }
++
++ i = 0;
++ while (ret > 0 && i < ARRAY_SIZE(port->port_altmode)) {
++ struct typec_altmode *alt;
++ struct typec_altmode_desc alt_desc = {
++ .svid = props[i * 4],
++ .mode = props[i * 4 + 1],
++ .vdo = props[i * 4 + 2],
++ .roles = props[i * 4 + 3],
++ };
++
++
++ tcpm_log(port, "Adding altmode SVID: 0x%04x, mode: %d, vdo: %u, role: %d",
++ alt_desc.svid, alt_desc.mode, alt_desc.vdo, alt_desc.roles);
++ alt = typec_port_register_altmode(port->typec_port,
++ &alt_desc);
++ if (IS_ERR(alt)) {
++ tcpm_log(port,
++ "%s: failed to register port alternate mode 0x%x",
++ dev_name(port->dev), alt_desc.svid);
++ break;
++ }
++ typec_altmode_set_drvdata(alt, port);
++ alt->ops = &tcpm_altmode_ops;
++ port->port_altmode[i] = alt;
++ i++;
++ ret -= 4;
++ }
++ }
++ return 0;
++}
++
+ static int tcpm_fw_get_caps(struct tcpm_port *port,
+ struct fwnode_handle *fwnode)
+ {
+@@ -4742,6 +4845,23 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
+ if (!fwnode)
+ return -EINVAL;
+
++#ifdef CONFIG_EXTCON
++ ret = fwnode_property_count_u32(fwnode, "extcon-cables");
++ if (ret > 0) {
++ port->extcon_cables = devm_kzalloc(port->dev, sizeof(u32) * ret, GFP_KERNEL);
++ if (!port->extcon_cables) {
++ dev_err(port->dev, "Failed to allocate memory for extcon cable types. "\
++ "Using default tyes");
++ goto extcon_default;
++ }
++ fwnode_property_read_u32_array(fwnode, "extcon-cables", port->extcon_cables, ret);
++ } else {
++extcon_default:
++ dev_info(port->dev, "No cable types defined, using default cables");
++ port->extcon_cables = default_supported_cables;
++ }
++#endif
++
+ /* USB data support is optional */
+ ret = fwnode_property_read_string(fwnode, "data-role", &cap_str);
+ if (ret == 0) {
+@@ -5114,6 +5234,17 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
+ goto out_destroy_wq;
+
+ port->try_role = port->typec_caps.prefer_role;
++#ifdef CONFIG_EXTCON
++ port->extcon = devm_extcon_dev_allocate(dev, port->extcon_cables);
++ if (IS_ERR(port->extcon)) {
++ dev_err(dev, "Failed to allocate extcon device: %ld", PTR_ERR(port->extcon));
++ goto out_destroy_wq;
++ }
++ if((err = devm_extcon_dev_register(dev, port->extcon))) {
++ dev_err(dev, "Failed to register extcon device: %d", err);
++ goto out_destroy_wq;
++ }
++#endif
+
+ port->typec_caps.fwnode = tcpc->fwnode;
+ port->typec_caps.revision = 0x0120; /* Type-C spec release 1.2 */
+@@ -5141,6 +5272,12 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
+ goto out_role_sw_put;
+ }
+
++ err = tcpm_fw_get_caps_late(port, tcpc->fwnode);
++ if (err < 0) {
++ dev_err(dev, "Failed to get altmodes from fwnode");
++ goto out_destroy_wq;
++ }
++
+ mutex_lock(&port->lock);
+ tcpm_init(port);
+ mutex_unlock(&port->lock);
+--
+GitLab
+
+From db4e9ffdb985752ae3c3436ff86f8f376ae8fd22 Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:25:32 +0200
+Subject: [PATCH] phy: rockchip: typec: Set extcon capabilities
+
+Do not mainline, hack.
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ drivers/phy/rockchip/phy-rockchip-typec.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
+index 70a31251b202..5385bb4f0bd4 100644
+--- a/drivers/phy/rockchip/phy-rockchip-typec.c
++++ b/drivers/phy/rockchip/phy-rockchip-typec.c
+@@ -40,6 +40,7 @@
+ #include <linux/clk-provider.h>
+ #include <linux/delay.h>
+ #include <linux/extcon.h>
++#include <linux/extcon-provider.h>
+ #include <linux/io.h>
+ #include <linux/iopoll.h>
+ #include <linux/kernel.h>
+@@ -1160,6 +1161,22 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
+ dev_err(dev, "Invalid or missing extcon\n");
+ return PTR_ERR(tcphy->extcon);
+ }
++ } else {
++ extcon_set_property_capability(tcphy->extcon, EXTCON_USB,
++ EXTCON_PROP_USB_SS);
++ extcon_set_property_capability(tcphy->extcon, EXTCON_USB_HOST,
++ EXTCON_PROP_USB_SS);
++ extcon_set_property_capability(tcphy->extcon, EXTCON_DISP_DP,
++ EXTCON_PROP_USB_SS);
++ extcon_set_property_capability(tcphy->extcon, EXTCON_USB,
++ EXTCON_PROP_USB_TYPEC_POLARITY);
++ extcon_set_property_capability(tcphy->extcon, EXTCON_USB_HOST,
++ EXTCON_PROP_USB_TYPEC_POLARITY);
++ extcon_set_property_capability(tcphy->extcon, EXTCON_DISP_DP,
++ EXTCON_PROP_USB_TYPEC_POLARITY);
++ extcon_sync(tcphy->extcon, EXTCON_USB);
++ extcon_sync(tcphy->extcon, EXTCON_USB_HOST);
++ extcon_sync(tcphy->extcon, EXTCON_DISP_DP);
+ }
+
+ pm_runtime_enable(dev);
+--
+GitLab
+
+From fd739ae47f9ea780a1e161a478e241df06eaff7e Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:26:27 +0200
+Subject: [PATCH] usb: typec: altmodes: displayport: Add hacky, generic altmode
+ detection
+
+Do not mainline, hack.
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ drivers/usb/typec/altmodes/displayport.c | 55 ++++++++++++++++++++++--
+ 1 file changed, 52 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c
+index e62e5e3da01e..a3d03db476aa 100644
+--- a/drivers/usb/typec/altmodes/displayport.c
++++ b/drivers/usb/typec/altmodes/displayport.c
+@@ -9,6 +9,8 @@
+ */
+
+ #include <linux/delay.h>
++#include <linux/extcon.h>
++#include <linux/extcon-provider.h>
+ #include <linux/mutex.h>
+ #include <linux/module.h>
+ #include <linux/usb/pd_vdo.h>
+@@ -135,15 +137,53 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
+ return ret;
+ }
+
++static void dp_altmode_update_extcon(struct dp_altmode *dp, bool disconnect) {
++ const struct device *dev = &dp->port->dev;
++ struct extcon_dev* edev = NULL;
++
++ while (dev) {
++ edev = extcon_find_edev_by_node(dev->of_node);
++ if(!IS_ERR(edev)) {
++ break;
++ }
++ dev = dev->parent;
++ }
++
++ if (IS_ERR_OR_NULL(edev)) {
++ return;
++ }
++
++ if (disconnect || !dp->data.conf) {
++ extcon_set_state_sync(edev, EXTCON_DISP_DP, false);
++ } else {
++ union extcon_property_value extcon_true = { .intval = true };
++ extcon_set_state(edev, EXTCON_DISP_DP, true);
++ if (DP_CONF_GET_PIN_ASSIGN(dp->data.conf) & DP_PIN_ASSIGN_MULTI_FUNC_MASK) {
++ extcon_set_state_sync(edev, EXTCON_USB_HOST, true);
++ extcon_set_property(edev, EXTCON_DISP_DP, EXTCON_PROP_USB_SS,
++ extcon_true);
++ } else {
++ extcon_set_state_sync(edev, EXTCON_USB_HOST, false);
++ }
++ extcon_sync(edev, EXTCON_DISP_DP);
++ extcon_set_state_sync(edev, EXTCON_USB, false);
++ }
++
++}
++
+ static int dp_altmode_configured(struct dp_altmode *dp)
+ {
+ int ret;
+
+ sysfs_notify(&dp->alt->dev.kobj, "displayport", "configuration");
+
+- if (!dp->data.conf)
++ if (!dp->data.conf) {
++ dp_altmode_update_extcon(dp, true);
+ return typec_altmode_notify(dp->alt, TYPEC_STATE_USB,
+ &dp->data);
++ }
++
++ dp_altmode_update_extcon(dp, false);
+
+ ret = dp_altmode_notify(dp);
+ if (ret)
+@@ -170,9 +210,11 @@ static int dp_altmode_configure_vdm(struct dp_altmode *dp, u32 conf)
+ if (ret) {
+ if (DP_CONF_GET_PIN_ASSIGN(dp->data.conf))
+ dp_altmode_notify(dp);
+- else
++ else {
++ dp_altmode_update_extcon(dp, true);
+ typec_altmode_notify(dp->alt, TYPEC_STATE_USB,
+ &dp->data);
++ }
+ }
+
+ return ret;
+@@ -211,6 +253,8 @@ static void dp_altmode_work(struct work_struct *work)
+ case DP_STATE_EXIT:
+ if (typec_altmode_exit(dp->alt))
+ dev_err(&dp->alt->dev, "Exit Mode Failed!\n");
++ else
++ dp_altmode_update_extcon(dp, true);
+ break;
+ default:
+ break;
+@@ -521,8 +565,13 @@ int dp_altmode_probe(struct typec_altmode *alt)
+ if (!(DP_CAP_DFP_D_PIN_ASSIGN(port->vdo) &
+ DP_CAP_UFP_D_PIN_ASSIGN(alt->vdo)) &&
+ !(DP_CAP_UFP_D_PIN_ASSIGN(port->vdo) &
+- DP_CAP_DFP_D_PIN_ASSIGN(alt->vdo)))
++ DP_CAP_DFP_D_PIN_ASSIGN(alt->vdo))) {
++ dev_err(&alt->dev, "No compatible pin configuration found:"\
++ "%04lx -> %04lx, %04lx <- %04lx",
++ DP_CAP_DFP_D_PIN_ASSIGN(port->vdo), DP_CAP_UFP_D_PIN_ASSIGN(alt->vdo),
++ DP_CAP_UFP_D_PIN_ASSIGN(port->vdo), DP_CAP_DFP_D_PIN_ASSIGN(alt->vdo));
+ return -ENODEV;
++ }
+
+ ret = sysfs_create_group(&alt->dev.kobj, &dp_altmode_group);
+ if (ret)
+--
+GitLab
+
+From e9d07cf5d983a3b941e604ae4ba9d277929e0650 Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:34:47 +0200
+Subject: [PATCH] sound: soc: codecs: es8316: Run micdetect only if jack status
+ asserted
+
+Think this is (was?) required to prevent flapping of detection status on
+the PBP.
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ sound/soc/codecs/es8316.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
+index bd5d230c5df2..a2d8bf620b6f 100644
+--- a/sound/soc/codecs/es8316.c
++++ b/sound/soc/codecs/es8316.c
+@@ -688,7 +688,7 @@ static void es8316_disable_jack_detect(struct snd_soc_component *component)
+ snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
+ ES8316_GPIO_ENABLE_INTERRUPT, 0);
+
+- if (es8316->jack->status & SND_JACK_MICROPHONE) {
++ if (es8316->jack && (es8316->jack->status & SND_JACK_MICROPHONE)) {
+ es8316_disable_micbias_for_mic_gnd_short_detect(component);
+ snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
+ }
+--
+GitLab
+
+From edbf5d93dbd845faa4aa74fb8a7c5e76cf35ef0d Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:36:47 +0200
+Subject: [PATCH] ASoC: soc-jack.c: supported inverted jack detect GPIOs
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ sound/soc/soc-jack.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
+index 0f1820f36b4d..8d9d77814f33 100644
+--- a/sound/soc/soc-jack.c
++++ b/sound/soc/soc-jack.c
+@@ -216,8 +216,6 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
+ int report;
+
+ enable = gpiod_get_value_cansleep(gpio->desc);
+- if (gpio->invert)
+- enable = !enable;
+
+ if (enable)
+ report = gpio->report;
+@@ -346,6 +344,9 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
+ goto undo;
+ }
+ } else {
++ int flags = GPIOF_IN;
++ if (gpios[i].invert)
++ flags |= GPIOF_ACTIVE_LOW;
+ /* legacy GPIO number */
+ if (!gpio_is_valid(gpios[i].gpio)) {
+ dev_err(jack->card->dev,
+@@ -355,7 +356,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
+ goto undo;
+ }
+
+- ret = gpio_request_one(gpios[i].gpio, GPIOF_IN,
++ ret = gpio_request_one(gpios[i].gpio, flags,
+ gpios[i].name);
+ if (ret)
+ goto undo;
+--
+GitLab
+
+From 43756ac8a7e63935843e95471a9557677cedcbe0 Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:43:27 +0200
+Subject: [PATCH] arm64: dts: rockchip: add oficially unsupported 2GHz opp
+
+No mainlining here.
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+index 667eeeb019de..decb212e2dca 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+@@ -392,6 +392,13 @@ mains_charger: dc-charger {
+ };
+ };
+
++&cluster1_opp {
++ opp08 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <1250000>;
++ };
++};
++
+ &cdn_dp {
+ status = "okay";
+ };
+--
+GitLab
+
+From 948d7ade0ddcf292b91d91cb8b6819a19ab3f604 Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Thu, 28 May 2020 14:44:15 +0200
+Subject: [PATCH] arm64: dts: rockchip: add typec extcon hack
+
+Not for mainline
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+index decb212e2dca..37f967a89401 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+@@ -401,6 +401,7 @@ opp08 {
+
+ &cdn_dp {
+ status = "okay";
++ extcon = <&fusb0>;
+ };
+
+ &cpu_b0 {
+@@ -735,6 +736,9 @@ connector {
+ <PDO_FIXED(5000, 1400, PDO_FIXED_USB_COMM)>;
+ try-power-role = "sink";
+
++ extcon-cables = <1 2 5 6 9 10 12 44>;
++ typec-altmodes = <0xff01 1 0x001c0000 1>;
++
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -1002,6 +1006,7 @@ spiflash: flash at 0 {
+ };
+
+ &tcphy0 {
++ extcon = <&fusb0>;
+ status = "okay";
+ };
+
+--
+GitLab
+
+From a8f3e4ffe533f952a468cb8f3d067865bd58144f Mon Sep 17 00:00:00 2001
+From: Tobias Schramm <t.schramm at manjaro.org>
+Date: Sat, 6 Jun 2020 23:45:10 +0200
+Subject: [PATCH] arm64: dts: rockchip: setup USB type c port as dual data role
+
+Some chargers try to put the charged device into device data role.
+Before this commit this condition caused the tcpm state machine to
+issue a hard reset due to a capability missmatch.
+
+Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+index c505c88b5d9b..d77dca5524ff 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+@@ -726,7 +726,7 @@ fusb0: fusb30x at 22 {
+
+ connector {
+ compatible = "usb-c-connector";
+- data-role = "host";
++ data-role = "dual";
+ label = "USB-C";
+ op-sink-microwatt = <1000000>;
+ power-role = "dual";
+--
+GitLab
+
diff --git a/kernel-rk3399-afbc-ytr.patch b/kernel-rk3399-afbc-ytr.patch
new file mode 100644
index 00000000..101eedfc
--- /dev/null
+++ b/kernel-rk3399-afbc-ytr.patch
@@ -0,0 +1,50 @@
+The AFBC decoder used in the Rockchip VOP assumes the use of the
+YUV-like colourspace transform (YTR). YTR is lossless for RGB(A)
+buffers, which covers the RGBA8 and RGB565 formats supported in
+vop_convert_afbc_format. Use of YTR is signaled with the
+AFBC_FORMAT_MOD_YTR modifier, which prior to this commit was missing. As
+such, a producer would have to generate buffers that do not use YTR,
+which the VOP would erroneously decode as YTR, leading to severe visual
+corruption.
+
+The upstream AFBC support was developed against a captured frame, which
+failed to exercise modifier support. Prior to bring-up of AFBC in Mesa
+(in the Panfrost driver), no open userspace respected modifier
+reporting. As such, this change is not expected to affect broken
+userspaces.
+
+Tested on RK3399 with Panfrost and Weston.
+
+Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+index 4a2099cb5..857d97cdc 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+@@ -17,9 +17,20 @@
+
+ #define NUM_YUV2YUV_COEFFICIENTS 12
+
++/* AFBC supports a number of configurable modes. Relevant to us is block size
++ * (16x16 or 32x8), storage modifiers (SPARSE, SPLIT), and the YUV-like
++ * colourspace transform (YTR). 16x16 SPARSE mode is always used. SPLIT mode
++ * could be enabled via the hreg_block_split register, but is not currently
++ * handled. The colourspace transform is implicitly always assumed by the
++ * decoder, so consumers must use this transform as well.
++ *
++ * Failure to match modifiers will cause errors displaying AFBC buffers
++ * produced by conformant AFBC producers, including Mesa.
++ */
+ #define ROCKCHIP_AFBC_MOD \
+ DRM_FORMAT_MOD_ARM_AFBC( \
+ AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE \
++ | AFBC_FORMAT_MOD_YTR \
+ )
+
+ enum vop_data_format {
+--
+2.28.0
+
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/kernel.git/commitdiff/8c9054aff253529737edf2127a16afcfcf45b0a8
More information about the pld-cvs-commit
mailing list