From 0bbcfb87aa1c4d4033f6887c86d1554ff10533da Mon Sep 17 00:00:00 2001 From: Tony Xie Date: Thu, 29 Jun 2023 19:51:40 +0800 Subject: [PATCH 01/22] soc: rockchip: amp: support config amp os irqs Signed-off-by: Tony Xie Change-Id: I628a5c4a863e4ed6d51a71ed9243d04993a04e43 --- drivers/soc/rockchip/rockchip_amp.c | 286 ++++++++++++++++++++++++++++ include/soc/rockchip/rockchip_amp.h | 39 ++++ 2 files changed, 325 insertions(+) create mode 100644 include/soc/rockchip/rockchip_amp.h diff --git a/drivers/soc/rockchip/rockchip_amp.c b/drivers/soc/rockchip/rockchip_amp.c index 6c66362ca1b7..0d1cb29ac207 100644 --- a/drivers/soc/rockchip/rockchip_amp.c +++ b/drivers/soc/rockchip/rockchip_amp.c @@ -6,6 +6,7 @@ * Author: Tony Xie */ +#include #include #include #include @@ -17,6 +18,12 @@ #define RK_CPU_STATUS_OFF 0 #define RK_CPU_STATUS_ON 1 #define RK_CPU_STATUS_BUSY -1 +#define AMP_AFF_MAX_CLUSTER 4 +#define AMP_AFF_MAX_CPU 8 +#define GPIO_BANK_NUM 16 +#define GPIO_GROUP_PRIO_MAX 3 + +#define AMP_GIC_DBG(fmt, arg...) do { if (0) { pr_warn(fmt, ##arg); } } while (0) enum amp_cpu_ctrl_status { AMP_CPU_STATUS_AMP_DIS = 0, @@ -44,6 +51,33 @@ static struct { u64 cpu_id; } cpu_boot_info[CONFIG_NR_CPUS]; +struct amp_gpio_group_s { + u32 bank_id; + u32 prio; + u32 irq_aff[AMP_AFF_MAX_CPU]; + u32 irq_id[AMP_AFF_MAX_CPU]; + u32 en[AMP_AFF_MAX_CPU]; +}; + +struct amp_irq_cfg_s { + u32 prio; + u32 cpumask; + u32 aff; + int amp_flag; +} irqs_cfg[1024]; + +static struct amp_gic_ctrl_s { + struct { + u32 aff; + u32 cpumask; + u32 flag; + } aff_to_cpumask[AMP_AFF_MAX_CLUSTER][AMP_AFF_MAX_CPU]; + struct amp_irq_cfg_s irqs_cfg[1024]; + u32 validmask[1020 / 32 + 1]; + struct amp_gpio_group_s gpio_grp[GPIO_BANK_NUM][GPIO_GROUP_PRIO_MAX]; + u32 gpio_banks; +} amp_ctrl; + static int get_cpu_boot_info_idx(unsigned long cpu_id) { int i; @@ -220,6 +254,257 @@ static int rockchip_amp_boot_cpus(struct device *dev, return 0; } +int rockchip_amp_check_amp_irq(u32 irq) +{ + return amp_ctrl.irqs_cfg[irq].amp_flag; +} + +u32 rockchip_amp_get_irq_prio(u32 irq) +{ + return amp_ctrl.irqs_cfg[irq].prio; +} + +u32 rockchip_amp_get_irq_cpumask(u32 irq) +{ + return amp_ctrl.irqs_cfg[irq].cpumask; +} + +static u32 amp_get_cpumask_bit(u32 aff) +{ + u32 aff_cluster, aff_cpu; + + aff_cluster = MPIDR_AFFINITY_LEVEL(aff, 1); + aff_cpu = MPIDR_AFFINITY_LEVEL(aff, 0); + + if (aff_cpu >= AMP_AFF_MAX_CPU || aff_cluster >= AMP_AFF_MAX_CLUSTER) + return 0; + + AMP_GIC_DBG("%s: aff:%d-%d: %x\n", __func__, aff_cluster, aff_cpu, + amp_ctrl.aff_to_cpumask[aff_cluster][aff_cpu].cpumask); + + return amp_ctrl.aff_to_cpumask[aff_cluster][aff_cpu].cpumask; +} + +static int gic_amp_get_gpio_prio_group_info(struct device_node *np, + struct amp_gic_ctrl_s *amp_ctrl, + int prio_id) +{ + u32 gpio_bank, count0, count1, prio, irq_id, irq_aff; + int i; + struct amp_gpio_group_s *gpio_grp; + struct amp_irq_cfg_s *irqs_cfg; + + if (prio_id >= GPIO_GROUP_PRIO_MAX) + return -EINVAL; + + if (of_property_read_u32_array(np, "gpio-bank", &gpio_bank, 1)) + return -EINVAL; + if (gpio_bank >= amp_ctrl->gpio_banks) + return -EINVAL; + + gpio_grp = &_ctrl->gpio_grp[gpio_bank][prio_id]; + + if (of_property_read_u32_array(np, "prio", &prio, 1)) + return -EINVAL; + + if (gpio_bank >= GPIO_BANK_NUM) + return -EINVAL; + + AMP_GIC_DBG("%s: gpio-%d, group prio:%d-%x\n", + __func__, gpio_bank, prio_id, prio); + + count0 = of_property_count_u32_elems(np, "girq-id"); + count1 = of_property_count_u32_elems(np, "girq-aff"); + + if (count0 != count1) + return -EINVAL; + + gpio_grp->prio = prio; + + for (i = 0; i < count0; i++) { + of_property_read_u32_index(np, "girq-id", i, &irq_id); + gpio_grp->irq_id[i] = irq_id; + of_property_read_u32_index(np, "girq-aff", i, &irq_aff); + + gpio_grp->irq_aff[i] = irq_aff; + + of_property_read_u32_index(np, "girq-en", i, &gpio_grp->en[i]); + + irqs_cfg = &_ctrl->irqs_cfg[irq_id]; + + AMP_GIC_DBG(" %s: group cpu-%d, irq-%d: prio-%x, aff-%x en-%d\n", + __func__, i, gpio_grp->irq_id[i], gpio_grp->prio, + gpio_grp->irq_aff[i], gpio_grp->en[i]); + + if (gpio_grp->en[i]) { + irqs_cfg->prio = gpio_grp->prio; + irqs_cfg->aff = irq_aff; + irqs_cfg->cpumask = amp_get_cpumask_bit(irq_aff); + irqs_cfg->amp_flag = 1; + } + + AMP_GIC_DBG(" %s: irqs_cfg prio-%x aff-%x cpumaks-%x en-%d\n", + __func__, irqs_cfg->prio, irqs_cfg->aff, + irqs_cfg->cpumask, irqs_cfg->amp_flag); + } + + return 0; +} + +static int gic_amp_gpio_group_get_info(struct device_node *group_node, + struct amp_gic_ctrl_s *amp_ctrl, + int idx) +{ + int i = 0; + struct device_node *node; + + if (group_node) { + for_each_available_child_of_node(group_node, node) { + if (i >= GPIO_GROUP_PRIO_MAX) + break; + if (!gic_amp_get_gpio_prio_group_info(node, amp_ctrl, + i)) { + i++; + } + } + } + return 0; +} + +static void gic_of_get_gpio_group(struct device_node *np, + struct amp_gic_ctrl_s *amp_ctrl) +{ + struct device_node *gpio_group_node, *node; + int i = 0; + + if (of_property_read_u32_array(np, "gpio-group-banks", + &_ctrl->gpio_banks, 1)) + return; + + gpio_group_node = of_get_child_by_name(np, "gpio-group"); + if (gpio_group_node) { + for_each_available_child_of_node(gpio_group_node, node) { + if (i >= amp_ctrl->gpio_banks) + break; + if (!gic_amp_gpio_group_get_info(node, amp_ctrl, i)) + i++; + } + } + + of_node_put(gpio_group_node); +} + +static int amp_gic_get_cpumask(struct device_node *np, struct amp_gic_ctrl_s *amp_ctrl) +{ + const struct property *prop; + int count, i; + u32 cluster, aff_cpu, aff, cpumask; + + prop = of_find_property(np, "amp-cpu-aff-maskbits", NULL); + if (!prop) + return -1; + + if (!prop->value) + return -1; + + count = of_property_count_u32_elems(np, "amp-cpu-aff-maskbits"); + if (count % 2) + return -1; + + for (i = 0; i < count / 2; i++) { + of_property_read_u32_index(np, "amp-cpu-aff-maskbits", + 2 * i, &aff); + cluster = MPIDR_AFFINITY_LEVEL(aff, 1); + aff_cpu = MPIDR_AFFINITY_LEVEL(aff, 0); + amp_ctrl->aff_to_cpumask[cluster][aff_cpu].aff = aff; + + of_property_read_u32_index(np, "amp-cpu-aff-maskbits", + 2 * i + 1, &cpumask); + + amp_ctrl->aff_to_cpumask[cluster][aff_cpu].cpumask = cpumask; + + AMP_GIC_DBG("cpumask: %d-%d: aff-%d cpumask-%d\n", + cluster, aff_cpu, aff, cpumask); + + if (!cpumask) + return -1; + } + + return 0; +} + +static void amp_gic_get_irqs_config(struct device_node *np, + struct amp_gic_ctrl_s *amp_ctrl) +{ + const struct property *prop; + int count, i; + u32 irq, prio, aff; + + prop = of_find_property(np, "amp-irqs", NULL); + if (!prop) + return; + + if (!prop->value) + return; + + count = of_property_count_u32_elems(np, "amp-irqs"); + + if (count < 0 || count % 3) + return; + + for (i = 0; i < count / 3; i++) { + of_property_read_u32_index(np, "amp-irqs", 3 * i, &irq); + + if (irq > 1020) + break; + + of_property_read_u32_index(np, "amp-irqs", 3 * i + 1, &prio); + of_property_read_u32_index(np, "amp-irqs", 3 * i + 2, &aff); + + AMP_GIC_DBG("%s: irq-%d aff-%d prio-%x\n", + __func__, irq, aff, prio); + + amp_ctrl->irqs_cfg[irq].prio = prio; + amp_ctrl->irqs_cfg[irq].aff = aff; + amp_ctrl->irqs_cfg[irq].cpumask = amp_get_cpumask_bit(aff); + + if (!amp_ctrl->irqs_cfg[irq].cpumask) { + AMP_GIC_DBG("%s: get cpumask error\n", __func__); + break; + } + + if (!amp_ctrl->irqs_cfg[irq].aff && + !amp_ctrl->irqs_cfg[irq].prio) + break; + + amp_ctrl->irqs_cfg[irq].amp_flag = 1; + + AMP_GIC_DBG("%s: irq-%d aff-%d cpumask-%d pri-%x\n", + __func__, irq, amp_ctrl->irqs_cfg[irq].aff, + amp_ctrl->irqs_cfg[irq].cpumask, + amp_ctrl->irqs_cfg[irq].prio); + } +} + +void rockchip_amp_get_gic_info(void) +{ + struct device_node *np; + + np = of_find_node_by_name(NULL, "rockchip-amp"); + if (!np) + return; + + if (amp_gic_get_cpumask(np, &_ctrl)) { + pr_err("%s: get amp gic cpu mask error\n", __func__); + goto exit; + } + gic_of_get_gpio_group(np, &_ctrl); + amp_gic_get_irqs_config(np, &_ctrl); + +exit: + of_node_put(np); +} + static int rockchip_amp_probe(struct platform_device *pdev) { struct rkamp_device *rkamp_dev = NULL; @@ -273,6 +558,7 @@ static int rockchip_amp_probe(struct platform_device *pdev) idx++; } } + of_node_put(cpus_node); } rk_amp_kobj = kobject_create_and_add("rk_amp", NULL); diff --git a/include/soc/rockchip/rockchip_amp.h b/include/soc/rockchip/rockchip_amp.h new file mode 100644 index 000000000000..1c37e8b46e0b --- /dev/null +++ b/include/soc/rockchip/rockchip_amp.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Rockchip AMP support. + * + * Copyright (c) 2023 Rockchip Electronics Co. Ltd. + * Author: Tony Xie + */ + +#ifndef _ROCKCHIP_AMP +#define _ROCKCHIP_AMP + +#if IS_REACHABLE(CONFIG_ROCKCHIP_AMP) +void rockchip_amp_get_gic_info(void); +int rockchip_amp_check_amp_irq(u32 irq); +u32 rockchip_amp_get_irq_prio(u32 irq); +u32 rockchip_amp_get_irq_cpumask(u32 irq); +#else +#include + +static inline void rockchip_amp_get_gic_info(void) +{ +} + +static inline int rockchip_amp_check_amp_irq(u32 irq) +{ + return 0; +} + +static inline u32 rockchip_amp_get_irq_prio(u32 irq) +{ + return GICD_INT_DEF_PRI; +} + +static inline u32 rockchip_amp_get_irq_cpumask(u32 irq) +{ + return 0; +} +#endif /* CONFIG_ROCKCHIP_AMP */ +#endif /* _ROCKCHIP_AMP */ From 2e7658ef57746182668ed94d9c14f57c74ebec7c Mon Sep 17 00:00:00 2001 From: Tony Xie Date: Thu, 29 Jun 2023 19:52:59 +0800 Subject: [PATCH 02/22] irqchip/gic: support config amp os irqs Signed-off-by: Tony Xie Change-Id: Id7ff9d5cccfe5656462542fcfa68fef51cdd910e --- drivers/irqchip/irq-gic-common.c | 21 +++++++++++ drivers/irqchip/irq-gic.c | 61 ++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index f47b41dfd023..7ce79b512e01 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -10,6 +10,10 @@ #include "irq-gic-common.h" +#ifdef CONFIG_ROCKCHIP_AMP +#include +#endif + static DEFINE_RAW_SPINLOCK(irq_controller_lock); static const struct gic_kvm_info *gic_kvm_info; @@ -112,8 +116,25 @@ void gic_dist_config(void __iomem *base, int gic_irqs, /* * Set priority on all global interrupts. */ +#ifdef CONFIG_ROCKCHIP_AMP + for (i = 32; i < gic_irqs; i += 4) { + u32 amp_pri, j; + + amp_pri = 0; + for (j = 0; j < 4; j++) { + if (rockchip_amp_check_amp_irq(i + j)) { + amp_pri |= rockchip_amp_get_irq_prio(i + j) << + (j * 8); + } else { + amp_pri |= GICD_INT_DEF_PRI << (j * 8); + } + } + writel_relaxed(amp_pri, base + GIC_DIST_PRI + i); + } +#else for (i = 32; i < gic_irqs; i += 4) writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i); +#endif /* * Deactivate and disable all SPIs. Leave the PPI and SGIs diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index ac027de9e5c4..cd3f72b4e2d6 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -47,6 +47,10 @@ #include "irq-gic-common.h" +#ifdef CONFIG_ROCKCHIP_AMP +#include +#endif + #ifdef CONFIG_ARM64 #include @@ -194,11 +198,19 @@ static int gic_peek_irq(struct irq_data *d, u32 offset) static void gic_mask_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR); } static void gic_eoimode1_mask_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif gic_mask_irq(d); /* * When masking a forwarded interrupt, make sure it is @@ -214,6 +226,10 @@ static void gic_eoimode1_mask_irq(struct irq_data *d) static void gic_unmask_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif gic_poke_irq(d, GIC_DIST_ENABLE_SET); } @@ -221,6 +237,10 @@ static void gic_eoi_irq(struct irq_data *d) { u32 hwirq = gic_irq(d); +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(hwirq)) + return; +#endif if (hwirq < 16) hwirq = this_cpu_read(sgi_intid); @@ -231,6 +251,10 @@ static void gic_eoimode1_eoi_irq(struct irq_data *d) { u32 hwirq = gic_irq(d); +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif /* Do not deactivate an IRQ forwarded to a vcpu. */ if (irqd_is_forwarded_to_vcpu(d)) return; @@ -246,6 +270,10 @@ static int gic_irq_set_irqchip_state(struct irq_data *d, { u32 reg; +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return -EINVAL; +#endif switch (which) { case IRQCHIP_STATE_PENDING: reg = val ? GIC_DIST_PENDING_SET : GIC_DIST_PENDING_CLEAR; @@ -296,6 +324,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type) unsigned int gicirq = gic_irq(d); int ret; +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return -EINVAL; +#endif + /* Interrupt configuration for SGIs can't be changed */ if (gicirq < 16) return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0; @@ -492,10 +525,29 @@ static void gic_dist_init(struct gic_chip_data *gic) * Set all global interrupts to this CPU only. */ cpumask = gic_get_cpumask(gic); + +#ifdef CONFIG_ROCKCHIP_AMP + for (i = 32; i < gic_irqs; i += 4) { + u32 maskval; + unsigned int j; + + maskval = 0; + for (j = 0; j < 4; j++) { + if (rockchip_amp_check_amp_irq(i + j)) { + maskval |= rockchip_amp_get_irq_cpumask(i + j) << + (j * 8); + } else { + maskval |= cpumask << (j * 8); + } + } + writel_relaxed(maskval, base + GIC_DIST_TARGET + i * 4 / 4); + } +#else cpumask |= cpumask << 8; cpumask |= cpumask << 16; for (i = 32; i < gic_irqs; i += 4) writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); +#endif gic_dist_config(base, gic_irqs, NULL); @@ -847,6 +899,11 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); unsigned int cpu; +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return -EINVAL; +#endif + if (!force) cpu = cpumask_any_and(mask_val, cpu_online_mask); else @@ -1509,6 +1566,10 @@ static int gic_of_setup(struct gic_chip_data *gic, struct device_node *node) gic_enable_of_quirks(node, gic_quirks, gic); +#ifdef CONFIG_ROCKCHIP_AMP + rockchip_amp_get_gic_info(); +#endif + return 0; error: From 56e05e2ff351c7f6c96711462435946d6bd85f2d Mon Sep 17 00:00:00 2001 From: Tony Xie Date: Thu, 29 Jun 2023 20:07:19 +0800 Subject: [PATCH 03/22] dt-bindings: soc: rockchip: add define for rockchip amp Signed-off-by: Tony Xie Change-Id: Ie4225d2b17b9f6180a1bbfc489c485562d5d2fe4 --- include/dt-bindings/soc/rockchip-amp.h | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 include/dt-bindings/soc/rockchip-amp.h diff --git a/include/dt-bindings/soc/rockchip-amp.h b/include/dt-bindings/soc/rockchip-amp.h new file mode 100644 index 000000000000..0681e92ef4da --- /dev/null +++ b/include/dt-bindings/soc/rockchip-amp.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +#ifndef _DT_BINDINGS_SOC_ROCKCHIP_AMP_H +#define _DT_BINDINGS_SOC_ROCKCHIP_AMP_H + +#define CPU_GET_AFFINITY(cpu, cluster) ((cpu) << 0 | ((cluster) << 8)) +#define GIC_AMP_IRQ_CFG_ROUTE(_irq, _prio, _aff) (_irq) (_prio) (_aff) +#endif From db0e436decc220f60ba4f50839fd5af443cdf52c Mon Sep 17 00:00:00 2001 From: Tony Xie Date: Thu, 29 Jun 2023 20:36:01 +0800 Subject: [PATCH 04/22] arm64: dts: rockchip: rk3308b-amp: support config amp os irqs Signed-off-by: Tony Xie Change-Id: I03ebaca4483c0c4d7be3e42a06774ec87cb8475e --- arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi index 72f3029c62c0..9b7ec9810f99 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi @@ -3,6 +3,8 @@ * Copyright (c) 2023 Rockchip Electronics Co., Ltd. */ +#include + / { rockchip_amp: rockchip-amp { compatible = "rockchip,amp"; @@ -12,6 +14,8 @@ pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer>; status = "okay"; + amp-cpu-aff-maskbits = <0x0 0x1 0x1 0x2 0x2 0x4 0x3 0x8>; + amp-irqs = ; }; reserved-memory { From 6d2677915dd63e2c20391ddb08cbe968b6a00eed Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Tue, 4 Jul 2023 11:14:14 +0800 Subject: [PATCH 05/22] soc: rockchip: pm_config: support mcu-sleep-config We configure "mcu sleep parameters" based on shared memory and atags. Refer to the following example to configure dts: rockchip_suspend: rockchip-suspend { ... rockchip-mcu-sleep-cfg { ... mcu-cec-wakeup { rockchip,tag = ; rockchip,params = <0x0 0x1 0x2 0x3>; }; ... mcu-uart-wakeup { rockchip,tag = ; rockchip,params = <0x3 0x2 0x1 0x0>; }; ... }; ... }; Signed-off-by: XiaoDong Huang Change-Id: I9cb9107334c8ae91add2d4055cfb48cf46bc3e73 --- drivers/soc/rockchip/rockchip_pm_config.c | 140 ++++++++++++++++++++++ include/linux/rockchip/rockchip_sip.h | 1 + 2 files changed, 141 insertions(+) diff --git a/drivers/soc/rockchip/rockchip_pm_config.c b/drivers/soc/rockchip/rockchip_pm_config.c index 639a0042b298..4ff89bf8b7c2 100644 --- a/drivers/soc/rockchip/rockchip_pm_config.c +++ b/drivers/soc/rockchip/rockchip_pm_config.c @@ -27,6 +27,10 @@ #define MAX_ON_OFF_REG_PROP_NAME_LEN 60 #define MAX_CONFIG_PROP_NAME_LEN 60 +#define RK_ATAG_MCU_SLP_CORE 0x526b0001 +#define RK_ATAG_MCU_SLP_MAX 0x526b00ff +#define RK_ATAG_NONE 0x00000000 + enum rk_pm_state { RK_PM_MEM = 0, RK_PM_MEM_LITE, @@ -52,6 +56,31 @@ static struct rk_sleep_config { u32 wakeup_config; } sleep_config[RK_PM_STATE_MAX]; +/* rk_tag related defines */ +#define sleep_tag_next(t) \ + ((struct rk_sleep_tag *)((__u32 *)(t) + (t)->hdr.size)) + +struct rk_tag_header { + u32 size; + u32 tag; +}; + +struct rk_sleep_tag { + struct rk_tag_header hdr; + u32 params[]; +}; + +struct rk_mcu_sleep_core_tag { + struct rk_tag_header hdr; + u32 total_size; + u32 reserve[13]; +}; + +struct rk_mcu_sleep_tags { + struct rk_mcu_sleep_core_tag core; + struct rk_sleep_tag slp_tags; +}; + static const struct of_device_id pm_match_table[] = { { .compatible = "rockchip,pm-px30",}, { .compatible = "rockchip,pm-rk1808",}, @@ -166,6 +195,115 @@ static int parse_on_off_regulator(struct device_node *node, enum rk_pm_state sta } #endif +static int parse_mcu_sleep_config(struct device_node *node) +{ + int ret, cnt; + struct arm_smccc_res res; + struct device_node *mcu_sleep_node; + struct device_node *child; + struct rk_mcu_sleep_tags *config; + struct rk_sleep_tag *slp_tag; + char *end; + + mcu_sleep_node = of_find_node_by_name(node, "rockchip-mcu-sleep-cfg"); + if (IS_ERR_OR_NULL(mcu_sleep_node)) { + ret = -ENODEV; + goto out; + } + + cnt = of_get_child_count(mcu_sleep_node); + if (!cnt) { + ret = -EINVAL; + goto free_mcu_mode; + } + + /* + * 4kb for sleep parameters + */ + res = sip_smc_request_share_mem(1, SHARE_PAGE_TYPE_SLEEP); + if (res.a0 != 0) { + pr_err("%s: no trust memory for mcu_sleep\n", __func__); + ret = -ENOMEM; + goto free_mcu_mode; + } + + /* Initialize core tag */ + memset((void *)res.a1, 0, sizeof(struct rk_mcu_sleep_tags)); + config = (struct rk_mcu_sleep_tags *)res.a1; + config->core.hdr.tag = RK_ATAG_MCU_SLP_CORE; + config->core.hdr.size = sizeof(struct rk_mcu_sleep_core_tag) / sizeof(u32); + config->core.total_size = sizeof(struct rk_mcu_sleep_tags) - + sizeof(struct rk_sleep_tag); + + slp_tag = &config->slp_tags; + + /* End point of sleep data */ + end = (char *)config + PAGE_SIZE - sizeof(struct rk_sleep_tag); + + for_each_available_child_of_node(mcu_sleep_node, child) { + /* Is overflow? */ + if ((char *)slp_tag->params >= end) + break; + + ret = of_property_read_u32_array(child, "rockchip,tag", + &slp_tag->hdr.tag, 1); + if (ret || + slp_tag->hdr.tag <= RK_ATAG_MCU_SLP_CORE || + slp_tag->hdr.tag >= RK_ATAG_MCU_SLP_MAX) { + pr_info("%s: no or invalid rockchip,tag in %s\n", + __func__, child->name); + + continue; + } + + cnt = of_property_count_u32_elems(child, "rockchip,params"); + if (cnt > 0) { + /* Is overflow? */ + if ((char *)(slp_tag->params + cnt) >= end) { + pr_warn("%s: no more space for rockchip,tag in %s\n", + __func__, child->name); + break; + } + + ret = of_property_read_u32_array(child, "rockchip,params", + slp_tag->params, cnt); + if (ret) { + pr_err("%s: rockchip,params error in %s\n", + __func__, child->name); + break; + } + + slp_tag->hdr.size = + cnt + sizeof(struct rk_tag_header) / sizeof(u32); + } else if (cnt == 0) { + slp_tag->hdr.size = 0; + } else { + continue; + } + + config->core.total_size += slp_tag->hdr.size * sizeof(u32); + + slp_tag = sleep_tag_next(slp_tag); + } + + /* Add none tag. + * Compiler will combine the follow code as "str xzr, [x28]", but + * "slp->hdr" may not be 8-byte alignment. So we use memset_io instead: + * slp_tag->hdr.size = 0; + * slp_tag->hdr.tag = RK_ATAG_NONE; + */ + memset_io(&slp_tag->hdr, 0, sizeof(slp_tag->hdr)); + + config->core.total_size += sizeof(struct rk_sleep_tag); + + ret = 0; + +free_mcu_mode: + of_node_put(mcu_sleep_node); +out: + return ret; +} + static int pm_config_probe(struct platform_device *pdev) { const struct of_device_id *match_id; @@ -270,6 +408,8 @@ static int pm_config_probe(struct platform_device *pdev) ret); } + parse_mcu_sleep_config(node); + #ifndef MODULE if (!of_property_read_u32_array(node, "rockchip,virtual-poweroff", diff --git a/include/linux/rockchip/rockchip_sip.h b/include/linux/rockchip/rockchip_sip.h index 4d78084b9960..717f0e80fcce 100644 --- a/include/linux/rockchip/rockchip_sip.h +++ b/include/linux/rockchip/rockchip_sip.h @@ -182,6 +182,7 @@ typedef enum { SHARE_PAGE_TYPE_DDR_ADDRMAP, SHARE_PAGE_TYPE_LAST_LOG, SHARE_PAGE_TYPE_HDCP, + SHARE_PAGE_TYPE_SLEEP, SHARE_PAGE_TYPE_MAX, } share_page_type_t; From bf9c5670aecec51fdceeee7a59455db1d4efd54c Mon Sep 17 00:00:00 2001 From: Zhang Yubing Date: Tue, 25 Jul 2023 15:36:51 +0800 Subject: [PATCH 06/22] drm/rockchip: vop2: report vividhdr feature by property Signed-off-by: Zhang Yubing Change-Id: I2d680b2066050ca2eeba0947936cc43a8855cbb1 --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 3 +++ include/uapi/drm/rockchip_drm.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 51e0789ee885..4f77fb27fd24 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -11077,6 +11077,7 @@ static int vop2_crtc_create_feature_property(struct vop2 *vop2, struct drm_crtc { ROCKCHIP_DRM_CRTC_FEATURE_ALPHA_SCALE, "ALPHA_SCALE" }, { ROCKCHIP_DRM_CRTC_FEATURE_HDR10, "HDR10" }, { ROCKCHIP_DRM_CRTC_FEATURE_NEXT_HDR, "NEXT_HDR" }, + { ROCKCHIP_DRM_CRTC_FEATURE_VIVID_HDR, "VIVID_HDR" }, }; if (vp_data->feature & VOP_FEATURE_ALPHA_SCALE) @@ -11085,6 +11086,8 @@ static int vop2_crtc_create_feature_property(struct vop2 *vop2, struct drm_crtc feature |= BIT(ROCKCHIP_DRM_CRTC_FEATURE_HDR10); if (vp_data->feature & VOP_FEATURE_NEXT_HDR) feature |= BIT(ROCKCHIP_DRM_CRTC_FEATURE_NEXT_HDR); + if (vp_data->feature & VOP_FEATURE_VIVID_HDR) + feature |= BIT(ROCKCHIP_DRM_CRTC_FEATURE_VIVID_HDR); prop = drm_property_create_bitmask(vop2->drm_dev, DRM_MODE_PROP_IMMUTABLE, "FEATURE", diff --git a/include/uapi/drm/rockchip_drm.h b/include/uapi/drm/rockchip_drm.h index 59f842d572d5..2ac71b43dba0 100644 --- a/include/uapi/drm/rockchip_drm.h +++ b/include/uapi/drm/rockchip_drm.h @@ -91,6 +91,7 @@ enum rockchip_crtc_feture { ROCKCHIP_DRM_CRTC_FEATURE_ALPHA_SCALE, ROCKCHIP_DRM_CRTC_FEATURE_HDR10, ROCKCHIP_DRM_CRTC_FEATURE_NEXT_HDR, + ROCKCHIP_DRM_CRTC_FEATURE_VIVID_HDR, }; enum rockchip_plane_feture { From 6926979cb02216b54921311abaae722ecc141e36 Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Fri, 28 Jul 2023 14:45:36 +0800 Subject: [PATCH 07/22] drm/rockchip: dw_hdmi: Fix crash caused by hotplug in uboot Signed-off-by: Algea Cao Change-Id: Id22025a2b464e68ac3683587eb808975439096df --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 4d35f0883228..fe7f9480e71c 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -1666,10 +1666,14 @@ static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) { struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); struct drm_crtc *crtc = encoder->crtc; - struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state); + struct rockchip_crtc_state *s; - if (WARN_ON(!crtc || !crtc->state)) + if (!crtc || !crtc->state) { + dev_info(hdmi->dev, "%s old crtc state is null\n", __func__); return; + } + + s = to_rockchip_crtc_state(crtc->state); if (crtc->state->active_changed) { if (hdmi->plat_data->split_mode) { @@ -1697,8 +1701,10 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) int mux; int ret; - if (WARN_ON(!crtc || !crtc->state)) + if (!crtc || !crtc->state) { + dev_info(hdmi->dev, "%s old crtc state is null\n", __func__); return; + } if (hdmi->phy) phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width); From 60dc45eb33c7bc9bf52fc1efe4bd82da0e40bad4 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Thu, 27 Jul 2023 18:11:12 +0800 Subject: [PATCH 08/22] soc: rockchip: cpuinfo: Add support for rk3528a Change-Id: I62baecdb5a5d10329dbe7c36fdae9a6df15ccc57 Signed-off-by: Liang Chen --- drivers/soc/rockchip/rockchip-cpuinfo.c | 5 ++++- include/linux/rockchip/cpu.h | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/soc/rockchip/rockchip-cpuinfo.c b/drivers/soc/rockchip/rockchip-cpuinfo.c index 9eea6f32a576..36af00ea8794 100644 --- a/drivers/soc/rockchip/rockchip-cpuinfo.c +++ b/drivers/soc/rockchip/rockchip-cpuinfo.c @@ -214,7 +214,10 @@ static void rk3308_init(void) static void rk3528_init(void) { - rockchip_soc_id = ROCKCHIP_SOC_RK3528; + if (of_machine_is_compatible("rockchip,rk3528")) + rockchip_soc_id = ROCKCHIP_SOC_RK3528; + else if (of_machine_is_compatible("rockchip,rk3528a")) + rockchip_soc_id = ROCKCHIP_SOC_RK3528A; } #define RK356X_PMU_GRF_PHYS 0xfdc20000 diff --git a/include/linux/rockchip/cpu.h b/include/linux/rockchip/cpu.h index 7cf949cd9ac4..dc3b9381e1ad 100644 --- a/include/linux/rockchip/cpu.h +++ b/include/linux/rockchip/cpu.h @@ -181,7 +181,8 @@ static inline bool cpu_is_rk3528(void) { if (rockchip_soc_id) return (rockchip_soc_id & ROCKCHIP_CPU_MASK) == ROCKCHIP_CPU_RK3528; - return of_machine_is_compatible("rockchip,rk3528"); + return of_machine_is_compatible("rockchip,rk3528") || + of_machine_is_compatible("rockchip,rk3528a"); } #else static inline bool cpu_is_rk3528(void) { return false; } @@ -223,6 +224,7 @@ static inline bool cpu_is_rk3568(void) { return false; } #define ROCKCHIP_SOC_RK3308B (ROCKCHIP_CPU_RK3308 | 0x01) #define ROCKCHIP_SOC_RK3308BS (ROCKCHIP_CPU_RK3308 | 0x02) #define ROCKCHIP_SOC_RK3528 (ROCKCHIP_CPU_RK3528 | 0x00) +#define ROCKCHIP_SOC_RK3528A (ROCKCHIP_CPU_RK3528 | 0x01) #define ROCKCHIP_SOC_RK3566 (ROCKCHIP_CPU_RK3566 | 0x00) #define ROCKCHIP_SOC_RK3568 (ROCKCHIP_CPU_RK3568 | 0x00) @@ -252,6 +254,7 @@ ROCKCHIP_SOC(RK3308, rk3308, RK3308) ROCKCHIP_SOC(RK3308, rk3308b, RK3308B) ROCKCHIP_SOC(RK3308, rk3308bs, RK3308BS) ROCKCHIP_SOC(RK3528, rk3528, RK3528) +ROCKCHIP_SOC(RK3528, rk3528a, RK3528A) ROCKCHIP_SOC(RK3568, rk3566, RK3566) ROCKCHIP_SOC(RK3568, rk3568, RK3568) From 23299c62a5f3693a6fd50d2e69fd00103638909b Mon Sep 17 00:00:00 2001 From: Zhang Yubing Date: Mon, 31 Jul 2023 15:19:58 +0800 Subject: [PATCH 09/22] drm/rockchip: drv: fix the config csc data issue Fixes: 6bd92608dfce ("drm/rockchip: drv: get acm and csc info when boot") Signed-off-by: Zhang Yubing Change-Id: I0dd41b229fce0c85bd3df03f03b4b40da06ef53a --- drivers/gpu/drm/rockchip/rockchip_drm_logo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c index 2c44fa94f6b1..af228f40c404 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c @@ -1060,7 +1060,7 @@ void rockchip_drm_show_logo(struct drm_device *drm_dev) if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->loader_protect) priv->crtc_funcs[pipe]->loader_protect(crtc, true, - &set->csc); + &unset->csc); priv->crtc_funcs[pipe]->crtc_close(crtc); if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->loader_protect) From 8ea19e33432c15ced01500a93a04598a1a156cfc Mon Sep 17 00:00:00 2001 From: Ziyuan Xu Date: Sun, 30 Jul 2023 10:17:09 +0800 Subject: [PATCH 10/22] soc: rockchip: tb_service: fixes the register haven't been handle Signed-off-by: Ziyuan Xu Change-Id: I3af3e5fd3b4725448363a1d8419dc4b9854f6cc6 --- drivers/soc/rockchip/rockchip_thunderboot_service.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/soc/rockchip/rockchip_thunderboot_service.c b/drivers/soc/rockchip/rockchip_thunderboot_service.c index 805042daa58a..d1420d141273 100644 --- a/drivers/soc/rockchip/rockchip_thunderboot_service.c +++ b/drivers/soc/rockchip/rockchip_thunderboot_service.c @@ -76,7 +76,7 @@ EXPORT_SYMBOL(rk_tb_client_register_cb_head); static void do_mcu_done(struct rk_tb_serv *serv) { - struct rk_tb_client *client, *client_s; + struct rk_tb_client *client; struct rockchip_mbox_msg msg; rockchip_mbox_read_msg(serv->mbox_rx_chan, &msg); @@ -97,12 +97,13 @@ static void do_mcu_done(struct rk_tb_serv *serv) return; } - list_for_each_entry_safe(client, client_s, &clients_list, node) { + while (!list_empty(&clients_list)) { + client = list_first_entry(&clients_list, struct rk_tb_client, node); + list_del(&client->node); spin_unlock(&lock); if (client->cb) client->cb(client->data); spin_lock(&lock); - list_del(&client->node); } atomic_set(&mcu_done, 1); spin_unlock(&lock); From ed5a9690cff59faf5293f65f114ca653a1c904f6 Mon Sep 17 00:00:00 2001 From: Zhihuan He Date: Fri, 28 Jul 2023 17:51:39 +0800 Subject: [PATCH 11/22] arm64: dts: rockchip: px30: delete dmc 528MHz and en 666MHz ODT For a more stable system, delete the 528MHz frequency and open the 666MHz frequency ODT. Signed-off-by: Zhihuan He Change-Id: I0354c6dde8f39a9b41878446475ee3acbe1be729 --- .../dts/rockchip/px30-dram-default-timing.dtsi | 4 ++-- arch/arm64/boot/dts/rockchip/px30.dtsi | 17 ++--------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/px30-dram-default-timing.dtsi b/arch/arm64/boot/dts/rockchip/px30-dram-default-timing.dtsi index c75c5ef4ef2a..99fb02048c82 100644 --- a/arch/arm64/boot/dts/rockchip/px30-dram-default-timing.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30-dram-default-timing.dtsi @@ -70,8 +70,8 @@ phy_lpddr4_dq_drv = ; phy_lpddr4_odt = ; - ddr4_odt_dis_freq = <666>; - phy_ddr4_odt_dis_freq = <666>; + ddr4_odt_dis_freq = <625>; + phy_ddr4_odt_dis_freq = <625>; ddr4_drv = ; ddr4_odt = ; phy_ddr4_ca_drv = ; diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index 34c8143b8046..ecb7884681b3 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -2013,11 +2013,11 @@ downdifferential = <20>; system-status-freq = < /*system status freq(KHz)*/ - SYS_STATUS_NORMAL 528000 + SYS_STATUS_NORMAL 666000 SYS_STATUS_REBOOT 450000 SYS_STATUS_SUSPEND 194000 SYS_STATUS_VIDEO_1080P 450000 - SYS_STATUS_BOOST 528000 + SYS_STATUS_BOOST 666000 SYS_STATUS_ISP 666000 SYS_STATUS_PERFORMANCE 1056000 >; @@ -2087,14 +2087,6 @@ opp-microvolt-L2 = <950000>; opp-microvolt-L3 = <950000>; }; - opp-528000000 { - opp-hz = /bits/ 64 <528000000>; - opp-microvolt = <975000>; - opp-microvolt-L0 = <975000>; - opp-microvolt-L1 = <975000>; - opp-microvolt-L2 = <950000>; - opp-microvolt-L3 = <950000>; - }; opp-666000000 { opp-hz = /bits/ 64 <666000000>; opp-microvolt = <1050000>; @@ -2125,11 +2117,6 @@ opp-hz = /bits/ 64 <328000000>; opp-microvolt = <950000>; }; - opp-528000000 { - opp-hz = /bits/ 64 <528000000>; - opp-microvolt = <950000>; - status = "disabled"; - }; opp-666000000 { opp-hz = /bits/ 64 <666000000>; opp-microvolt = <950000>; From c19bda6df357253169369e98cc95e968b1953b52 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Wed, 2 Aug 2023 06:19:29 +0000 Subject: [PATCH 12/22] phy/rockchip: samsung-hdptx: make deskew fifo works on shared pointer the deskew fifo works on its own pointers may cause inter-lane skew to exceed the vesa standard, this poses a risk of errors in dp sink parsing MSA packet which inserted in data stream Change-Id: Ia3bdfaed8696c8f7f21f39f0b55d18b1dce7761f Signed-off-by: Guochun Huang --- drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c index 93c1f1ed8b23..2d142cf731d1 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -318,6 +318,7 @@ /* lane_reg031E */ #define LN_POLARITY_INV BIT(2) +#define LN_LANE_MODE BIT(1) #define LANE_REG(lane, offset) (0x400 * (lane) + (offset)) @@ -1059,8 +1060,9 @@ static int rockchip_hdptx_phy_power_on(struct phy *phy) u32 invert = hdptx->lane_polarity_invert[lane]; regmap_update_bits(hdptx->regmap, LANE_REG(lane, 0x0c78), - LN_POLARITY_INV, - FIELD_PREP(LN_POLARITY_INV, invert)); + LN_POLARITY_INV | LN_LANE_MODE, + FIELD_PREP(LN_POLARITY_INV, invert) | + FIELD_PREP(LN_LANE_MODE, 1)); } if (mode == PHY_MODE_DP) { From 43f141406e7cdee3e0ce429d1e12015bbb8eb333 Mon Sep 17 00:00:00 2001 From: Lin Jinhan Date: Thu, 27 Jul 2023 15:38:28 +0800 Subject: [PATCH 13/22] crypto: rockchip: Fixed the timeout timer being triggered incorrectly If the time required for a single data calculation exceeds 3 seconds, timeout occurs.The timeout timer should be reset after the CRYPTO irq interrupt is triggered. Change-Id: I21516ba57bfc8eef3b22624e4ed95523d000cee2 Signed-off-by: Lin Jinhan --- drivers/crypto/rockchip/rk_crypto_core.c | 23 ++++++++++++++++--- drivers/crypto/rockchip/rk_crypto_v2_ahash.c | 4 ++++ .../crypto/rockchip/rk_crypto_v2_skcipher.c | 4 ++++ drivers/crypto/rockchip/rk_crypto_v3_ahash.c | 4 ++++ .../crypto/rockchip/rk_crypto_v3_skcipher.c | 4 ++++ 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/rockchip/rk_crypto_core.c b/drivers/crypto/rockchip/rk_crypto_core.c index 56a50d5c01de..2a9cf2da6372 100644 --- a/drivers/crypto/rockchip/rk_crypto_core.c +++ b/drivers/crypto/rockchip/rk_crypto_core.c @@ -272,9 +272,17 @@ static void start_irq_timer(struct rk_crypto_dev *rk_dev) static void rk_crypto_irq_timer_handle(struct timer_list *t) { struct rk_crypto_dev *rk_dev = from_timer(rk_dev, t, timer); + unsigned long flags; + + spin_lock_irqsave(&rk_dev->lock, flags); rk_dev->err = -ETIMEDOUT; rk_dev->stat.timeout_cnt++; + + rk_unload_data(rk_dev); + + spin_unlock_irqrestore(&rk_dev->lock, flags); + tasklet_schedule(&rk_dev->done_task); } @@ -282,8 +290,12 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) { struct rk_crypto_dev *rk_dev = platform_get_drvdata(dev_id); struct rk_alg_ctx *alg_ctx; + unsigned long flags; - spin_lock(&rk_dev->lock); + spin_lock_irqsave(&rk_dev->lock, flags); + + /* reset timeout timer */ + start_irq_timer(rk_dev); alg_ctx = rk_alg_ctx_cast(rk_dev->async_req); @@ -292,9 +304,14 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) if (alg_ctx->ops.irq_handle) alg_ctx->ops.irq_handle(irq, dev_id); - tasklet_schedule(&rk_dev->done_task); + /* already trigger timeout */ + if (rk_dev->err != -ETIMEDOUT) { + spin_unlock_irqrestore(&rk_dev->lock, flags); + tasklet_schedule(&rk_dev->done_task); + } else { + spin_unlock_irqrestore(&rk_dev->lock, flags); + } - spin_unlock(&rk_dev->lock); return IRQ_HANDLED; } diff --git a/drivers/crypto/rockchip/rk_crypto_v2_ahash.c b/drivers/crypto/rockchip/rk_crypto_v2_ahash.c index dd9ea240bac0..919603ff4768 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2_ahash.c +++ b/drivers/crypto/rockchip/rk_crypto_v2_ahash.c @@ -58,6 +58,10 @@ static void rk_hash_reset(struct rk_crypto_dev *rk_dev) pool_timeout_us); CRYPTO_WRITE(rk_dev, CRYPTO_HASH_CTL, 0xffff0000); + + /* clear dma int status */ + tmp = CRYPTO_READ(rk_dev, CRYPTO_DMA_INT_ST); + CRYPTO_WRITE(rk_dev, CRYPTO_DMA_INT_ST, tmp); } static int rk_crypto_irq_handle(int irq, void *dev_id) diff --git a/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c b/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c index 2a4628f9f58a..2bfff0d28771 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c +++ b/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c @@ -197,6 +197,10 @@ static void rk_cipher_reset(struct rk_crypto_dev *rk_dev) pool_timeout_us); CRYPTO_WRITE(rk_dev, CRYPTO_BC_CTL, 0xffff0000); + + /* clear dma int status */ + tmp = CRYPTO_READ(rk_dev, CRYPTO_DMA_INT_ST); + CRYPTO_WRITE(rk_dev, CRYPTO_DMA_INT_ST, tmp); } static void rk_crypto_complete(struct crypto_async_request *base, int err) diff --git a/drivers/crypto/rockchip/rk_crypto_v3_ahash.c b/drivers/crypto/rockchip/rk_crypto_v3_ahash.c index f39026dbc314..0c91b45b2123 100644 --- a/drivers/crypto/rockchip/rk_crypto_v3_ahash.c +++ b/drivers/crypto/rockchip/rk_crypto_v3_ahash.c @@ -63,6 +63,10 @@ static void rk_hash_reset(struct rk_crypto_dev *rk_dev) pool_timeout_us); CRYPTO_WRITE(rk_dev, CRYPTO_HASH_CTL, 0xffff0000); + + /* clear dma int status */ + tmp = CRYPTO_READ(rk_dev, CRYPTO_DMA_INT_ST); + CRYPTO_WRITE(rk_dev, CRYPTO_DMA_INT_ST, tmp); } static int rk_hash_mid_data_store(struct rk_crypto_dev *rk_dev, struct rk_hash_mid_data *mid_data) diff --git a/drivers/crypto/rockchip/rk_crypto_v3_skcipher.c b/drivers/crypto/rockchip/rk_crypto_v3_skcipher.c index 26d2b714761c..4220e6cbeb14 100644 --- a/drivers/crypto/rockchip/rk_crypto_v3_skcipher.c +++ b/drivers/crypto/rockchip/rk_crypto_v3_skcipher.c @@ -196,6 +196,10 @@ static void rk_cipher_reset(struct rk_crypto_dev *rk_dev) pool_timeout_us); CRYPTO_WRITE(rk_dev, CRYPTO_BC_CTL, 0xffff0000); + + /* clear dma int status */ + tmp = CRYPTO_READ(rk_dev, CRYPTO_DMA_INT_ST); + CRYPTO_WRITE(rk_dev, CRYPTO_DMA_INT_ST, tmp); } static void rk_crypto_complete(struct crypto_async_request *base, int err) From 203965847cc8724810f8c47ecc5477affab206bc Mon Sep 17 00:00:00 2001 From: Lin Jinhan Date: Thu, 15 Jun 2023 16:44:35 +0800 Subject: [PATCH 14/22] crypto: rockchip: utils: optimize alignment criteria There is no length alignment requirement for the last scatterlist. Signed-off-by: Lin Jinhan Change-Id: I9625bce9379cef4c1a8507ba523f5f303d60c9e6 --- drivers/crypto/rockchip/rk_crypto_utils.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/rockchip/rk_crypto_utils.c b/drivers/crypto/rockchip/rk_crypto_utils.c index 5db73ab1628c..5758e0eede97 100644 --- a/drivers/crypto/rockchip/rk_crypto_utils.c +++ b/drivers/crypto/rockchip/rk_crypto_utils.c @@ -72,14 +72,18 @@ static int check_scatter_align(struct scatterlist *sg_src, { int in, out, align; + /* The last piece has no need for length alignment */ in = IS_ALIGNED((u32)sg_src->offset, 4) && - IS_ALIGNED((u32)sg_src->length, align_mask) && + (!sg_next(sg_src) || + IS_ALIGNED((u32)sg_src->length, align_mask)) && (sg_phys(sg_src) < SZ_4G); if (!sg_dst) return in; + /* The last piece has no need for length alignment */ out = IS_ALIGNED((u32)sg_dst->offset, 4) && - IS_ALIGNED((u32)sg_dst->length, align_mask) && + (!sg_next(sg_dst) || + IS_ALIGNED((u32)sg_dst->length, align_mask)) && (sg_phys(sg_dst) < SZ_4G); align = in && out; From b406f355a2d5ad59202caf876c5be5b943e84021 Mon Sep 17 00:00:00 2001 From: "yuefu.su" Date: Fri, 28 Jul 2023 16:05:29 +0800 Subject: [PATCH 15/22] media: i2c: update sc230ai again map Signed-off-by: yuefu.su Change-Id: I6c5928d5bbb73a9d32a809f6750160a8730c0100 --- drivers/media/i2c/sc230ai.c | 47 +++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/drivers/media/i2c/sc230ai.c b/drivers/media/i2c/sc230ai.c index 179b219d2aba..084f5bf603fd 100644 --- a/drivers/media/i2c/sc230ai.c +++ b/drivers/media/i2c/sc230ai.c @@ -61,9 +61,6 @@ #define SC230AI_REG_SEXPOSURE_L 0x3e05 #define SC230AI_EXPOSURE_MIN 1 #define SC230AI_EXPOSURE_STEP 1 -#define SC230AI_EXPOSURE_LIN_MAX (2 * 0x465 - 9) -#define SC230AI_EXPOSURE_HDR_MAX_S (2 * 0x465 - 9) -#define SC230AI_EXPOSURE_HDR_MAX_L (2 * 0x465 - 9) #define SC230AI_VTS_MAX 0x7fff #define SC230AI_REG_DIG_GAIN 0x3e06 @@ -74,7 +71,7 @@ #define SC230AI_REG_SANA_GAIN 0x3e12 #define SC230AI_REG_SANA_FINE_GAIN 0x3e13 #define SC230AI_GAIN_MIN 1000 -#define SC230AI_GAIN_MAX 1722628 //108.512*15.875*1000 +#define SC230AI_GAIN_MAX 1574800 // 99.2*15.875*1000 #define SC230AI_GAIN_STEP 1 #define SC230AI_GAIN_DEFAULT 1000 #define SC230AI_LGAIN 0 @@ -678,46 +675,46 @@ static int sc230ai_get_gain_reg(struct sc230ai *sc230ai, u32 *again, u32 *dgain, *again = 0x00; *dgain = 0x00; *dgain_fine = total_gain * 128 / 1000; - } else if (total_gain < 3391) { /* 2 ~ 3.391 gain*/ + } else if (total_gain < 3100) { /* 2 ~ 3.1 gain*/ *again = 0x01; *dgain = 0x00; *dgain_fine = total_gain * 128 / 1000 / 2; - } else if (total_gain < 3391 * 2) { /* 3.391 ~ 6.782 gain*/ + } else if (total_gain < 3100 * 2) { /* 3.100 ~ 6.200 gain*/ *again = 0x40; *dgain = 0x00; - *dgain_fine = total_gain * 128 / 3391; - } else if (total_gain < 3391 * 4) { /* 6.782 ~ 13.564 gain*/ + *dgain_fine = total_gain * 128 / 3100; + } else if (total_gain < 3100 * 4) { /* 6.200 ~ 12.400 gain*/ *again = 0x48; *dgain = 0x00; - *dgain_fine = total_gain * 128 / 3391 / 2; - } else if (total_gain < 3391 * 8) { /* 13.564 ~ 27.128 gain*/ + *dgain_fine = total_gain * 128 / 3100 / 2; + } else if (total_gain < 3100 * 8) { /* 12.400 ~ 24.800 gain*/ *again = 0x49; *dgain = 0x00; - *dgain_fine = total_gain * 128 / 3391 / 4; - } else if (total_gain < 3391 * 16) { /* 27.128 ~ 54.256 gain*/ + *dgain_fine = total_gain * 128 / 3100 / 4; + } else if (total_gain < 3100 * 16) { /* 24.800 ~ 49.600 gain*/ *again = 0x4b; *dgain = 0x00; - *dgain_fine = total_gain * 128 / 3391 / 8; - } else if (total_gain < 3391 * 32) { /* 54.256 ~ 108.512 gain*/ + *dgain_fine = total_gain * 128 / 3100 / 8; + } else if (total_gain < 3100 * 32) { /* 49.600 ~ 99.200 gain*/ *again = 0x4f; *dgain = 0x00; - *dgain_fine = total_gain * 128 / 3391 / 16; - } else if (total_gain < 3391 * 64) { /* 108.512 ~ 217.024 gain*/ + *dgain_fine = total_gain * 128 / 3100 / 16; + } else if (total_gain < 3100 * 64) { /* 99.200 ~ 198.400 gain*/ *again = 0x5f; *dgain = 0x00; - *dgain_fine = total_gain * 128 / 3391 / 32; - } else if (total_gain < 3391 * 128) { /* 217.024 ~ 434.048 gain*/ + *dgain_fine = total_gain * 128 / 3100 / 32; + } else if (total_gain < 3100 * 128) { /* 198.400 ~ 396.800 gain*/ *again = 0x5f; *dgain = 0x01; - *dgain_fine = total_gain * 128 / 3391 / 64; - } else if (total_gain < 3391 * 256) { /* 434.048 ~ 868.096 gain*/ + *dgain_fine = total_gain * 128 / 3100 / 64; + } else if (total_gain < 3100 * 256) { /* 396.800 ~ 793.600 gain*/ *again = 0x5f; *dgain = 0x03; - *dgain_fine = total_gain * 128 / 3391 / 128; - } else if (total_gain < 3391 * 512) { /* 868.096 ~ 1736.192 gain*/ + *dgain_fine = total_gain * 128 / 3100 / 128; + } else { /* 793.600 ~ 1587.200 gain*/ *again = 0x5f; *dgain = 0x07; - *dgain_fine = total_gain * 128 / 3391 / 128; + *dgain_fine = total_gain * 128 / 3100 / 128; } return ret; @@ -1406,7 +1403,7 @@ static int sc230ai_set_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_VBLANK: /* Update max exposure while meeting expected vblanking */ - max = sc230ai->cur_mode->height + ctrl->val - 4; + max = sc230ai->cur_mode->height + ctrl->val - 5; __v4l2_ctrl_modify_range(sc230ai->exposure, sc230ai->exposure->minimum, max, sc230ai->exposure->step, @@ -1545,7 +1542,7 @@ static int sc230ai_initialize_controls(struct sc230ai *sc230ai) V4L2_CID_VBLANK, vblank_def, SC230AI_VTS_MAX - mode->height, 1, vblank_def); - exposure_max = SC230AI_EXPOSURE_LIN_MAX; + exposure_max = mode->vts_def - 5; sc230ai->exposure = v4l2_ctrl_new_std(handler, &sc230ai_ctrl_ops, V4L2_CID_EXPOSURE, SC230AI_EXPOSURE_MIN, exposure_max, SC230AI_EXPOSURE_STEP, From 0cb0d5f1ec17e9bd7d17cdb3d67156d80845edb8 Mon Sep 17 00:00:00 2001 From: Chen Shunqing Date: Tue, 1 Aug 2023 07:06:02 +0000 Subject: [PATCH 16/22] media: rockchip: hdmirx: fix CTS HF2-86 test fail If sample_flat field is set to 1, there can't be any sound. Change-Id: I56ad87d1165fe7d1cc993f9522c4e6d50c253b80 Signed-off-by: Chen Shunqing --- drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c | 6 +++++- drivers/media/platform/rockchip/hdmirx/rk_hdmirx.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c index 29a096af948b..1390989518f1 100644 --- a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c +++ b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c @@ -3172,7 +3172,7 @@ static void hdmirx_delayed_work_audio(struct work_struct *work) struct rk_hdmirx_dev, delayed_work_audio); struct hdmirx_audiostate *as = &hdmirx_dev->audio_state; - u32 fs_audio, ch_audio; + u32 fs_audio, ch_audio, sample_flat; int cur_state, init_state, pre_state, fifo_status2; unsigned long delay = 200; @@ -3237,6 +3237,10 @@ static void hdmirx_delayed_work_audio(struct work_struct *work) } } as->pre_state = cur_state; + + sample_flat = hdmirx_readl(hdmirx_dev, AUDIO_PROC_STATUS1) & AUD_SAMPLE_FLAT; + hdmirx_update_bits(hdmirx_dev, AUDIO_PROC_CONFIG0, I2S_EN, sample_flat ? 0 : I2S_EN); + exit: schedule_delayed_work_on(hdmirx_dev->bound_cpu, &hdmirx_dev->delayed_work_audio, diff --git a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.h b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.h index a1af89eea681..d49f7c4fe266 100644 --- a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.h +++ b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.h @@ -228,6 +228,7 @@ #define AUDIO_PROC_CONFIG3 0x048c #define AUDIO_PROC_STATUS1 0x0490 #define AUD_SAMPLE_PRESENT GENMASK(20, 17) +#define AUD_SAMPLE_FLAT GENMASK(16, 13) #define SCDC_CONFIG 0x0580 #define HPDLOW BIT(1) #define POWERPROVIDED BIT(0) From 9bef8f31ad7a331c4f3bc6bb1fed515a3c61ef9a Mon Sep 17 00:00:00 2001 From: Shunhua Lan Date: Wed, 2 Aug 2023 10:57:10 +0800 Subject: [PATCH 17/22] arm64: configs: rockchip_defconfig: Enable RT5651 for rk3399 excavator evb Signed-off-by: Shunhua Lan Change-Id: I09cdf40fdeac8dccc13c3a4b3ec4d3b58c2c35e3 --- arch/arm64/configs/rockchip_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index b5046cb58622..1ebb4d093c1e 100644 --- a/arch/arm64/configs/rockchip_defconfig +++ b/arch/arm64/configs/rockchip_defconfig @@ -714,6 +714,7 @@ CONFIG_SND_SOC_RK817=y CONFIG_SND_SOC_RK_CODEC_DIGITAL=y CONFIG_SND_SOC_RK_DSM=y CONFIG_SND_SOC_RT5640=y +CONFIG_SND_SOC_RT5651=y CONFIG_SND_SOC_SPDIF=y CONFIG_SND_SOC_AW883XX=y CONFIG_SND_SIMPLE_CARD=y From 1173b14159d8e77ac3d26b32a568e976686cf00d Mon Sep 17 00:00:00 2001 From: Yandong Lin Date: Fri, 28 Jul 2023 11:54:20 +0800 Subject: [PATCH 18/22] video: rockchip: mpp: fix reset_group protected range In some platform, there are some devices share PD. If one device is doing pmu idle request to cru reset and at this time cpu want to read/write reg for the device will crash. So use the reset_group to prevent the case. There is a issue that reset_group protected range not enough, so fix it. Signed-off-by: Yandong Lin Change-Id: Ide32966f7cff842e4611213d26901617fd57bc14 --- drivers/video/rockchip/mpp/mpp_common.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index aa84cc813a94..25865943f4f3 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -818,6 +818,12 @@ static int mpp_task_run(struct mpp_dev *mpp, } else { mpp_set_grf(mpp->grf_info); } + /* + * Lock the reader locker of the device resource lock here, + * release at the finish operation + */ + mpp_reset_down_read(mpp->reset_group); + /* * for iommu share hardware, should attach to ensure * working in current device @@ -825,6 +831,7 @@ static int mpp_task_run(struct mpp_dev *mpp, ret = mpp_iommu_attach(mpp->iommu_info); if (ret) { dev_err(mpp->dev, "mpp_iommu_attach failed\n"); + mpp_reset_up_read(mpp->reset_group); return -ENODATA; } @@ -834,11 +841,6 @@ static int mpp_task_run(struct mpp_dev *mpp, if (mpp->auto_freq_en && mpp->hw_ops->set_freq) mpp->hw_ops->set_freq(mpp, task); - /* - * TODO: Lock the reader locker of the device resource lock here, - * release at the finish operation - */ - mpp_reset_down_read(mpp->reset_group); mpp_iommu_dev_activate(mpp->iommu_info, mpp); if (mpp->dev_ops->run) From 54ff36c469979af1c97a0467841e1de3048a7ab7 Mon Sep 17 00:00:00 2001 From: Yandong Lin Date: Thu, 3 Aug 2023 11:10:17 +0800 Subject: [PATCH 19/22] video: rockchip: mpp: fix irq on poweroff for rkvdec2_link rkvdec2_link_power_off(): power_enabled = 0 -> disable irq -> power off rkvdec2_link_irq(): if power_enabled == 0 -> return and not clear irq there is a corner case: 1. after power_enabled flag set to 0 and before disable irq 2. irq coming 3. irq return and not clear irq 4. repeat step 2 Signed-off-by: Yandong Lin Change-Id: I284bf40acb19e0c48cf04e526a534fec6383eb11 --- drivers/video/rockchip/mpp/mpp_rkvdec2_link.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 339e7086e1a8..3a348ba87ca0 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -517,11 +517,6 @@ static int rkvdec2_link_irq(struct mpp_dev *mpp) struct rkvdec_link_dev *link_dec = dec->link_dec; u32 irq_status = 0; - if (!atomic_read(&link_dec->power_enabled)) { - dev_info(link_dec->dev, "irq on power off\n"); - return -1; - } - irq_status = readl(link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); if (irq_status & RKVDEC_LINK_BIT_IRQ_RAW) { From 2a8db47d13ccab9d8b5477e2f51e7302d74bac3b Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 20 Jul 2023 09:20:45 +0800 Subject: [PATCH 20/22] mmc: dw_mmc: Add some safe delay for releasing power leak Add some delay for some broken card which need long time to release the remain power leak. 200ms is very safe, no need to bother device tree property, as it depends on card not board. Fixes: 60c9e5240f35 ("mmc: dw_mmc: Add normal and idle pinctrl control") Change-Id: I5437945cd860674be860d246200e15eed9d91e03 Signed-off-by: Shawn Lin Signed-off-by: Yifeng Zhao --- drivers/mmc/host/dw_mmc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index fde49464a637..a88d9b908d97 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1468,7 +1468,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct dw_mci_slot *slot = mmc_priv(mmc); const struct dw_mci_drv_data *drv_data = slot->host->drv_data; - u32 regs; + u32 regs, power_off_delay; int ret; switch (ios->bus_width) { @@ -1507,8 +1507,14 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) switch (ios->power_mode) { case MMC_POWER_UP: - if (!IS_ERR_OR_NULL(slot->host->pinctrl)) - pinctrl_select_state(slot->host->pinctrl, slot->host->idle_state); + if (dw_mci_get_cd(mmc) && !IS_ERR_OR_NULL(slot->host->pinctrl)) { + if (!pinctrl_select_state(slot->host->pinctrl, slot->host->idle_state)) { + if (device_property_read_u32(slot->host->dev, "power-off-delay-ms", + &power_off_delay)) + power_off_delay = 200; + msleep(power_off_delay); + } + } if (!IS_ERR(mmc->supply.vmmc)) { ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, From 84a85ea4a6d50c21116b84088ea7aa7f12334cfd Mon Sep 17 00:00:00 2001 From: Shiqin Chen Date: Wed, 2 Aug 2023 15:49:50 +0800 Subject: [PATCH 21/22] arm64: dts: rockchip: rk3568-toybrick-sd0: change gmac1 txdelay Signed-off-by: Shiqin Chen Change-Id: I8fbaf468dc41b4da91345a089c0fcd3eb560a6b4 --- arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi index 13692175b129..6041d1a1994c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568-toybrick-sd0.dtsi @@ -207,7 +207,7 @@ &gmac1m1_rgmii_bus ð1m1_pins>; - tx_delay = <0x47>; + tx_delay = <0x30>; rx_delay = <0x28>; phy-handle = <&rgmii_phy1>; From 8405687e7c2caa1b86236d98de602974388942c1 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Thu, 3 Aug 2023 15:09:07 +0800 Subject: [PATCH 22/22] rtc: rockchip: fix up the rtc compensation value rtc compensation value needs to be converted to a bcd code. Signed-off-by: Elaine Zhang Change-Id: Ic24a5ba0c31c42b804d1efa65702e680bae26630 --- drivers/rtc/rtc-rockchip.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-rockchip.c b/drivers/rtc/rtc-rockchip.c index 5fa4f1a85b72..8dd82ef4d45f 100644 --- a/drivers/rtc/rtc-rockchip.c +++ b/drivers/rtc/rtc-rockchip.c @@ -508,7 +508,7 @@ static void rockchip_rtc_compensation_delay_work(struct work_struct *work) c_mon = DIV_ROUND_CLOSEST(30 * 24 * tcamp, 32768); if (c_hour > 1) - rockchip_rtc_write(rtc->regmap, RTC_COMP_H, (c_hour - 1) | trim_dir); + rockchip_rtc_write(rtc->regmap, RTC_COMP_H, bin2bcd((c_hour - 1)) | trim_dir); else rockchip_rtc_write(rtc->regmap, RTC_COMP_H, CLK32K_NO_COMP); @@ -522,7 +522,7 @@ static void rockchip_rtc_compensation_delay_work(struct work_struct *work) if (c_det_day > 1) rockchip_rtc_write(rtc->regmap, RTC_COMP_D, - (c_det_day - 1) | trim_dir); + bin2bcd((c_det_day - 1)) | trim_dir); else rockchip_rtc_write(rtc->regmap, RTC_COMP_D, CLK32K_NO_COMP); @@ -536,7 +536,7 @@ static void rockchip_rtc_compensation_delay_work(struct work_struct *work) if (c_det_mon) rockchip_rtc_write(rtc->regmap, RTC_COMP_M, - (c_det_mon - 1) | trim_dir); + bin2bcd((c_det_mon - 1)) | trim_dir); else rockchip_rtc_write(rtc->regmap, RTC_COMP_M, CLK32K_NO_COMP);