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 8a71ba608617..add361c0557f 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -2073,11 +2073,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 >; @@ -2147,14 +2147,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>; @@ -2185,11 +2177,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>; 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 { 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>; diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index f42667ad83d4..ce5a1c013865 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 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_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; 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) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 865a7f461b2b..15616b5f1549 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -1686,10 +1686,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) { @@ -1717,8 +1721,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); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c index 357b20b9fdfb..8e186333b815 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) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 9b280c33db86..a4888d986069 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -11082,6 +11082,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) @@ -11090,6 +11091,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/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index a610821c8ff2..00eb807bea4a 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); void gic_enable_of_quirks(const struct device_node *np, @@ -99,8 +103,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 324f18d06639..44b2d7d9180b 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -48,6 +48,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; @@ -486,10 +519,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); @@ -842,6 +894,11 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, struct gic_chip_data *gic = irq_data_get_irq_chip_data(d); unsigned int cpu; +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return -EINVAL; +#endif + if (unlikely(gic != &gic_data[0])) return -EINVAL; @@ -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: diff --git a/drivers/media/i2c/sc230ai.c b/drivers/media/i2c/sc230ai.c index 4cf8e3d84249..43ea5ee00b0e 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; @@ -1395,7 +1392,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, @@ -1534,7 +1531,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, 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) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a243c5094802..20c7ba16ac01 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1505,7 +1505,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) { @@ -1544,8 +1544,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, 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) { diff --git a/drivers/rtc/rtc-rockchip.c b/drivers/rtc/rtc-rockchip.c index 6ffcacb1e8ff..94399461e5a3 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); 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/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/drivers/soc/rockchip/rockchip_pm_config.c b/drivers/soc/rockchip/rockchip_pm_config.c index 5f8e98a3aaa8..9020a5c1630a 100644 --- a/drivers/soc/rockchip/rockchip_pm_config.c +++ b/drivers/soc/rockchip/rockchip_pm_config.c @@ -28,6 +28,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, @@ -53,6 +57,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",}, @@ -169,6 +198,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; @@ -273,6 +411,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/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); diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index 7c55c14e5368..acc9b07b65c7 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) 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) { 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 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) 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; 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 */ 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 {