diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.yaml b/Documentation/devicetree/bindings/spi/spi-rockchip.yaml index 34f9d13de332..c67fd42e42bb 100644 --- a/Documentation/devicetree/bindings/spi/spi-rockchip.yaml +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.yaml @@ -109,6 +109,10 @@ properties: description: GPIO spec for the spi slave ready signal. maxItems: 1 + rockchip,autosuspend-delay-ms: + default: 0 + description: Set pm runtime autosuspend value in milliseconds. + required: - compatible - reg diff --git a/arch/arm/boot/dts/rv1106.dtsi b/arch/arm/boot/dts/rv1106.dtsi index 1cf580756db0..ff475c11903d 100644 --- a/arch/arm/boot/dts/rv1106.dtsi +++ b/arch/arm/boot/dts/rv1106.dtsi @@ -1423,6 +1423,7 @@ snps,dis-tx-ipgap-linecheck-quirk; snps,usb2-gadget-lpm-disable; snps,usb2-lpm-disable; + snps,parkmode-disable-hs-quirk; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/rv1126.dtsi b/arch/arm/boot/dts/rv1126.dtsi index 1474f438074f..141631c1e57c 100644 --- a/arch/arm/boot/dts/rv1126.dtsi +++ b/arch/arm/boot/dts/rv1126.dtsi @@ -2556,6 +2556,7 @@ snps,tx-fifo-resize; snps,xhci-trb-ent-quirk; snps,usb2-lpm-disable; + snps,parkmode-disable-hs-quirk; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-excavator-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-excavator-sapphire.dtsi index c12a87057876..59cdade78801 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-excavator-sapphire.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-excavator-sapphire.dtsi @@ -32,7 +32,7 @@ "Speaker", "Speaker Power", "IN1P", "Main Mic", "IN2P", "Headset Mic", - "IN2N", "Headset Mic"; + "IN2N", "Headset Mic", "Headset Mic", "micbias1"; play-pause-key { label = "playpause"; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi index 9fdf361bade2..fca870290aff 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi @@ -4135,9 +4135,9 @@ nvmem-cells = <&codec_leakage>, <&venc_opp_info>; nvmem-cell-names = "leakage", "opp-info"; rockchip,leakage-voltage-sel = < - 1 8 0 - 9 20 1 - 21 254 2 + 1 15 0 + 16 25 1 + 26 254 2 >; rockchip,grf = <&sys_grf>; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index 99c758ff264d..20040bc5e5c2 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -3160,6 +3160,11 @@ static int dw_hdmi_ctrl_show(struct seq_file *s, void *v) struct dw_hdmi_qp *hdmi = s->private; u32 i = 0, j = 0, val = 0; + if (hdmi->disabled) { + dev_err(hdmi->dev, "hdmi is disabled\n"); + return -EACCES; + } + seq_puts(s, "\n---------------------------------------------------"); for (i = 0; i < ARRAY_SIZE(hdmi_reg_table); i++) { @@ -3191,6 +3196,11 @@ dw_hdmi_ctrl_write(struct file *file, const char __user *buf, u32 reg, val; char kbuf[25]; + if (hdmi->disabled) { + dev_err(hdmi->dev, "hdmi is disabled\n"); + return -EACCES; + } + if (count > 24) { dev_err(hdmi->dev, "out of buf range\n"); return count; diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index 83c186eccd95..e386c39537ae 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -1213,6 +1213,9 @@ static int dw_mipi_dsi2_get_dsc_params_from_sink(struct dw_mipi_dsi2 *dsi2, dsi2->slave->dsc_enable = dsi2->dsc_enable; } + if (!dsi2->dsc_enable) + return 0; + of_property_read_u32(np, "slice-width", &dsi2->slice_width); of_property_read_u32(np, "slice-height", &dsi2->slice_height); of_property_read_u8(np, "version-major", &dsi2->version_major); @@ -1248,8 +1251,21 @@ static int dw_mipi_dsi2_get_dsc_params_from_sink(struct dw_mipi_dsi2 *dsi2, len -= header->payload_length; } + if (!pps) { + dev_err(dsi2->dev, "not found dsc pps definition\n"); + return -EINVAL; + } + dsi2->pps = pps; + if (dsi2->slave) { + u16 pic_width = be16_to_cpu(pps->pic_width) / 2; + + dsi2->pps->pic_width = cpu_to_be16(pic_width); + dev_info(dsi2->dev, "dsc pic_width change from %d to %d\n", + pic_width * 2, pic_width); + } + return 0; } diff --git a/drivers/rkflash/sfc.c b/drivers/rkflash/sfc.c index 44a14792a90d..19773a8ec0fc 100644 --- a/drivers/rkflash/sfc.c +++ b/drivers/rkflash/sfc.c @@ -12,6 +12,7 @@ #define SFC_MAX_IOSIZE_VER4 (0xFFFFFFFF) static void __iomem *g_sfc_reg; +static u32 sfc_version; static void sfc_reset(void) { @@ -75,6 +76,7 @@ int sfc_init(void __iomem *reg_addr) if (sfc_get_version() >= SFC_VER_4) writel(1, g_sfc_reg + SFC_LEN_CTRL); + sfc_version = sfc_get_version(); return SFC_OK; } @@ -116,7 +118,7 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size) op->sfctrl.d32 |= 0x2; cmd.b.datasize = size; - if (sfc_get_version() >= SFC_VER_4) + if (sfc_version >= SFC_VER_4) writel(size, g_sfc_reg + SFC_LEN_EXT); else cmd.b.datasize = size; @@ -238,6 +240,8 @@ int sfc_request(struct rk_sfc_op *op, u32 addr, void *data, u32 size) break; } + if (!bytes) + break; sfc_delay(1); if (timeout++ > 10000) { diff --git a/drivers/rkflash/sfc_nand.c b/drivers/rkflash/sfc_nand.c index f0eeec956fd8..4accf3d791c6 100644 --- a/drivers/rkflash/sfc_nand.c +++ b/drivers/rkflash/sfc_nand.c @@ -311,7 +311,7 @@ static int sfc_nand_write_feature(u32 addr, u8 status) return ret; } -static int sfc_nand_wait_busy(u8 *data, int timeout) +static int sfc_nand_wait_busy_sleep(u8 *data, int timeout, int sleep_us) { int ret; int i; @@ -319,7 +319,9 @@ static int sfc_nand_wait_busy(u8 *data, int timeout) *data = 0; - for (i = 0; i < timeout; i++) { + for (i = 0; i < timeout; i += sleep_us) { + usleep_range(sleep_us, sleep_us + 50); + ret = sfc_nand_read_feature(0xC0, &status); if (ret != SFC_OK) @@ -329,8 +331,6 @@ static int sfc_nand_wait_busy(u8 *data, int timeout) if (!(status & (1 << 0))) return SFC_OK; - - sfc_delay(1); } return SFC_NAND_WAIT_TIME_OUT; @@ -794,7 +794,7 @@ u32 sfc_nand_erase_block(u8 cs, u32 addr) if (ret != SFC_OK) return ret; - ret = sfc_nand_wait_busy(&status, 1000 * 1000); + ret = sfc_nand_wait_busy_sleep(&status, 1000 * 1000, 1000); if (status & (1 << 2)) return SFC_NAND_PROG_ERASE_ERROR; @@ -851,6 +851,7 @@ u32 sfc_nand_prog_page_raw(u8 cs, u32 addr, u32 *p_page_buf) op.sfctrl.d32 = 0; op.sfctrl.b.datalines = sfc_nand_dev.prog_lines; op.sfctrl.b.addrbits = 16; + op.sfctrl.b.enbledma = 0; plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0; sfc_request(&op, plane, p_page_buf, page_size); @@ -880,7 +881,8 @@ u32 sfc_nand_prog_page_raw(u8 cs, u32 addr, u32 *p_page_buf) if (ret != SFC_OK) return ret; - ret = sfc_nand_wait_busy(&status, 1000 * 1000); + ret = sfc_nand_wait_busy_sleep(&status, 1000 * 1000, 200); + if (status & (1 << 3)) return SFC_NAND_PROG_ERASE_ERROR; @@ -931,7 +933,10 @@ u32 sfc_nand_read(u32 row, u32 *p_page_buf, u32 column, u32 len) sfc_get_version() < SFC_VER_3) sfc_nand_rw_preset(); - sfc_nand_wait_busy(&status, 1000 * 1000); + sfc_nand_wait_busy_sleep(&status, 1000 * 1000, 50); + if (sfc_nand_dev.manufacturer == 0x01 && status) + sfc_nand_wait_busy_sleep(&status, 1000 * 1000, 50); + ecc_result = p_nand_info->ecc_status(); op.sfcmd.d32 = 0; @@ -942,6 +947,7 @@ u32 sfc_nand_read(u32 row, u32 *p_page_buf, u32 column, u32 len) op.sfctrl.d32 = 0; op.sfctrl.b.datalines = sfc_nand_dev.read_lines; op.sfctrl.b.addrbits = 16; + op.sfctrl.b.enbledma = 0; plane = p_nand_info->plane_per_die == 2 ? ((row >> 6) & 0x1) << 12 : 0; ret = sfc_request(&op, plane | column, p_page_buf, len); diff --git a/drivers/soc/rockchip/rockchip_amp.c b/drivers/soc/rockchip/rockchip_amp.c index 0d1cb29ac207..3bb0920eab42 100644 --- a/drivers/soc/rockchip/rockchip_amp.c +++ b/drivers/soc/rockchip/rockchip_amp.c @@ -111,29 +111,29 @@ static ssize_t boot_cpu_show(struct device *dev, static void cpu_status_print(unsigned long cpu_id, struct arm_smccc_res *res) { if (res->a0) { - pr_info("get cpu-0x%lx status(%lx) error!\n", cpu_id, res->a0); + pr_info("failed to get cpu[%lx] status, ret=%lx!\n", cpu_id, res->a0); return; } if (res->a1 == AMP_CPU_STATUS_AMP_DIS) - pr_info("cpu-0x%lx amp is disable (%ld)\n", cpu_id, res->a1); + pr_info("cpu[%lx] amp is disabled (%ld)\n", cpu_id, res->a1); else if (res->a1 == AMP_CPU_STATUS_EN) - pr_info("cpu-0x%lx amp is enable (%ld)\n", cpu_id, res->a1); + pr_info("cpu[%lx] amp is enabled (%ld)\n", cpu_id, res->a1); else if (res->a1 == AMP_CPU_STATUS_ON) - pr_info("cpu-0x%lx amp: cpu is on (%ld)\n", cpu_id, res->a1); + pr_info("cpu[%lx] amp: cpu is on (%ld)\n", cpu_id, res->a1); else if (res->a1 == AMP_CPU_STATUS_OFF) - pr_info("cpu-0x%lx amp: cpu is off(%ld)\n", cpu_id, res->a1); + pr_info("cpu[%lx] amp: cpu is off(%ld)\n", cpu_id, res->a1); else - pr_info("cpu-0x%lx status(%ld) is error\n", cpu_id, res->a1); + pr_info("cpu[%lx] amp status(%ld) is error\n", cpu_id, res->a1); if (res->a2 == RK_CPU_STATUS_OFF) - pr_info("cpu-0x%lx status(%ld) is off\n", cpu_id, res->a2); + pr_info("cpu[%lx] status(%ld) is off\n", cpu_id, res->a2); else if (res->a2 == RK_CPU_STATUS_ON) - pr_info("cpu-0x%lx status(%ld) is on\n", cpu_id, res->a2); + pr_info("cpu[%lx] status(%ld) is on\n", cpu_id, res->a2); else if (res->a2 == RK_CPU_STATUS_BUSY) - pr_info("cpu-0x%lx status(%ld) is busy\n", cpu_id, res->a2); + pr_info("cpu[%lx] status(%ld) is busy\n", cpu_id, res->a2); else - pr_info("cpu-0x%lx status(%ld) is error\n", cpu_id, res->a2); + pr_info("cpu[%lx] status(%ld) is error\n", cpu_id, res->a2); } static ssize_t boot_cpu_store(struct device *dev, @@ -141,9 +141,9 @@ static ssize_t boot_cpu_store(struct device *dev, const char *buf, size_t count) { - char cmd[10]; - unsigned long cpu_id; struct arm_smccc_res res = {0}; + unsigned long cpu_id; + char cmd[10]; int ret, idx; ret = sscanf(buf, "%s", cmd); @@ -154,12 +154,10 @@ static ssize_t boot_cpu_store(struct device *dev, if (!strncmp(cmd, "status", strlen("status"))) { ret = sscanf(buf, "%s %lx", cmd, &cpu_id); - if (ret != 2) return -EINVAL; - res = sip_smc_get_amp_info(RK_AMP_SUB_FUNC_GET_CPU_STATUS, - cpu_id); + res = sip_smc_get_amp_info(RK_AMP_SUB_FUNC_GET_CPU_STATUS, cpu_id); cpu_status_print(cpu_id, &res); } else if (!strncmp(cmd, "off", strlen("off"))) { ret = sscanf(buf, "%s %lx", cmd, &cpu_id); @@ -167,17 +165,14 @@ static ssize_t boot_cpu_store(struct device *dev, return -EINVAL; idx = get_cpu_boot_info_idx(cpu_id); - if (idx >= 0 && cpu_boot_info[idx].en) { ret = sip_smc_amp_config(RK_AMP_SUB_FUNC_REQ_CPU_OFF, cpu_id, 0, 0); if (ret) - pr_info("requesting a cpu off is error(%d)!\n", - ret); + dev_warn(dev, "failed to request cpu[%lx] off, ret=%d!\n", cpu_id, ret); } } else if (!strncmp(cmd, "on", strlen("on"))) { ret = sscanf(buf, "%s %lx", cmd, &cpu_id); - if (ret != 2) return -EINVAL; @@ -188,11 +183,14 @@ static ssize_t boot_cpu_store(struct device *dev, cpu_boot_info[idx].entry, 0); if (ret) - pr_info("booting up a cpu is error(%d)!\n", - ret); + dev_warn(dev, "Brought up cpu[%lx] failed, ret=%d\n", cpu_id, ret); + else + pr_info("Brought up cpu[%lx] ok.\n", cpu_id); + } else { + dev_warn(dev, "cpu[%lx] is unavailable\n", cpu_id); } } else { - pr_info("unsupported cmd(%s)\n", cmd); + dev_warn(dev, "unsupported cmd(%s)\n", cmd); } return count; @@ -207,46 +205,53 @@ static int rockchip_amp_boot_cpus(struct device *dev, struct device_node *cpu_node, int idx) { u64 cpu_entry, cpu_id; - u32 cpu_mode; + u32 cpu_mode, boot_on; int ret; if (idx >= CONFIG_NR_CPUS) return -1; + if (of_property_read_u64_array(cpu_node, "id", &cpu_id, 1)) { + dev_warn(dev, "failed to get 'id'\n"); + return -1; + } + if (of_property_read_u64_array(cpu_node, "entry", &cpu_entry, 1)) { - dev_warn(dev, "can not get the entry\n"); + dev_warn(dev, "failed to get cpu[%llx] 'entry'\n", cpu_id); return -1; } if (!cpu_entry) { - dev_warn(dev, "cpu-entry is 0\n"); - return -1; - } - - if (of_property_read_u64_array(cpu_node, "id", &cpu_id, 1)) { - dev_warn(dev, "can not get the cpu id\n"); + dev_warn(dev, "invalid cpu[%llx] 'entry': 0\n", cpu_id); return -1; } if (of_property_read_u32_array(cpu_node, "mode", &cpu_mode, 1)) { - dev_warn(dev, "can not get the cpu mode\n"); + dev_warn(dev, "failed to get cpu[%llx] 'mode'\n", cpu_id); return -1; } + if (of_property_read_u32_array(cpu_node, "boot-on", &boot_on, 1)) + boot_on = 1; /* compatible old action */ + cpu_boot_info[idx].entry = cpu_entry; cpu_boot_info[idx].mode = cpu_mode; cpu_boot_info[idx].cpu_id = cpu_id; ret = sip_smc_amp_config(RK_AMP_SUB_FUNC_CFG_MODE, cpu_id, cpu_mode, 0); if (ret) { - dev_warn(dev, "setting cpu mode is error(%d)!\n", ret); + dev_warn(dev, "failed to set cpu mode, ret=%d\n", ret); return ret; } - ret = sip_smc_amp_config(RK_AMP_SUB_FUNC_CPU_ON, cpu_id, cpu_entry, 0); - if (ret) { - dev_warn(dev, "booting up a cpu is error(%d)!\n", ret); - return ret; + if (boot_on) { + ret = sip_smc_amp_config(RK_AMP_SUB_FUNC_CPU_ON, cpu_id, cpu_entry, 0); + if (ret) { + dev_warn(dev, "Brought up cpu[%llx] failed, ret=%d\n", cpu_id, ret); + return ret; + } else { + pr_info("Brought up cpu[%llx] ok.\n", cpu_id); + } } cpu_boot_info[idx].en = 1; @@ -507,9 +512,9 @@ exit: static int rockchip_amp_probe(struct platform_device *pdev) { - struct rkamp_device *rkamp_dev = NULL; - int ret, i, idx = 0; struct device_node *cpus_node, *cpu_node; + struct rkamp_device *rkamp_dev; + int ret, i, idx = 0; rkamp_dev = devm_kzalloc(&pdev->dev, sizeof(*rkamp_dev), GFP_KERNEL); if (!rkamp_dev) @@ -518,18 +523,20 @@ static int rockchip_amp_probe(struct platform_device *pdev) rkamp_dev->num_clks = devm_clk_bulk_get_all(&pdev->dev, &rkamp_dev->clks); if (rkamp_dev->num_clks < 0) return -ENODEV; + ret = clk_bulk_prepare_enable(rkamp_dev->num_clks, rkamp_dev->clks); if (ret) return dev_err_probe(&pdev->dev, ret, "failed to prepare enable clks: %d\n", ret); pm_runtime_enable(&pdev->dev); - rkamp_dev->num_pds = of_count_phandle_with_args(pdev->dev.of_node, "power-domains", - "#power-domain-cells"); - + rkamp_dev->num_pds = + of_count_phandle_with_args(pdev->dev.of_node, "power-domains", + "#power-domain-cells"); if (rkamp_dev->num_pds > 0) { - rkamp_dev->pd_dev = devm_kmalloc_array(&pdev->dev, rkamp_dev->num_pds, - sizeof(*rkamp_dev->pd_dev), GFP_KERNEL); + rkamp_dev->pd_dev = + devm_kmalloc_array(&pdev->dev, rkamp_dev->num_pds, + sizeof(*rkamp_dev->pd_dev), GFP_KERNEL); if (!rkamp_dev->pd_dev) return -ENOMEM; @@ -550,13 +557,10 @@ static int rockchip_amp_probe(struct platform_device *pdev) } cpus_node = of_get_child_by_name(pdev->dev.of_node, "amp-cpus"); - if (cpus_node) { for_each_available_child_of_node(cpus_node, cpu_node) { - if (!rockchip_amp_boot_cpus(&pdev->dev, cpu_node, - idx)) { + if (!rockchip_amp_boot_cpus(&pdev->dev, cpu_node, idx)) idx++; - } } of_node_put(cpus_node); } @@ -576,8 +580,8 @@ static int rockchip_amp_probe(struct platform_device *pdev) static int rockchip_amp_remove(struct platform_device *pdev) { - int i; struct rkamp_device *rkamp_dev = platform_get_drvdata(pdev); + int i; clk_bulk_disable_unprepare(rkamp_dev->num_clks, rkamp_dev->clks); diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 5c97e2bb0d96..66d04ee4fe5f 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -982,6 +982,7 @@ static int rockchip_spi_probe(struct platform_device *pdev) bool slave_mode; struct pinctrl *pinctrl = NULL; const struct rockchip_spi_quirks *quirks_cfg; + u32 val; slave_mode = of_property_read_bool(np, "spi-slave"); @@ -1109,6 +1110,13 @@ static int rockchip_spi_probe(struct platform_device *pdev) if (quirks_cfg) rs->max_baud_div_in_cpha = quirks_cfg->max_baud_div_in_cpha; + if (!device_property_read_u32(&pdev->dev, "rockchip,autosuspend-delay-ms", &val)) { + if (val > 0) { + pm_runtime_set_autosuspend_delay(&pdev->dev, val); + pm_runtime_use_autosuspend(&pdev->dev); + } + } + pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev);