From 4ebddb8c853fc5dd1e6dc7662f7de4dec5e699ba Mon Sep 17 00:00:00 2001 From: LiuDiMing Lin Date: Wed, 26 Feb 2025 14:52:51 +0800 Subject: [PATCH 01/11] iio: imu: inv_icm42670: use gpiod_to_irq to get interrupts instead Change-Id: I968b7f0186d0ad3bbe926a47dbed2f173d6538ce Signed-off-by: LiuDiMing Lin --- drivers/iio/imu/inv_icm42670/inv_icm42670.h | 2 +- .../iio/imu/inv_icm42670/inv_icm42670_core.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/iio/imu/inv_icm42670/inv_icm42670.h b/drivers/iio/imu/inv_icm42670/inv_icm42670.h index d7c863f71cbf..3dc9d042455b 100644 --- a/drivers/iio/imu/inv_icm42670/inv_icm42670.h +++ b/drivers/iio/imu/inv_icm42670/inv_icm42670.h @@ -520,7 +520,7 @@ struct icm42670_data { struct regmap *regmap; struct iio_trigger *trig; struct device_node *node; - int int1_gpio; + struct gpio_desc *int1_gpiod; struct regulator *vdd_supply; struct regulator *vddio_supply; u16 accel_frequency; diff --git a/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c b/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c index 8b249c10a7e8..5bb09a83139b 100644 --- a/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c +++ b/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c @@ -1092,10 +1092,6 @@ static int icm42670_chip_init(struct icm42670_data *data, icm42670_bus_setup bus dev_err(dev, "reset done status bit missing (%0x)\n", regval); return -ENODEV; } - // Configure the INT1 GPIO as input - ret = gpio_direction_input(data->int1_gpio); - if (ret < 0) - dev_err(dev, "gpio_direction_input failed!\r\n"); /* set chip bus configuration */ ret = bus_setup(data); @@ -1224,11 +1220,16 @@ int icm42670_core_probe(struct regmap *regmap, if (data->node == NULL) dev_err(dev, "ic2 node not find!\n"); - data->int1_gpio = of_get_named_gpio(data->node, "int1-gpio", 0); - if (data->int1_gpio < 0) { - dev_err(dev, "Could not get int1_gpio!\n"); - return -EINVAL; - } + data->int1_gpiod = devm_gpiod_get(dev, "int1", GPIOD_IN); + if (IS_ERR(data->int1_gpiod)) + return dev_err_probe(dev, PTR_ERR(data->int1_gpiod), "Could not get int1 gpio\n"); + + /* Get the same result through gpiod_to_irq to ensure that + * the affinity can be restored after CPU off/on + */ + irq = gpiod_to_irq(data->int1_gpiod); + if (irq < 0) + return dev_err_probe(dev, irq, "Could not get IRQ from GPIO\n"); data->enable_fifo = of_property_read_bool(data->node, "enable-fifo"); if (true != data->enable_fifo) From 76976b1b61967f73e7a2bfbb6386d2eca28ead0d Mon Sep 17 00:00:00 2001 From: LiuDiMing Lin Date: Thu, 13 Feb 2025 14:35:53 +0800 Subject: [PATCH 02/11] iio: imu: inv_icm42670: fix suspend/resume handling This ensures all device settings are properly preserved across suspend/resume cycles and improves error handling robustness. Change-Id: I7624236c67b8cfb8ef7f7dcb15b3fa49dd9b16a2 Signed-off-by: LiuDiMing Lin --- .../iio/imu/inv_icm42670/inv_icm42670_core.c | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c b/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c index 5bb09a83139b..d181f328046c 100644 --- a/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c +++ b/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c @@ -528,11 +528,10 @@ static int icm42670_gyro_off(struct icm42670_data *data) return ret; cmd &= (~(BIT_PWR_MGMT0_GYRO(INV_ICM42670_SENSOR_MODE_LOW_NOISE))); // Gyro off - msleep(80); ret = regmap_write(data->regmap, REG_PWR_MGMT_0, cmd); if (ret < 0) return ret; - msleep(200); + usleep_range(200, 201); return ret; } @@ -1339,14 +1338,13 @@ EXPORT_SYMBOL_GPL(icm42670_core_probe); */ static int __maybe_unused sleep_icm42670_resume(struct device *dev) { - int ret; - struct icm42670_data *st = iio_priv(dev_get_drvdata(dev)); + int ret = 0; + struct icm42670_data *st = iio_priv(dev_get_drvdata(dev)); struct iio_dev *indio_dev = dev_get_drvdata(dev); mutex_lock(&st->lock); - ret = regulator_enable(st->vdd_supply); - if (ret) + if (!pm_runtime_suspended(dev)) goto out_unlock; usleep_range(3000, 4000); @@ -1361,10 +1359,7 @@ static int __maybe_unused sleep_icm42670_resume(struct device *dev) icm42670_set_lpf_bw(st, ICM42670_GYRO, st->gyro_lpf_bw_buff); ret = icm42670_set_enable(indio_dev, 1); - if (ret) - goto out_unlock; - devm_regulator_put(st->vdd_supply); out_unlock: mutex_unlock(&st->lock); return ret; @@ -1376,28 +1371,21 @@ out_unlock: */ static int __maybe_unused sleep_icm42670_suspend(struct device *dev) { - struct icm42670_data *st = iio_priv(dev_get_drvdata(dev)); + struct icm42670_data *st = iio_priv(dev_get_drvdata(dev)); struct iio_dev *indio_dev = dev_get_drvdata(dev); - int ret; + int ret = 0; mutex_lock(&st->lock); + if (pm_runtime_suspended(dev)) + goto out_unlock; + st->gyro_frequency_buff = st->gyro_frequency; st->accel_frequency_buff = st->accel_frequency; st->accel_lpf_bw_buff = st->accel_lpf_bw; st->gyro_lpf_bw_buff = st->gyro_lpf_bw; - if (pm_runtime_suspended(dev)) { - ret = 0; - goto out_unlock; - } - ret = icm42670_set_enable(indio_dev, 0); - if (ret) - goto out_unlock; - - regulator_disable(st->vdd_supply); - devm_regulator_put(st->vdd_supply); out_unlock: mutex_unlock(&st->lock); From 173ce59ad2e3af271f80d562ec8a50ed6d00aee2 Mon Sep 17 00:00:00 2001 From: Shengfei Xu Date: Thu, 6 Mar 2025 11:14:46 +0800 Subject: [PATCH 03/11] power: supply: rockchip-charger-manager: Supports charging via docking station Supports charging via docking station, but connected devices will undergo a power cycle (temporary power loss followed by reconnection) when the charger is unplugged from the docking station. Change-Id: Ia24f1dc976f73cebb1758e069a4c49131d7a85f3 Signed-off-by: Shengfei Xu --- .../power/supply/rockchip_charger_manager.c | 141 ++++++++++++++++-- 1 file changed, 130 insertions(+), 11 deletions(-) diff --git a/drivers/power/supply/rockchip_charger_manager.c b/drivers/power/supply/rockchip_charger_manager.c index a8d2da300dcf..f7b1a4ef8c6c 100644 --- a/drivers/power/supply/rockchip_charger_manager.c +++ b/drivers/power/supply/rockchip_charger_manager.c @@ -328,6 +328,7 @@ struct charger_manager { struct delayed_work cm_monitor_work; /* init at driver add */ struct delayed_work cm_jeita_work; /* init at driver add */ struct delayed_work dc_work; + struct work_struct pd_work; /* The state of charger cable */ bool attached; @@ -340,6 +341,7 @@ struct charger_manager { /* The rockchip-charger-manager use Extcon framework */ struct work_struct wq; struct notifier_block nb; + struct notifier_block pd_nb; struct chargepump_info cp; struct fuel_gauge_info fg_info; @@ -350,6 +352,9 @@ struct charger_manager { int is_fast_charge; int is_charge; + bool is_normal_charge; + bool is_pd_charge; + bool is_pps_charge; unsigned long next_polling; u64 charging_start_time; @@ -695,6 +700,7 @@ static int set_sw_charger_input_limit_current(struct charger_manager *cm, return ret; } + cm->fc_config->sw_input_current = input_current_ua; cm->fc_config->ibus_dcdc_lmt = input_current_ua; return 0; } @@ -2302,6 +2308,7 @@ static int cm_pd_adapter_det(struct charger_manager *cm) fc_config = cm->fc_config; cm->is_fast_charge = 1; + cm->is_pd_charge = true; CM_DBG("POWER_SUPPLY_USB_TYPE_PD\n"); fc_config->charge_type = CHARGE_TYPE_PD; ret = power_supply_get_property(desc->tcpm_psy, @@ -2335,12 +2342,15 @@ static int cm_pps_adapter_det(struct charger_manager *cm) fc_config = cm->fc_config; cm->is_fast_charge = 1; + cm->is_pps_charge = true; CM_DBG("POWER_SUPPLY_USB_TYPE_PD_PPS\n"); if (desc->psy_charger_pump_stat != NULL) { #if defined(CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP) fc_config->charge_type = CHARGE_TYPE_PPS; CM_DBG("charge_type: %d, %d\n", cm->fc_config->charge_type, __LINE__); cm_charge_pump_move_state(cm, PPS_PM_STATE_ENTRY); + if (cm->fc_config->jeita_charge_support) + cancel_delayed_work(&cm->cm_jeita_work); /* * Setup work for controlling charger * according to charger cable. @@ -2399,6 +2409,10 @@ static int cm_normal_adapter_det(struct charger_manager *cm) fc_config = cm->fc_config; fc_config->adaper_power_init_flag = 0; + cm->is_normal_charge = false; + cm->is_fast_charge = false; + cm->is_pps_charge = false; + ret = power_supply_get_property(desc->tcpm_psy, POWER_SUPPLY_PROP_CURRENT_MAX, &val); @@ -2548,21 +2562,27 @@ static int charger_extcon_notifier(struct notifier_block *self, } switch (val.intval) { case POWER_SUPPLY_USB_TYPE_PD: - ret = cm_pd_adapter_det(cm); - CM_DBG("USB-TYPE: POWER_SUPPLY_USB_TYPE_PD\n"); - if (ret) - return NOTIFY_BAD; + if (!cm->is_pps_charge && !cm->is_pd_charge) { + ret = cm_pd_adapter_det(cm); + CM_DBG("USB-TYPE: POWER_SUPPLY_USB_TYPE_PD\n"); + if (ret) + return NOTIFY_BAD; + } break; case POWER_SUPPLY_USB_TYPE_PD_PPS: - ret = cm_pps_adapter_det(cm); - if (ret) - return NOTIFY_BAD; - CM_DBG("USB-TYPE: POWER_SUPPLY_USB_TYPE_PD\n"); + if (!cm->is_pps_charge) { + ret = cm_pps_adapter_det(cm); + if (ret) + return NOTIFY_BAD; + CM_DBG("USB-TYPE: POWER_SUPPLY_USB_TYPE_PD\n"); + } break; default: - ret = cm_normal_adapter_det(cm); - if (ret) - return NOTIFY_BAD; + if (!cm->is_pps_charge && !cm->is_pd_charge && !cm->is_normal_charge) { + ret = cm_normal_adapter_det(cm); + if (ret) + return NOTIFY_BAD; + } break; } @@ -2579,6 +2599,94 @@ static int charger_extcon_notifier(struct notifier_block *self, return NOTIFY_DONE; } +static void cm_pd_work(struct work_struct *work) +{ + struct charger_manager *cm = container_of(work, + struct charger_manager, + pd_work); + struct fastcharge_config *fc_config = cm->fc_config; + struct charger_desc *desc = cm->desc; + union power_supply_propval prop; + int usb_type, online; + int ret; + + ret = power_supply_get_property(cm->desc->tcpm_psy, + POWER_SUPPLY_PROP_USB_TYPE, &prop); + if (ret != 0) { + dev_err(cm->dev, "[%d] failed to get POWER_SUPPLY_PROP_ONLINE\n", __LINE__); + return; + } + usb_type = prop.intval; + + ret = power_supply_get_property(cm->desc->tcpm_psy, + POWER_SUPPLY_PROP_ONLINE, &prop); + if (ret != 0) { + dev_err(cm->dev, "[%d] failed to get POWER_SUPPLY_PROP_ONLINE\n", __LINE__); + return; + } + online = prop.intval; + + if (online) { + cm->attached = 1; + switch (usb_type) { + case POWER_SUPPLY_USB_TYPE_PD_PPS: + CM_DBG("POWER_SUPPLY_USB_TYPE_PD_PPS\n"); + if (!cm->is_pps_charge) + cm_pps_adapter_det(cm); + break; + case POWER_SUPPLY_USB_TYPE_PD: + CM_DBG("POWER_SUPPLY_USB_TYPE_PD\n"); + power_supply_get_property(desc->tcpm_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, + &prop); + if ((!cm->is_pps_charge && !cm->is_pd_charge) || + (prop.intval != fc_config->sw_input_current)) + cm_pd_adapter_det(cm); + break; + case POWER_SUPPLY_USB_TYPE_C: + CM_DBG("POWER_SUPPLY_USB_TYPE_C\n"); + if (!cm->is_pps_charge && !cm->is_pd_charge && !cm->is_normal_charge) + cm_normal_adapter_det(cm); + break; + default: + cm_normal_adapter_det(cm); + } + } +} + +static int cm_pd_notifier_call(struct notifier_block *self, + unsigned long event, + void *ptr) +{ + struct charger_manager *cm = + container_of(self, struct charger_manager, pd_nb); + struct power_supply *psy = ptr; + + if (event != PSY_EVENT_PROP_CHANGED) + return NOTIFY_OK; + + if (psy->of_node != cm->desc->tcpm_psy->of_node) + return NOTIFY_OK; + + queue_work(cm->cm_wq, &cm->pd_work); + + return NOTIFY_OK; +} + +static int cm_pd_init(struct charger_manager *cm) +{ + int ret; + + cm->pd_nb.notifier_call = cm_pd_notifier_call; + ret = power_supply_reg_notifier(&cm->pd_nb); + if (ret) { + dev_err(cm->dev, "failed to power supply reg notifier\n"); + return ret; + } + + return 0; +} + static void cm_disable_charge(struct charger_manager *cm) { #if defined(CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP) @@ -2988,6 +3096,7 @@ static int charger_manager_probe(struct platform_device *pdev) if (cm->desc->support_dc_charger) INIT_DELAYED_WORK(&cm->dc_work, cm_dc_det_work); + INIT_WORK(&cm->pd_work, cm_pd_work); /* Register extcon device for charger cable */ ret = charger_extcon_init(cm); @@ -2995,6 +3104,11 @@ static int charger_manager_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Cannot initialize extcon device\n"); goto err_reg_extcon; } + ret = cm_pd_init(cm); + if (ret < 0) { + dev_err(&pdev->dev, "Cannot initialize pd device\n"); + goto err_reg_extcon; + } cm_dc_init(cm); chg_en_create_device_node(&pdev->dev); @@ -3002,6 +3116,7 @@ static int charger_manager_probe(struct platform_device *pdev) CM_DBG("charger manager ok!!!"); return 0; err_reg_extcon: + destroy_workqueue(cm->cm_wq); return ret; } @@ -3035,12 +3150,14 @@ static int charger_manager_remove(struct platform_device *pdev) { struct charger_manager *cm = platform_get_drvdata(pdev); + power_supply_unreg_notifier(&cm->pd_nb); #if defined(CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP) cancel_delayed_work_sync(&cm->cm_monitor_work); #endif cancel_delayed_work_sync(&cm->cm_jeita_work); if (cm->desc->support_dc_charger) cancel_delayed_work_sync(&cm->dc_work); + destroy_workqueue(cm->cm_wq); return 0; } @@ -3052,11 +3169,13 @@ static void charger_manager_shutdown(struct platform_device *pdev) union power_supply_propval val; int ret; + power_supply_unreg_notifier(&cm->pd_nb); cancel_delayed_work_sync(&cm->cm_monitor_work); #endif cancel_delayed_work_sync(&cm->cm_jeita_work); if (cm->desc->support_dc_charger) cancel_delayed_work_sync(&cm->dc_work); + destroy_workqueue(cm->cm_wq); CM_DBG("charger manager shutdown\n"); #if defined(CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP) From 4b02d79b0b83eb1ba0ad42f589fd14896c1346a3 Mon Sep 17 00:00:00 2001 From: Yu Zheng Date: Tue, 17 Dec 2024 10:30:09 +0800 Subject: [PATCH 04/11] arm64: configs: add rk3576_dv.config Change-Id: Ifea1f89560e412427a3afe9761f5cbffba0d31d9 Signed-off-by: Yu Zheng --- arch/arm64/configs/rk3576_dv.config | 137 ++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 arch/arm64/configs/rk3576_dv.config diff --git a/arch/arm64/configs/rk3576_dv.config b/arch/arm64/configs/rk3576_dv.config new file mode 100644 index 000000000000..b4cab4225950 --- /dev/null +++ b/arch/arm64/configs/rk3576_dv.config @@ -0,0 +1,137 @@ +# CONFIG_ATA is not set +CONFIG_AX88796B_PHY=y +CONFIG_BATTERY_CW221X=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BT is not set +# CONFIG_CAN is not set +# CONFIG_CGROUPS is not set +CONFIG_CHARGER_SC89601=y +# CONFIG_CPU_PX30 is not set +# CONFIG_CPU_RK1808 is not set +# CONFIG_CPU_RK3328 is not set +# CONFIG_CPU_RK3399 is not set +# CONFIG_CPU_RK3528 is not set +# CONFIG_CPU_RK3562 is not set +# CONFIG_CPU_RK3568 is not set +# CONFIG_CPU_RK3588 is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_DEBUG_MISC is not set +# CONFIG_DTC_SYMBOLS is not set +# CONFIG_DVB_DYNAMIC_MINORS is not set +# CONFIG_DVB_NET is not set +# CONFIG_ETHERNET is not set +CONFIG_EXFAT_FS=y +# CONFIG_EXT4_FS is not set +CONFIG_FAT_DEFAULT_IOCHARSET="cp936" +# CONFIG_FTRACE is not set +# CONFIG_I3C is not set +# CONFIG_IKCONFIG is not set +CONFIG_INV_ICM42670_SPI=y +# CONFIG_ISO9660_FS is not set +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MEDIA_USB_SUPPORT is not set +# CONFIG_MOTORCOMM_PHY is not set +# CONFIG_MTD_OF_PARTS is not set +# CONFIG_MTD_SPI_NAND_ATO is not set +# CONFIG_MTD_SPI_NAND_BIWIN is not set +# CONFIG_MTD_SPI_NAND_DEVICE_AUTOSELECT is not set +# CONFIG_MTD_SPI_NAND_DOSILICON is not set +# CONFIG_MTD_SPI_NAND_ESMT is not set +# CONFIG_MTD_SPI_NAND_ETRON is not set +# CONFIG_MTD_SPI_NAND_FORESEE is not set +# CONFIG_MTD_SPI_NAND_GSTO is not set +# CONFIG_MTD_SPI_NAND_HIKSEMI is not set +# CONFIG_MTD_SPI_NAND_HYF is not set +# CONFIG_MTD_SPI_NAND_JSC is not set +# CONFIG_MTD_SPI_NAND_MACRONIX is not set +# CONFIG_MTD_SPI_NAND_MICRON is not set +# CONFIG_MTD_SPI_NAND_PARAGON is not set +# CONFIG_MTD_SPI_NAND_SILICONGO is not set +# CONFIG_MTD_SPI_NAND_SKYHIGH is not set +# CONFIG_MTD_SPI_NAND_TOSHIBA is not set +# CONFIG_MTD_SPI_NAND_UNIM is not set +# CONFIG_MTD_SPI_NAND_WINBOND is not set +# CONFIG_MTD_SPI_NAND_XINCUN is not set +# CONFIG_MTD_SPI_NAND_XTX is not set +# CONFIG_MTD_SPI_NAND_ZBIT is not set +# CONFIG_MTD_SPI_NOR is not set +CONFIG_MTD_UBI_BLOCK=y +# CONFIG_NAMESPACES is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_PCI is not set +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12 +# CONFIG_PROFILING is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_RELAY is not set +# CONFIG_RK630_PHY is not set +CONFIG_ROCKCHIP_CHARGER_MANAGER=y +# CONFIG_ROCKCHIP_PHY is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SLUB_DEBUG is not set +CONFIG_SND_ALOOP=y +CONFIG_SND_SOC_RK730=y +# CONFIG_STACKTRACE is not set +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_USBNET=y +# CONFIG_VHOST_MENU is not set +CONFIG_VIDEO_IMX386=y +# CONFIG_VIDEO_LT6911UXC is not set +# CONFIG_VIDEO_LT6911UXE is not set +# CONFIG_VIDEO_LT7911D is not set +# CONFIG_VIDEO_OS04A10 is not set +# CONFIG_VIDEO_OV4689 is not set +# CONFIG_VIDEO_OV50C40 is not set +# CONFIG_VIDEO_OV5695 is not set +# CONFIG_VIDEO_OV7251 is not set +# CONFIG_VIDEO_RK_IRCUT is not set +# CONFIG_VIDEO_SC4336 is not set +# CONFIG_VIRTIO_MENU is not set +# CONFIG_XFS_FS is not set +CONFIG_EXFAT_DEFAULT_IOCHARSET="cp936" +CONFIG_INV_ICM42670=y +CONFIG_NO_IOPORT_MAP=y +CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP=y +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +CONFIG_USB_ARMLINUX=y +CONFIG_USB_BELKIN=y +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_KC2190 is not set +# CONFIG_USB_NET_AQC111 is not set +CONFIG_USB_NET_AX88179_178A=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_MBIM is not set +CONFIG_USB_NET_CDC_NCM=y +CONFIG_USB_NET_CDC_SUBSET=y +CONFIG_USB_NET_CDC_SUBSET_ENABLE=y +# CONFIG_USB_NET_CH9200 is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_NET1080=y +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +CONFIG_USB_NET_ZAURUS=y +CONFIG_USB_RTL8153_ECM=y +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set From 0a07eff3f1d5629ec6899f487706a06692b9186e Mon Sep 17 00:00:00 2001 From: LiuDiMing Lin Date: Sat, 25 Jan 2025 11:06:41 +0800 Subject: [PATCH 05/11] arm64: dts: rockchip: add rk3576 evb1 v10 dv dts Change-Id: I01fa42fc175fba9f51b577f35de0bf42dcb63c94 Signed-off-by: LiuDiMing Lin --- arch/arm64/boot/dts/rockchip/Makefile | 1 + .../boot/dts/rockchip/rk3576-evb1-v10-dv.dts | 871 ++++++++++++++++++ 2 files changed, 872 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-dv.dts diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 358b28f4f38b..db50efcd7c95 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -251,6 +251,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-ebook-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-ebook-x3-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-android9.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-dv.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-edp-NV140QUM-N61.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-hdmi2dp.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-image-reverse-demo.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-dv.dts b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-dv.dts new file mode 100644 index 000000000000..c64a5fefe615 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-dv.dts @@ -0,0 +1,871 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + * + */ + +/dts-v1/; +#include +#include "rk3576s.dtsi" +#include "rk3576s-evb1.dtsi" +#include "rk3576-linux.dtsi" + +/ { + model = "Rockchip RK3576 EVB1 V10 DV Board"; + compatible = "rockchip,rk3576-evb1-v10-dv", "rockchip,rk3576"; + /delete-node/ vbus5v0-typec; + /delete-node/ vcc-mipicsi0-regulator; + /delete-node/ vcc-mipicsi1-regulator; + + bat: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <8000000>; + precharge-current-microamp = <180000>; + precharge-upper-limit-microvolt = <3600000>; + charge-term-current-microamp = <300000>; + constant-charge-current-max-microamp = <10000000>; + constant-charge-voltage-max-microvolt = <4350000>; + factory-internal-resistance-micro-ohms = <80>; + voltage-max-design-microvolt = <4350000>; + voltage-min-design-microvolt = <3000000>; + }; + + charge-animation { + compatible = "rockchip,uboot-charge"; + rockchip,uboot-charge-on = <0>; + rockchip,android-charge-on = <1>; + rockchip,uboot-low-power-voltage = <3450>; + rockchip,screen-on-voltage = <3500>; + rockchip,auto-wakeup-interval = <5>; + rockchip,uboot-exit-charge-level = <2>; + rockchip,uboot-exit-charge-voltage = <3500>; + rockchip,uboot-exit-charge-auto = <1>; + status = "disabled"; + }; + + rk730_sound: rk730-sound { + status = "okay"; + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip-rk730"; + spk-con-gpio = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; + rockchip,pre-power-on-delay-ms = <30>; + rockchip,post-power-down-delay-ms = <40>; + rockchip,format = "i2s"; + rockchip,mclk-fs = <256>; + rockchip,cpu = <&sai0>; + rockchip,codec = <&rk730>; + rockchip,audio-routing = + "Headphone", "LOUT1", + "Headphone", "ROUT1", + "Speaker", "LOUT2", + "Speaker", "ROUT2", + "Headphone", "Headphone Power", + "Headphone", "Headphone Power", + "Speaker", "Speaker Power", + "Speaker", "Speaker Power", + "MIC2", "Main Mic", + "MIC1", "Headset Mic"; + }; +}; + +&backlight { + pwms = <&pwm1_6ch_3 0 25000 0>; + status = "okay"; +}; + +&chosen { + bootargs = "earlycon=uart8250,mmio32,0x2ad40000 console=ttyFIQ0 \ + ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs rw rootwait \ + rcupdate.rcu_expedited=1 rcu_nocbs=all isolcpus=3 nohz_full=3 \ + snd_aloop.index=7 snd_aloop.use_raw_jiffies=1"; +}; + +&CPU_SLEEP { + status = "disabled"; +}; + +&csi2_dcphy0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_in_ucam0: endpoint@1 { + reg = <1>; + remote-endpoint = <&imx386_out0>; + data-lanes = <1 2 3 4>; + }; + + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + csidcphy0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi0_csi2_input>; + }; + }; + }; +}; + +&display_subsystem { + status = "okay"; +}; + +&dp { + status = "okay"; +}; + +&dp0 { + status = "okay"; +}; + +&dp0_in_vp2 { + status = "okay"; +}; + +&dsi { + status = "disabled"; +}; + +&es8388_sound { + status = "disabled"; +}; + +&gpio4 { + interrupt-affinity = <&cpu_l0>, <&cpu_l3>, <&cpu_l0>, <&cpu_l0>; + interrupt-pins = <0>, + , + <0>, + <0>; +}; + +>1x { + status = "disabled"; +}; + +&hdmi { + status = "disabled"; +}; + +&hdmi_in_vp0 { + status = "disabled"; +}; + +&hdptxphy_hdmi { + status = "disabled"; +}; + +&i2c2 { + status = "okay"; + /delete-node/ husb311@4e; + + usbc0: fusb302@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&usbc0_int>; + vbus-supply = <&vbus5v0_typec>; + wakeup-source; + status = "okay"; + + port { + usbc0_role_sw: endpoint { + remote-endpoint = <&usb_drd0_role_switch>; + }; + }; + + usb_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + power-role = "dual"; + try-power-role = "sink"; + op-sink-microwatt = <1000000>; + sink-pdos = + ; + source-pdos = + ; + mode-switch = <&dp>; + + altmodes { + #address-cells = <1>; + #size-cells = <0>; + + altmode@0 { + reg = <0>; + svid = <0xff01>; + vdo = <0xffffffff>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usbc0_orien_sw: endpoint { + remote-endpoint = <&usbdp_phy_orientation_switch>; + }; + }; + + port@1 { + reg = <1>; + dp_altmode_mux: endpoint { + remote-endpoint = <&usbdp_phy_dp_altmode_mux>; + }; + }; + }; + }; + }; +}; + +&i2c3 { + status = "disabled"; +}; + +&i2c4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4m1_xfer>; + + cw221X@64 { + compatible = "cellwise,cw221X"; + reg = <0x64>; + status = "okay"; + cw,user_rsense = <2000>; + cellwise,battery-profile = /bits/ 8 + <0x5A 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0xAA 0xB4 0xB7 0xBB 0xA7 0x9F 0xE3 0xD6 + 0xD0 0xFF 0xF5 0xA4 0x89 0x6D 0x5B 0x51 + 0x48 0x47 0x45 0xCC 0xC5 0xD8 0x7E 0xD3 + 0xCD 0xCC 0xCB 0xCA 0xC3 0xBF 0xDD 0x9A + 0xB7 0xB9 0xB0 0x99 0x8A 0x82 0x76 0x69 + 0x61 0x63 0x77 0x8E 0xA5 0x7F 0x55 0x5F + 0x20 0x00 0xAB 0x10 0x00 0xA2 0xEC 0x00 + 0x00 0x00 0x64 0x26 0xB1 0xCE 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x11>; + }; + + sc89601: sc89601@6b { + compatible = "sc,sc89601"; + reg = <0x6b>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&charger_ok>; + interrupt-parent = <&gpio0>; + interrupts = ; /* IRQ_TYPE_LEVEL_LOW>;*/ + charger-phandle = <&usbc0>; + sc,battery-regulation-voltage = <4350000>; /* 4200000,4.2V , 4350000, 4232000*/ + sc,charge-current = <3000000>; /*2040000,* 2.040A, 3000000 */ + sc,termination-current = <180000>; /* 180mA, 180000 */ + sc,precharge-current = <180000>; /* 180mA */ + sc,minimum-sys-voltage = <3400000>; /*3500000, 3.5V */ + sc,boost-voltage = <5000000>; /*5100000, 5.1V */ + sc,boost-max-current = <1500000>; /*1200000, 1200mA */ + + sc,use-stat-pin = <0>; /* enable stat pin */ + sc,boost-freq = <0>; /* 1.5MHz */ + + //monitored-battery = <&bat>; + regulators { + otg-en-pin = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; + vbus5v0_typec: vbus5v0-typec { + regulator-compatible = "otg-vbus"; + regulator-name = "vbus5v0_typec"; + }; + }; + }; +}; + +&i2c5 { + status = "okay"; + pinctrl-0 = <&i2c5m2_xfer>; + + imx386: imx386@1a { + compatible = "sony,imx386"; + reg = <0x1a>; + clocks = <&cru CLK_MIPI_CAMERAOUT_M0>; + clock-names = "xvclk"; + pinctrl-names = "default"; + pinctrl-0 = <&cam_clk0m1_clk0>; // GPIO2 D2 + power-domains = <&power RK3576_PD_VI>; + avdd-supply = <&vcc_mipidcphy0>; + reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&gpio2 RK_PD7 GPIO_ACTIVE_HIGH>; + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "CMK-OT2022-PX1"; + rockchip,camera-module-lens-name = "IR0147-50IRC-8M-F20"; + port { + imx386_out0: endpoint { + remote-endpoint = <&mipi_in_ucam0>; + data-lanes = <1 2 3 4>; + }; + }; + }; +}; + +&i2c7 { + status = "disabled"; +}; + +&i2c9 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c9m2_xfer>; + + rk730: rk730@16 { + #sound-dai-cells = <0>; + compatible = "rockchip,rk730"; + reg = <0x16>; + clocks = <&mclkout_sai0>; + clock-names = "mclk"; + assigned-clocks = <&mclkout_sai0>; + assigned-clock-rates = <12288000>; + pinctrl-names = "default"; + pinctrl-0 = <&sai0m0_mclk>; + status = "okay"; + }; +}; + +&little_core_thermal { + trips { + threshold: trip-point-0 { + temperature = <105000>; + hysteresis = <2000>; + type = "passive"; + }; + target: trip-point-1 { + temperature = <105000>; + hysteresis = <2000>; + type = "passive"; + }; + little_core_crit: little-core-crit { + /* millicelsius */ + temperature = <115000>; + /* millicelsius */ + hysteresis = <2000>; + type = "critical"; + }; + }; +}; + +&mipi0_csi2 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi0_csi2_input: endpoint@1 { + reg = <1>; + remote-endpoint = <&csidcphy0_out>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mipi0_csi2_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&cif_mipi_in0>; + }; + }; + }; +}; + +&mipidcphy0_pwr { + rockchip,pins = + /* camera power en */ + <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; +}; + +/* + * The pins of pcie1 and mcu_panel are multiplexed + */ +&pcie0 { + status = "disabled"; +}; + +&pinctrl { + inv { + inv_int1: inv-int1 { + rockchip,pins = + <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + charger { + charger_ok: charger_ok { + rockchip,pins = + <0 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>, + <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + usb_host_pwren: usb-host-pwren { + rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usb_otg0_pwren: usb-otg0-pwren { + rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usbc0_int: usbc0-int { + rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm1_6ch_3 { + pinctrl-names = "active"; + pinctrl-0 = <&pwm1m3_ch3>; + status = "okay"; +}; + +&rgb { + status = "okay"; + rockchip,data-sync-bypass; + pinctrl-names = "default"; + /* + * rgb3x8_pins_m0/rgb3x8_pins_m1 for RGB3x8(8bit) + * rgb565_pins for RGB565(16bit) + */ + pinctrl-0 = <&rgb3x8_pins_m0>; + + /* + * 240x320 RGB/MCU screen DT20QV063 + */ + mcu_panel: mcu-panel { + /* + * MEDIA_BUS_FMT_RGB888_3X8 for RGB3x8(8bit) + * MEDIA_BUS_FMT_RGB565_1X16 for RGB565(16bit) + * MEDIA_BUS_FMT_RGB565_2X8_LE for RGB565(8bit) + */ + bus-format = ; + backlight = <&backlight>; // dummy bl configuration + enable-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>; + enable-delay-ms = <20>; + reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>; + reset-delay-ms = <200>; + prepare-delay-ms = <10>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + init-delay-ms = <120>; + width-mm = <217>; + height-mm = <136>; + + // type:0 is cmd, 1 is data + panel-init-sequence = [ + //type delay num val1 val2 val3 + // private access + 00 00 01 fd + 01 00 01 06 + 01 00 01 08 + + 00 00 01 61 + 01 00 01 07 + 01 00 01 07 + + 00 00 01 73 + 01 00 01 70 + 00 00 01 73 + 01 00 01 00 + + 00 00 01 61 + 01 00 01 07 + 01 00 01 07 + // bias setting + 00 00 01 62 + 01 00 01 00 + 01 00 01 44 + 01 00 01 40 + // vsp + 00 00 01 65 + 01 00 01 08 + 01 00 01 10 + 01 00 01 21 + // vsn + 00 00 01 66 + 01 00 01 08 + 01 00 01 10 + 01 00 01 21 + // add source neg time + 00 00 01 67 + 01 00 01 21 + 01 00 01 40 + // gamma vap/van + 00 00 01 68 + 01 00 01 70 + 01 00 01 37 + 01 00 01 2a + 01 00 01 16 + + // frame rate + 00 00 01 b1 + 01 00 01 0f + 01 00 01 02 + 01 00 01 04 + + 00 00 01 b4 + 01 00 01 01 + + // porch + 00 00 01 b5 + 01 00 01 02 + 01 00 01 02 + 01 00 01 0a + 01 00 01 14 + + // display function + 00 00 01 b6 + 01 00 01 44 + 01 00 01 01 + 01 00 01 9f + 01 00 01 00 + 01 00 01 02 + // source + 00 00 01 e6 + 01 00 01 00 + 01 00 01 ff + + 00 00 01 e7 + 01 00 01 01 + 01 00 01 04 + 01 00 01 03 + 01 00 01 03 + 01 00 01 00 + 01 00 01 12 + + 00 00 01 e8 + 01 00 01 00 + 01 00 01 70 + 01 00 01 00 + // gate + 00 00 01 ec + 01 00 01 52 + // gamma_sel + 00 00 01 df + 01 00 01 11 + // gamma test1 + 00 00 01 e0 + 01 00 01 07 + 01 00 01 07 + 01 00 01 0a + 01 00 01 13 + 01 00 01 0e + 01 00 01 11 + 01 00 01 11 + 01 00 01 19 + + 00 00 01 e3 + 01 00 01 12 + 01 00 01 0f + 01 00 01 11 + 01 00 01 0e + 01 00 01 10 + 01 00 01 09 + 01 00 01 05 + 01 00 01 06 + + 00 00 01 e1 + 01 00 01 2a + 01 00 01 71 + + 00 00 01 e4 + 01 00 01 6b + 01 00 01 2a + + 00 00 01 e2 + 01 00 01 00 + 01 00 01 13 + 01 00 01 17 + 01 00 01 31 + 01 00 01 36 + 01 00 01 3f + + 00 00 01 e5 + 01 00 01 3f + 01 00 01 36 + 01 00 01 32 + 01 00 01 17 + 01 00 01 13 + 01 00 01 00 + + 00 00 01 f6 + 01 00 01 01 + 01 00 01 30 + 01 00 01 00 + 01 00 01 00 + + 00 00 01 f1 + 01 00 01 01 //te + 01 00 01 01 //01 + 01 00 01 20 //02 + + 00 00 01 fd + 01 00 01 fa + 01 00 01 fc + + 00 00 01 3a + 01 00 01 55 + + 00 00 01 35 + 01 00 01 00 + 00 00 01 36 + 01 00 01 00 + + // exit sleep + 00 c8 01 11 + // display on + 00 14 01 29 + + 00 00 01 2a + 01 00 01 00 + 01 00 01 00 + 01 00 01 00 + 01 00 01 ef + + 00 00 01 2b + 01 00 01 00 + 01 00 01 00 + 01 00 01 01 + 01 00 01 3f + + 00 00 01 2c + ]; + + panel-exit-sequence = [ + //type delay num val1 val2 val3 + // display off + 00 14 01 28 + // enter sleep + 00 c8 01 10 + ]; + + display-timings { + native-mode = <&kd050fwfba002_timing>; + + kd050fwfba002_timing: timing0 { + /* + * 7840125 for frame rate 45Hz + * 10453500 for frame rate 60Hz + */ + clock-frequency = <2742750>; + hactive = <240>; + vactive = <320>; + hback-porch = <10>; + hfront-porch = <5>; + vback-porch = <10>; + vfront-porch = <5>; + hsync-len = <10>; + vsync-len = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <1>; + }; + }; + + port { + panel_in_rgb: endpoint { + remote-endpoint = <&rgb_out_panel>; + }; + }; + }; + + ports { + rgb_out: port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + rgb_out_panel: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_in_rgb>; + }; + }; + }; +}; + +&rgb_in_vp1 { + status = "okay"; +}; + +&route_dp0 { + status = "okay"; +}; + +&route_dsi { + status = "disabled"; +}; + +&route_hdmi { + status = "disabled"; +}; + +&route_rgb { + status = "okay"; + connect = <&vp1_out_rgb>; +}; + +&rkcif { + status = "okay"; +}; + +&rkcif_mipi_lvds { + status = "okay"; + + port { + cif_mipi_in0: endpoint { + remote-endpoint = <&mipi0_csi2_output>; + }; + }; +}; + +&rkcif_mipi_lvds_sditf { + status = "okay"; + + port { + mipi_lvds_sditf: endpoint { + remote-endpoint = <&isp_vir0>; + }; + }; +}; + +&rkcif_mmu { + status = "okay"; +}; + +&rkisp { + status = "okay"; +}; + +&rkisp_mmu { + status = "okay"; +}; + +&rkisp_vir0 { + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + isp_vir0: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_lvds_sditf>; + }; + }; +}; + +&rkisp_vir0_sditf { + status = "okay"; +}; + +&rkvpss { + status = "okay"; +}; + +&rkvpss_mmu { + status = "okay"; +}; + +&rkvpss_vir0 { + status = "okay"; +}; + +&sai0 { + status = "okay"; + pinctrl-0 = <&sai0m0_lrck + &sai0m0_sclk + &sai0m0_sdi0 + &sai0m0_sdo0>; +}; + +/* + * The pins of sai1 and mcu_panel are multiplexed + */ +&sai1 { + status = "disabled"; +}; + +&sfc0 { + status = "okay"; + + flash@0 { + compatible = "spi-nand"; + reg = <0>; + spi-max-frequency = <80000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <1>; + }; +}; + +&spi4 { + status = "okay"; + max-freq = <24000000>; + pinctrl-names = "default"; + pinctrl-0 = <&spi4m2_csn0 &spi4m2_pins &inv_int1>; + icm42670: icm42670@0 { + compatible = "invensense,icm42670"; + reg = <0x0>; + spi-max-frequency = <24000000>; + spi-cpha; + spi-cpol; + vdd-supply = <&vcc_3v3_s0>; + drive-open-drain = <1>; + int1-gpio = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; + interrupt-parent = <&gpio4>; + interrupts = <12 IRQ_TYPE_EDGE_FALLING>; + status = "okay"; + }; +}; + +&usbdp_phy { + sbu1-dc-gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; + sbu2-dc-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; +}; + +&vcc_mipidcphy0 { + gpio = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; +}; + +&vp0 { + status = "disabled"; +}; + +&vp1 { + mcu-timing { + mcu-pix-total = <5>; + mcu-cs-pst = <1>; + mcu-cs-pend = <4>; + mcu-rw-pst = <2>; + mcu-rw-pend = <3>; + + mcu-hold-mode = <0>; + }; +}; + +&vdd_0v75_s3 { + regulator-min-microvolt = <550000>; +}; From af693b73221abc40840c541c8f5e346bee68e5de Mon Sep 17 00:00:00 2001 From: Ye Zhang Date: Mon, 10 Mar 2025 18:17:45 +0800 Subject: [PATCH 06/11] gpio: rockchip: release clk correctly when error Fixes: 7b561549e482 ("gpio: rockchip: binding thread to specified cpu") Signed-off-by: Ye Zhang Change-Id: I6e1828400c1d11c8fafdb33561c5673e6efcf934 --- drivers/gpio/gpio-rockchip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index be27f2949081..45605bd019f2 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -1140,7 +1140,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev) ret = rockchip_gpio_parse_irqs(pdev, bank); if (ret < 0) - return ret; + goto err_clk; rockchip_gpio_init_cpuhp(); /* @@ -1213,6 +1213,7 @@ err_unlock: rockchip_gpio_remove_cpuhp(); mutex_unlock(&bank->deferred_lock); +err_clk: clk_disable_unprepare(bank->clk); clk_disable_unprepare(bank->db_clk); From b8bfe877da6d8ddee512066e25129a74d3e785c1 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 7 Mar 2025 15:06:33 +0800 Subject: [PATCH 07/11] drm/rockchip: vop2: add support force DOVI mode RK3588 force DOVI mode[only have UI->coer2 and none base layer to core1], the UI layer must from layer2 and connect to core2, so insert unused win to layer0. Signed-off-by: Sandy Huang Change-Id: I84b37120a0de10960fb41a7989130d48bdad153d --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 108 ++++++++++++++----- 1 file changed, 79 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index a356469f08b6..1ca70116f39e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -12254,6 +12254,83 @@ static bool post_sharp_enabled(struct drm_crtc *crtc) return true; } +static void vop2_crtc_update_zpos_for_dovi(struct drm_crtc *crtc, struct vop2_zpos *vop2_zpos) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct vop2 *vop2 = vp->vop2; + const struct vop2_data *vop2_data = vop2->data; + struct drm_plane *plane; + struct vop2_plane_state *vpstate; + bool has_base_layer = false; + uint8_t nr_layers = 0; + + drm_atomic_crtc_for_each_plane(plane, crtc) { + vpstate = to_vop2_plane_state(plane->state); + if (vpstate->dovi_input_type == DOVI_BASE_LAYER) + has_base_layer = true; + } + + /* + * At RK3588 force DOVI mode[only have UI->coer2 and none base layer to core1] + * the UI layer must from layer2 and connect to core2, so insert unused win to + * layer0. + */ + if (vp->nr_layers == 1 && has_base_layer == false) { + struct vop2_zpos vop2_zpos0; + int phys_id, freed_phy_id = ROCKCHIP_VOP2_PHY_ID_INVALID; + int zpos0_phy_id = vop2_zpos[0].win_phys_id; + unsigned long win_mask = vp->win_mask; + + /* find freed layer to core1 */ + for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) { + if (phys_id != zpos0_phy_id && + phys_id != vop2_data->dovi->enhance_layer_phy_id) { + freed_phy_id = phys_id; + break; + } + } + if (freed_phy_id == ROCKCHIP_VOP2_PHY_ID_INVALID) { + DRM_DEV_ERROR(vop2->dev, "Can't find freed phy id for dovi core1\n"); + return; + } + + memcpy(&vop2_zpos0, &vop2_zpos[0], sizeof(struct vop2_zpos)); + vp->nr_layers++; + vop2_zpos[0].zpos = 0; + vop2_zpos[0].win_phys_id = freed_phy_id; + + memcpy(&vop2_zpos[1], &vop2_zpos0, sizeof(struct vop2_zpos)); + vop2_zpos[1].zpos = 1; + } + nr_layers = vp->nr_layers; + + /* + * At RK3588 dovi mode, the layer0 and layer1 is used for dovi layer, + * layer0 for base layer, layer1 for enhance layer, the enhance layer + * is option, but it's always occupy this layer, and the other layer + * must be assigned from layer2, so copy the other layers to &vop_zpos[2]. + */ + if (vp->nr_layers > 1) { + struct vop2_zpos *vop2_zpos_tmp; + int i = 0; + + vop2_zpos_tmp = kmalloc_array(nr_layers - 1, sizeof(struct vop2_zpos), GFP_KERNEL); + if (!vop2_zpos_tmp) + return; + + /* Insert esmart3 as core1 enhance layer to zpos1 */ + memcpy(vop2_zpos_tmp, &vop2_zpos[1], (nr_layers - 1) * sizeof(struct vop2_zpos)); + vp->nr_layers++; + vop2_zpos[1].zpos = 1; + vop2_zpos[1].win_phys_id = vop2_data->dovi->enhance_layer_phy_id; + memcpy(&vop2_zpos[2], vop2_zpos_tmp, (nr_layers - 1) * sizeof(struct vop2_zpos)); + for (i = 0; i < nr_layers - 1; i++) + vop2_zpos[2 + i].zpos = 2 + i; + + kfree(vop2_zpos_tmp); + } +} + static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) { struct vop2_video_port *vp = to_vop2_video_port(crtc); @@ -12378,33 +12455,9 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_stat vp->nr_layers = nr_layers; sort(vop2_zpos, nr_layers, sizeof(vop2_zpos[0]), vop2_zpos_cmp, NULL); - /* - * At RK3588 dovi mode, the layer0 and layer1 is used for dovi layer, - * layer0 for base layer, layer1 for enhance layer, the enhance layer - * is option, but it's always occupy this layer, and the other layer - * must be assigned from layer2, so copy the other layers to &vop_zpos[2]. - */ - if (vop2->version == VOP_VERSION_RK3588 && - vop2_is_dovi_mode(vp) && vp->nr_layers > 1) { - const struct vop2_data *vop2_data = vop2->data; - struct vop2_zpos *vop2_zpos_tmp; - int i = 0; - vop2_zpos_tmp = kmalloc_array(nr_layers - 1, sizeof(struct vop2_zpos), GFP_KERNEL); - if (!vop2_zpos_tmp) - goto dovi_err; - - /* Insert esmart3 as core1 enhance layer to zpos1 */ - memcpy(vop2_zpos_tmp, &vop2_zpos[1], (nr_layers - 1) * sizeof(struct vop2_zpos)); - vp->nr_layers++; - vop2_zpos[1].zpos = 1; - vop2_zpos[1].win_phys_id = vop2_data->dovi->enhance_layer_phy_id; - memcpy(&vop2_zpos[2], vop2_zpos_tmp, (nr_layers - 1) * sizeof(struct vop2_zpos)); - for (i = 0; i < nr_layers - 1; i++) - vop2_zpos[2 + i].zpos = 2 + i; - - kfree(vop2_zpos_tmp); - } + if (vop2->version == VOP_VERSION_RK3588 && vop2_is_dovi_mode(vp)) + vop2_crtc_update_zpos_for_dovi(crtc, vop2_zpos); if (!vp->hdr10_at_splice_mode) { if (is_vop3(vop2)) { @@ -12481,9 +12534,6 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_stat } } -dovi_err: - if (vcstate->splice_mode) - kfree(vop2_zpos_splice); out: kfree(vop2_zpos); } From 8141859ffb417762bdb81254769ed35240d4304d Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 7 Mar 2025 15:20:03 +0800 Subject: [PATCH 08/11] drm/rockchip: vop2: add aclk reset when exit from dovi mode The burr of the vsync signal maybe lead to core1 work abnormally, so add aclk reset when exit from dovi mode. Signed-off-by: Sandy Huang Change-Id: I6266a874a54d5b0df97a2824e135c4249e5abf1f --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 1ca70116f39e..43c485c43c2d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -4979,6 +4979,13 @@ static void vop2_dovi_post_disable(struct drm_crtc *crtc) vp->dovi_hdr_mode = false; vp->dovi_hdr_en = false; vp->dovi_hdr_in = false; + + /** + * The burr of the vsync signal maybe lead to core1 work abnormally, + * so add aclk reset when exit from dovi mode. + */ + vop2_clk_reset(vop2->axi_rst); + drm_info(vop2, "vp%d dovi disabled\n", vp->id); } @@ -5653,7 +5660,6 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, VOP_MODULE_SET(vop2, vp, hdr_lut_update_en, 0); vop2_dovi_pre_disable(crtc); vop2_disable_all_planes_for_crtc(crtc); - vop2_dovi_post_disable(crtc); if (vop2->dscs[vcstate->dsc_id].enabled && vop2->dscs[vcstate->dsc_id].attach_vp_id == vp->id && @@ -5742,6 +5748,7 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, vop2_dsp_hold_valid_irq_disable(crtc); + vop2_dovi_post_disable(crtc); vop2_disable(crtc); vop2->active_vp_mask &= ~BIT(vp->id); From 968469b63516f2a6675c02ef4773d53a6f495156 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 7 Mar 2025 15:26:44 +0800 Subject: [PATCH 09/11] drm/rockchip: vop2: dynamic enable/disable dovi core After this commit, dovi core will be disabled when unused. Signed-off-by: Sandy Huang Change-Id: If3585155599374d0ed8f36cfb4adfac6996eee2e --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 36 ++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 43c485c43c2d..8adb908b0f89 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -4869,22 +4869,44 @@ static void vop2_dovi_enable(struct drm_crtc *crtc) struct hdr_extend *hdr_data; int i = 0; - if (vp->dovi_hdr_en) - return; + if (!vcstate->hdr_ext_data) + goto DISABLE_DOVI; hdr_data = (struct hdr_extend *)vcstate->hdr_ext_data->data; - if (!hdr_data) - return; + if (!hdr_data || hdr_data->hdr_type != HDR_DOVI) + goto DISABLE_DOVI; + dovi_data = &hdr_data->dovi_data; for (i = 0; i < vop2_data->dovi->nr_dovi_cores; i++) { dovi_core = &vop2->dovi_cores[i]; - if (vop2_check_dovi_core_enabled(dovi_core->id, dovi_data->valid)) + if (vop2_check_dovi_core_enabled(dovi_core->id, dovi_data->valid)) { VOP_MODULE_SET(vop2, dovi_core, enable, 1); + } else { + VOP_MODULE_SET(vop2, dovi_core, enable, 0); + VOP_MODULE_SET(vop2, dovi_core, lut_update, 0); + if (dovi_core->id == 2) + VOP_MODULE_SET(vop2, dovi_core, dly_en, 0); + } } vp->dovi_hdr_en = true; - DRM_DEV_INFO(vop2->dev, "vp%d dovi enabled\n", vp->id); + DRM_DEV_DEBUG(vop2->dev, "vp%d dovi enabled\n", vp->id); + + return; + +DISABLE_DOVI: + if (!vp->dovi_hdr_en) + return; + + for (i = 0; i < vop2_data->dovi->nr_dovi_cores; i++) { + dovi_core = &vop2->dovi_cores[i]; + + VOP_MODULE_SET(vop2, dovi_core, enable, 0); + VOP_MODULE_SET(vop2, dovi_core, lut_update, 0); + if (dovi_core->id == 2) + VOP_MODULE_SET(vop2, dovi_core, dly_en, 0); + } } static int vop2_dovi_init(struct drm_crtc *crtc) @@ -12951,6 +12973,8 @@ static void vop2_cfg_update(struct drm_crtc *crtc, if (vp_data->feature & VOP_FEATURE_OVERSCAN) vop2_post_config(crtc); + if (vp_data->feature & VOP_FEATURE_DOVI) + vop2_dovi_enable(crtc); if (vop2_is_dovi_mode(vp) && vp->enabled_win_mask) { vop2_dovi_mode_config(crtc); vop2_load_dovi_coe_table(crtc); From a638f5bb9e3c3607b716795411164491274fdc9c Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 7 Mar 2025 15:45:46 +0800 Subject: [PATCH 10/11] drm/rockchip: vop2: update mode changed for dovi DOVI will set mode changed at the following case: (1) Enter or Exit dovi output mode; (2) Keep dovi output mode, and change from non dovi video to dovi video; Signed-off-by: Sandy Huang Change-Id: I24b2dca58031c6930e207350856f215af8863b4b --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 52 +++++++++++++++----- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 8adb908b0f89..eeba530bc14b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -10636,23 +10636,51 @@ static void vop2_update_post_csc_info(struct vop2_video_port *vp, } /* - * Check hdr_ext_data switch from valid to NULL or - * NULL to valid. - * This is used to check a switch from dynamic HDR2SDR - * or SDR2HDR output mode switch. + * DOVI will set mode changed at the following case: + * (1) Enter or Exit dovi output mode[judge by old/new crtc state]; + * (2) Keep dovi output mode, and change from non dovi video to dovi video[judge + * by core1 bypass_composer state]; */ -static bool vop_hdr_ext_data_switch(struct drm_crtc_state *old_state, +static bool vop2_dovi_mode_changed(struct drm_crtc_state *old_state, struct drm_crtc_state *new_state) { struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_state); struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_state); struct drm_property_blob *new_blob = new_vcstate->hdr_ext_data; struct drm_property_blob *old_blob = old_vcstate->hdr_ext_data; + struct hdr_extend *old_hdr_data, *new_hdr_data; + bool mode_changed = false; - if ((!old_blob && new_blob) || (!new_blob && old_blob)) - return false; + if (!old_blob && new_blob) { + new_hdr_data = (struct hdr_extend *)new_vcstate->hdr_ext_data->data; + if (new_hdr_data->hdr_type == HDR_DOVI) + mode_changed = true; + } else if (!new_blob && old_blob) { + old_hdr_data = (struct hdr_extend *)old_vcstate->hdr_ext_data->data; + if (old_hdr_data->hdr_type == HDR_DOVI) + mode_changed = true; + } else if (old_blob && new_blob) { + struct dovi_regs *old_dovi_reg_data, *new_dovi_reg_data; - return true; + new_hdr_data = (struct hdr_extend *)new_vcstate->hdr_ext_data->data; + old_hdr_data = (struct hdr_extend *)old_vcstate->hdr_ext_data->data; + if (old_hdr_data->hdr_type != new_hdr_data->hdr_type) { + mode_changed = true; + } else if (old_hdr_data->hdr_type == new_hdr_data->hdr_type && + old_hdr_data->hdr_type == HDR_DOVI) { + old_dovi_reg_data = &old_hdr_data->dovi_data; + new_dovi_reg_data = &new_hdr_data->dovi_data; + + /* dovi core1 bypass_composer change from 1 to 0 must enter mode_changed */ + if ((old_dovi_reg_data->core1[1] & BIT(0)) == 1 && + (new_dovi_reg_data->core1[1] & BIT(0)) == 0) { + mode_changed = true; + DRM_INFO("dovi core1 bypass_composer from 1 to 0\n"); + } + } + } + + return mode_changed; } static int vop2_crtc_atomic_check(struct drm_crtc *crtc, @@ -10669,7 +10697,6 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc, struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_crtc_state); struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_crtc_state); struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; - bool hdr_ext_data_change; if (vop2_has_feature(vop2, VOP_FEATURE_SPLICE)) { if (adjusted_mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) { @@ -10694,10 +10721,9 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc, else vp->acm_state_changed = false; - hdr_ext_data_change = !vop_hdr_ext_data_switch(old_crtc_state, new_crtc_state) | - new_crtc_state->active_changed; - if (hdr_ext_data_change) - new_crtc_state->mode_changed = true; + if (vp_data->feature & VOP_FEATURE_DOVI) + new_crtc_state->mode_changed |= + vop2_dovi_mode_changed(old_crtc_state, new_crtc_state); return 0; } From 8127940715d154ad28fc1764e5dd6233517fe3b6 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 7 Mar 2025 15:54:39 +0800 Subject: [PATCH 11/11] drm/rockchip: vop2: add support dovi mode config Mode0: normal mode echo 0 > /sys/kernel/debug/dri/0/video_port0/dovi_mode Mode1: disable aclk reset when enter dovi echo 1 > /sys/kernel/debug/dri/0/video_port0/dovi_mode Signed-off-by: Sandy Huang Change-Id: Ie680a86453d9bad2334b2ba67f8806d5cf382003 --- .../gpu/drm/rockchip/rockchip_drm_debugfs.c | 58 +++++++++++++++++++ .../gpu/drm/rockchip/rockchip_drm_debugfs.h | 7 +++ drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 4 ++ drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 20 ++++--- 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c b/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c index 7b5e3c2bbe2f..6d5690a13446 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c @@ -397,3 +397,61 @@ int rockchip_drm_debugfs_add_dclk_rate(struct drm_crtc *crtc, struct dentry *roo return 0; } +static int rockchip_drm_debugfs_dovi_mode_show(struct seq_file *s, void *data) +{ + seq_puts(s, " Mode0: normal mode\n"); + seq_puts(s, " echo 0 > /sys/kernel/debug/dri/0/video_port0/dovi_mode\n"); + seq_puts(s, " Mode1: disable aclk reset when enter dovi\n"); + seq_puts(s, " echo 1 > /sys/kernel/debug/dri/0/video_port0/dovi_mode\n"); + + return 0; +} + +static int rockchip_drm_debugfs_dovi_mode_open(struct inode *inode, struct file *file) +{ + struct drm_crtc *crtc = inode->i_private; + + return single_open(file, rockchip_drm_debugfs_dovi_mode_show, crtc); +} + +static ssize_t rockchip_drm_debugfs_dovi_mode_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *s = file->private_data; + struct drm_crtc *crtc = s->private; + struct rockchip_drm_private *private = crtc->dev->dev_private; + u8 mode; + + if (len != 2) { + DRM_INFO("Unsupported dovi mode\n"); + return -EINVAL; + } + + if (kstrtou8_from_user(ubuf, len, 0, &mode)) + return -EFAULT; + + private->dovi_mode = mode; + + return len; +} + +static const struct file_operations rockchip_drm_debugfs_dovi_mode_fops = { + .owner = THIS_MODULE, + .open = rockchip_drm_debugfs_dovi_mode_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = rockchip_drm_debugfs_dovi_mode_write, +}; + +int rockchip_drm_debugfs_add_dovi_mode(struct drm_crtc *crtc, struct dentry *root) +{ + struct dentry *ent; + + ent = debugfs_create_file("dovi_mode", 0644, root, crtc, + &rockchip_drm_debugfs_dovi_mode_fops); + if (!ent) + DRM_ERROR("Failed to add dovi_mode for debugfs\n"); + + return 0; +} diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.h b/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.h index bb7290146427..13c95c0b8c24 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.h @@ -38,6 +38,7 @@ rockchip_drm_crtc_dump_plane_buffer(struct drm_crtc *crtc) int rockchip_drm_debugfs_add_color_bar(struct drm_crtc *crtc, struct dentry *root); int rockchip_drm_debugfs_add_regs_write(struct drm_crtc *crtc, struct dentry *root); int rockchip_drm_debugfs_add_dclk_rate(struct drm_crtc *crtc, struct dentry *root); +int rockchip_drm_debugfs_add_dovi_mode(struct drm_crtc *crtc, struct dentry *root); #else static inline int rockchip_drm_add_dump_buffer(struct drm_crtc *crtc, struct dentry *root) @@ -68,6 +69,12 @@ rockchip_drm_debugfs_add_dclk_rate(struct drm_crtc *crtc, struct dentry *root) { return 0; } + +static inline int +rockchip_drm_debugfs_add_dovi_mode(struct drm_crtc *crtc, struct dentry *root) +{ + return 0; +} #endif #endif diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index 998b6afa962f..d20ebb7e6c6a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -595,6 +595,10 @@ struct rockchip_drm_private { */ struct mutex ovl_lock; bool need_ovl_lock; + /** + * @dovi_mode: dovi mode from userspace for dovi test. + */ + u8 dovi_mode; struct rockchip_drm_vcnt vcnt[ROCKCHIP_MAX_CRTC]; struct rockchip_drm_error_event error_event; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index eeba530bc14b..288a1f25ccea 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -8428,6 +8428,7 @@ static int vop2_crtc_debugfs_init(struct drm_minor *minor, struct drm_crtc *crtc rockchip_drm_debugfs_add_color_bar(crtc, vop2->debugfs); rockchip_drm_debugfs_add_regs_write(crtc, vop2->debugfs); rockchip_drm_debugfs_add_dclk_rate(crtc, vop2->debugfs); + rockchip_drm_debugfs_add_dovi_mode(crtc, vop2->debugfs); #endif for (i = 0; i < ARRAY_SIZE(vop2_debugfs_files); i++) vop2->debugfs_files[i].data = vop2; @@ -10639,15 +10640,19 @@ static void vop2_update_post_csc_info(struct vop2_video_port *vp, * DOVI will set mode changed at the following case: * (1) Enter or Exit dovi output mode[judge by old/new crtc state]; * (2) Keep dovi output mode, and change from non dovi video to dovi video[judge - * by core1 bypass_composer state]; + * by core1 bypass_composer state], except dovi_mode changed to non zero value + * by userspace. */ -static bool vop2_dovi_mode_changed(struct drm_crtc_state *old_state, - struct drm_crtc_state *new_state) +static bool vop2_dovi_mode_changed(struct drm_crtc *crtc, + struct drm_atomic_state *state) { - struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_state); - struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_state); + struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); + struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_crtc_state); + struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_crtc_state); struct drm_property_blob *new_blob = new_vcstate->hdr_ext_data; struct drm_property_blob *old_blob = old_vcstate->hdr_ext_data; + struct rockchip_drm_private *private = crtc->dev->dev_private; struct hdr_extend *old_hdr_data, *new_hdr_data; bool mode_changed = false; @@ -10667,7 +10672,8 @@ static bool vop2_dovi_mode_changed(struct drm_crtc_state *old_state, if (old_hdr_data->hdr_type != new_hdr_data->hdr_type) { mode_changed = true; } else if (old_hdr_data->hdr_type == new_hdr_data->hdr_type && - old_hdr_data->hdr_type == HDR_DOVI) { + old_hdr_data->hdr_type == HDR_DOVI && ++ private->dovi_mode == 0) { old_dovi_reg_data = &old_hdr_data->dovi_data; new_dovi_reg_data = &new_hdr_data->dovi_data; @@ -10723,7 +10729,7 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc, if (vp_data->feature & VOP_FEATURE_DOVI) new_crtc_state->mode_changed |= - vop2_dovi_mode_changed(old_crtc_state, new_crtc_state); + vop2_dovi_mode_changed(crtc, state); return 0; }