Merge branch 'CR_1874_v4l2_515_changhuang.liang' into 'jh7110-5.15.y-devel'
authorandy.hu <andy.hu@starfivetech.com>
Fri, 26 Aug 2022 02:24:31 +0000 (02:24 +0000)
committerandy.hu <andy.hu@starfivetech.com>
Fri, 26 Aug 2022 02:24:31 +0000 (02:24 +0000)
CR_1874_v4l2_515_changhuang.liang

See merge request sdk/linux!406

26 files changed:
Documentation/devicetree/bindings/riscv/starfive-jh7110.yaml [new file with mode: 0644]
MAINTAINERS
arch/riscv/boot/dts/starfive/Makefile
arch/riscv/boot/dts/starfive/jh7110-clk.dtsi [changed mode: 0644->0755]
arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts [new file with mode: 0644]
arch/riscv/boot/dts/starfive/jh7110.dtsi
drivers/Kconfig
drivers/clk/starfive/clk-starfive-jh7110-stg.c
drivers/cpufreq/Kconfig
drivers/cpufreq/Kconfig.riscv [new file with mode: 0644]
drivers/cpufreq/Makefile
drivers/cpufreq/cpufreq-dt-platdev.c
drivers/cpufreq/starfive-cpufreq.c [new file with mode: 0644]
drivers/crypto/starfive/jh7110/jh7110-pka.c
drivers/crypto/starfive/jh7110/jh7110-sha.c
drivers/crypto/starfive/jh7110/jh7110-str.h
drivers/gpu/drm/verisilicon/inno_hdmi.c
drivers/gpu/drm/verisilicon/vs_dc.c
drivers/media/platform/starfive/v4l2_driver/stf_isp_ioctl.h
drivers/media/platform/starfive/v4l2_driver/stf_video.c
drivers/media/platform/starfive/v4l2_driver/stf_vin.c
drivers/media/platform/starfive/v4l2_driver/stfcamss.c
drivers/media/platform/starfive/v4l2_driver/stfcamss.h
include/dt-bindings/clock/starfive-jh7110-clkgen.h
sound/soc/codecs/wm8960.c
sound/soc/dwc/dwc-i2s.c

diff --git a/Documentation/devicetree/bindings/riscv/starfive-jh7110.yaml b/Documentation/devicetree/bindings/riscv/starfive-jh7110.yaml
new file mode 100644 (file)
index 0000000..4402530
--- /dev/null
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/riscv/starfive.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7110 SoC-based boards
+
+maintainers:
+  - Michael Zhu <michael.zhu@starfivetech.com>
+  - Jianlong Huang <jianlong.huang@starfivetech.com>
+
+description:
+  StarFive JH7110 SoC-based boards
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+      - items:
+          - const: starfive,jh7110
+          - const: starfive,jh7110-evb
+          - const: starfive,visionfive-v2
+
+additionalProperties: true
+
+...
index 12ded5c..95a1d9d 100644 (file)
@@ -20836,3 +20836,14 @@ Q:     http://patchwork.kernel.org/project/LKML/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 F:     *
 F:     */
+
+STARFIVE JH7110 EVB USB DEVICE SUPPORT
+M:     Jianlong Huang <jianlong.huang@starfivetech.com>
+S:     Maintained
+F:     arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts
+
+STARFIVE JH7110 SOC BOARDS
+M:     Jianlong Huang <jianlong.huang@starfivetech.com>
+S:     Maintained
+F:     Documentation/devicetree/bindings/riscv/starfive-jh7110.yaml
+
index ed9df6b..fc946b3 100644 (file)
@@ -10,4 +10,5 @@ dtb-$(CONFIG_SOC_STARFIVE_JH7110) += jh7110-visionfive-v2.dtb \
                                jh7110-evb-spi-uart2.dtb        \
                                jh7110-evb-uart1-rgb2hdmi.dtb   \
                                jh7110-evb-uart4-emmc-spdif.dtb \
-                               jh7110-evb-uart5-pwm-i2c-tdm.dtb
+                               jh7110-evb-uart5-pwm-i2c-tdm.dtb\
+                               jh7110-evb-usbdevice.dtb
old mode 100644 (file)
new mode 100755 (executable)
index 9c9aade..9461520
                clock-frequency = <50000000>;
        };
 
-       stg_apb: stg_apb {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <51200000>;
-       };
-
        gmac0_rmii_refin: gmac0_rmii_refin {
                compatible = "fixed-clock";
                #clock-cells = <0>;
diff --git a/arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts b/arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts
new file mode 100644 (file)
index 0000000..a591bec
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Copyright (C) 2022 Hal Feng <hal.feng@starfivetech.com>
+ */
+
+/dts-v1/;
+#include "jh7110-evb.dtsi"
+
+/ {
+       model = "StarFive JH7110 EVB";
+       compatible = "starfive,jh7110-evb", "starfive,jh7110";
+};
+
+/* default sd card */
+&sdio0 {
+       clock-frequency = <102400000>;
+       max-frequency = <200000000>;
+       card-detect-delay = <300>;
+       bus-width = <4>;
+       broken-cd;
+       cap-sd-highspeed;
+       post-power-on-delay-ms = <200>;
+       status = "okay";
+};
+
+&usbdrd30 {
+       dr_mode = "peripheral"; /*host or peripheral*/
+       status = "okay";
+};
+
+
+&pcie1 {
+       status = "okay";
+};
index e74f1d3..fc25056 100755 (executable)
        #address-cells = <2>;
        #size-cells = <2>;
 
+       cluster0_opp: opp-table-0 {
+                       compatible = "operating-points-v2";
+                       opp-shared;
+                       opp-375000000 {
+                                       opp-hz = /bits/ 64 <375000000>;
+                                       opp-microvolt = <880000>;
+                       };
+                       opp-500000000 {
+                                       opp-hz = /bits/ 64 <500000000>;
+                                       opp-microvolt = <880000>;
+                       };
+                       opp-625000000 {
+                                       opp-hz = /bits/ 64 <625000000>;
+                                       opp-microvolt = <880000>;
+                       };
+                       opp-750000000 {
+                                       opp-hz = /bits/ 64 <750000000>;
+                                       opp-microvolt = <880000>;
+                       };
+                       opp-875000000 {
+                                       opp-hz = /bits/ 64 <875000000>;
+                                       opp-microvolt = <880000>;
+                       };
+                       opp-1000000000 {
+                                       opp-hz = /bits/ 64 <1000000000>;
+                                       opp-microvolt = <900000>;
+                       };
+                       opp-1250000000 {
+                                       opp-hz = /bits/ 64 <1250000000>;
+                                       opp-microvolt = <950000>;
+                       };
+                       opp-1375000000 {
+                                       opp-hz = /bits/ 64 <1375000000>;
+                                       opp-microvolt = <1000000>;
+                       };
+                       opp-1500000000 {
+                                       opp-hz = /bits/ 64 <1500000000>;
+                                       opp-microvolt = <1100000>;
+                       };
+                       opp-1625000000 {
+                                       opp-hz = /bits/ 64 <1625000000>;
+                                       opp-microvolt = <1100000>;
+                       };
+                       opp-1750000000 {
+                                       opp-hz = /bits/ 64 <1750000000>;
+                                       opp-microvolt = <1200000>;
+                       };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        riscv,isa = "rv64imafdc";
                        tlb-split;
                        status = "okay";
+                       operating-points-v2 = <&cluster0_opp>;
 
                        cpu1intctrl: interrupt-controller {
                                #interrupt-cells = <1>;
                        riscv,isa = "rv64imafdc";
                        tlb-split;
                        status = "okay";
+                       operating-points-v2 = <&cluster0_opp>;
 
                        cpu2intctrl: interrupt-controller {
                                #interrupt-cells = <1>;
                        riscv,isa = "rv64imafdc";
                        tlb-split;
                        status = "okay";
+                       operating-points-v2 = <&cluster0_opp>;
 
                        cpu3intctrl: interrupt-controller {
                                #interrupt-cells = <1>;
                        riscv,isa = "rv64imafdc";
                        tlb-split;
                        status = "okay";
+                       operating-points-v2 = <&cluster0_opp>;
 
                        cpu4intctrl: interrupt-controller {
                                #interrupt-cells = <1>;
                                 <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
                                 <&tdm_ext>, <&mclk_ext>,
                                 <&jtag_tck_inner>, <&bist_apb>,
-                                <&stg_apb>, <&clk_rtc>,
+                                <&clk_rtc>,
                                 <&gmac0_rmii_refin>, <&gmac0_rgmii_rxin>;
                        clock-names = "osc", "gmac1_rmii_refin",
                                "gmac1_rgmii_rxin",
                                "i2srx_bclk_ext", "i2srx_lrck_ext",
                                "tdm_ext", "mclk_ext",
                                "jtag_tck_inner", "bist_apb",
-                               "stg_apb", "clk_rtc",
+                               "clk_rtc",
                                "gmac0_rmii_refin", "gmac0_rgmii_rxin";
                        #clock-cells = <1>;
                        starfive,sys-syscon = <&sys_syscon 0x18 0x1c
                        dsp@0 {
                        };
                };
+
+               stf_cpufreq: starfive,stf-cpufreq {
+                       compatible = "starfive,stf-cpufreq";
+                       clocks = <&clkgen JH7110_PLL0_OUT>,
+                                        <&clkgen JH7110_CPU_ROOT>,
+                                        <&osc>;
+                       clock-names = "pll0", "cpu_clk", "osc";
+               };
        };
 };
index f58f714..1898ff9 100644 (file)
@@ -241,4 +241,6 @@ source "drivers/e24/Kconfig"
 
 source "drivers/xrp/Kconfig"
 
+source "drivers/cpufreq/Kconfig"
+
 endmenu
index 3105ba5..9ef47fe 100755 (executable)
@@ -15,8 +15,6 @@
 
 /* external clocks */
 #define JH7110_OSC                             (JH7110_CLK_END + 0)
-/* stg external clocks */
-#define JH7110_STG_APB                         (JH7110_CLK_END + 11)
 
 static const struct jh7110_clk_data jh7110_clk_stg_data[] __initconst = {
        //hifi4
@@ -127,6 +125,9 @@ int __init clk_starfive_jh7110_stg_init(struct platform_device *pdev,
        priv->pll[PLL_OF(JH7110_STG_SYSCON_PCLK)] =
                        devm_clk_hw_register_fixed_factor(priv->dev,
                        "u0_stg_syscon_pclk", "stg_apb", 0, 1, 1);
+       priv->pll[PLL_OF(JH7110_STG_APB)] =
+                       devm_clk_hw_register_fixed_factor(priv->dev,
+                       "stg_apb", "apb_bus", 0, 1, 1);
 
        for (idx = JH7110_CLK_SYS_REG_END; idx < JH7110_CLK_STG_REG_END; idx++) {
                u32 max = jh7110_clk_stg_data[idx].max;
@@ -145,15 +146,13 @@ int __init clk_starfive_jh7110_stg_init(struct platform_device *pdev,
                for (i = 0; i < init.num_parents; i++) {
                        unsigned int pidx = jh7110_clk_stg_data[idx].parents[i];
 
-                       if (pidx < JH7110_CLK_STG_REG_END)
+                       if (pidx < JH7110_CLK_REG_END )
                                parents[i].hw = &priv->reg[pidx].hw;
                        else if ((pidx < JH7110_CLK_STG_END) &&
-                               (pidx > JH7110_CLK_SYS_END))
+                               (pidx > (JH7110_CLK_SYS_END - 1)))
                                parents[i].hw = priv->pll[PLL_OF(pidx)];
                        else if (pidx == JH7110_OSC)
                                parents[i].fw_name = "osc";
-                       else if (pidx == JH7110_STG_APB)
-                               parents[i].fw_name = "stg_apb";
                }
 
                clk->hw.init = &init;
index c3038cd..d62547d 100644 (file)
@@ -322,4 +322,8 @@ config QORIQ_CPUFREQ
          which are capable of changing the CPU's frequency dynamically.
 
 endif
+
+if RISCV
+source "drivers/cpufreq/Kconfig.riscv"
+endif
 endmenu
diff --git a/drivers/cpufreq/Kconfig.riscv b/drivers/cpufreq/Kconfig.riscv
new file mode 100644 (file)
index 0000000..b375e26
--- /dev/null
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# RISCV CPU Frequency scaling drivers
+#
+
+config RISCV_STARFIVE_CPUFREQ
+       bool "Starfive JH7110"
+       depends on SOC_STARFIVE
+       default y
+       help
+         This adds the CPUFreq driver for Starfive SoC.
+
+         If in doubt, say N.
+
+
index 48ee585..ecbd06c 100644 (file)
@@ -100,6 +100,10 @@ obj-$(CONFIG_PPC_PASEMI_CPUFREQ)   += pasemi-cpufreq.o
 obj-$(CONFIG_POWERNV_CPUFREQ)          += powernv-cpufreq.o
 
 ##################################################################################
+# Riscv platform drivers
+obj-$(CONFIG_RISCV_STARFIVE_CPUFREQ)   += starfive-cpufreq.o
+
+##################################################################################
 # Other platform drivers
 obj-$(CONFIG_BMIPS_CPUFREQ)            += bmips-cpufreq.o
 obj-$(CONFIG_IA64_ACPI_CPUFREQ)                += ia64-acpi-cpufreq.o
index ca1d103..5cbdeb5 100644 (file)
@@ -160,6 +160,7 @@ static const struct of_device_id blocklist[] __initconst = {
        { .compatible = "qcom,apq8064", },
        { .compatible = "qcom,msm8974", },
        { .compatible = "qcom,msm8960", },
+       { .compatible = "starfive,jh7110", },
 
        { }
 };
diff --git a/drivers/cpufreq/starfive-cpufreq.c b/drivers/cpufreq/starfive-cpufreq.c
new file mode 100644 (file)
index 0000000..acfe11c
--- /dev/null
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2022 StarFive Technology Co., Ltd.
+ *
+ * Starfive CPUfreq Support
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+#include <linux/module.h>
+
+#define VOLT_TOL               (10000)
+
+struct stf_cpu_dvfs_info {
+       struct regulator *vddcpu;
+       struct clk *cpu_clk;
+       struct clk *pll0_clk;
+       struct clk *osc_clk;
+       unsigned long regulator_latency;
+       struct device *cpu_dev;
+       struct cpumask cpus;
+};
+
+static int stf_cpufreq_set_target_index(struct cpufreq_policy *policy,
+                                       unsigned int index)
+{
+       struct cpufreq_frequency_table *freq_table = policy->freq_table;
+       struct stf_cpu_dvfs_info *info = cpufreq_get_driver_data();
+       struct dev_pm_opp *opp;
+       unsigned long old_freq, new_freq;
+       int old_vdd, target_vdd, ret;
+
+       old_freq = clk_get_rate(info->cpu_clk);
+       old_vdd = regulator_get_voltage(info->vddcpu);
+       if (old_vdd < 0) {
+               pr_err("Invalid cpu regulator value: %d\n", old_vdd);
+               return old_vdd;
+       }
+
+       new_freq = freq_table[index].frequency * 1000;
+       opp = dev_pm_opp_find_freq_ceil(info->cpu_dev, &new_freq);
+       if (IS_ERR(opp)) {
+               pr_err("Failed to find OPP for %ld\n", new_freq);
+               return PTR_ERR(opp);
+       }
+       target_vdd = dev_pm_opp_get_voltage(opp);
+       dev_pm_opp_put(opp);
+
+
+       if (info->vddcpu && new_freq > old_freq) {
+               ret = regulator_set_voltage(info->vddcpu,
+                                          target_vdd, target_vdd + VOLT_TOL);
+               if (ret != 0) {
+                       pr_err("Failed to set vddcpu for %ldkHz: %d\n",
+                              new_freq, ret);
+                       return ret;
+               }
+       }
+
+       if (clk_set_parent(policy->clk, info->osc_clk))
+               pr_err("cpu set parent osc failed\n");
+
+       ret = clk_set_rate(info->pll0_clk, new_freq);
+       if (ret < 0) {
+               pr_err("Failed to set rate %ldkHz: %d\n",
+                      new_freq, ret);
+       }
+       if (clk_set_parent(policy->clk, info->pll0_clk))
+               pr_err("cpu set parent pll0 failed\n");
+
+       if (info->vddcpu && new_freq < old_freq) {
+               ret = regulator_set_voltage(info->vddcpu,
+                                           target_vdd, target_vdd + VOLT_TOL);
+               if (ret != 0) {
+                       pr_err("Failed to set vddcpu for %ldkHz: %d\n",
+                              new_freq, ret);
+                       if (clk_set_rate(policy->clk, old_freq * 1000) < 0)
+                               pr_err("Failed to restore original clock rate\n");
+
+                       return ret;
+               }
+       }
+
+       pr_debug("Set actual frequency %lukHz\n",
+                clk_get_rate(policy->clk) / 1000);
+
+       return 0;
+}
+
+static int stf_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+       struct stf_cpu_dvfs_info *info = cpufreq_get_driver_data();
+       struct cpufreq_frequency_table *freq_table;
+       int ret;
+
+       ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
+       if (ret) {
+               pr_err("Failed to init cpufreq table for cpu%d: %d\n",
+                      policy->cpu, ret);
+               return ret;
+       }
+
+       cpumask_copy(policy->cpus, &info->cpus);
+       policy->freq_table = freq_table;
+       policy->driver_data = info;
+       policy->clk = info->cpu_clk;
+
+       return 0;
+}
+
+static int stf_cpu_dvfs_info_init(struct platform_device *pdev,
+                       struct stf_cpu_dvfs_info *info)
+{
+       struct device *dev = &pdev->dev;
+       int ret;
+       static int retry = 3;
+
+       info->vddcpu = regulator_get_optional(&pdev->dev, "cpu_vdd_0p9");
+       if (IS_ERR(info->vddcpu)) {
+               if (PTR_ERR(info->vddcpu) == -EPROBE_DEFER)
+                       dev_warn(&pdev->dev, "The cpu regulator is not ready, retry.\n");
+               else
+                       dev_err(&pdev->dev, "Failed to get regulator for cpu\n");
+               if (retry-- > 0)
+                       return -EPROBE_DEFER;
+               else
+                       return PTR_ERR(info->vddcpu);
+       }
+
+       info->cpu_clk = devm_clk_get(dev, "cpu_clk");
+       if (IS_ERR(info->cpu_clk)) {
+               dev_err(&pdev->dev, "Unable to obtain cpu_clk: %ld\n",
+                          PTR_ERR(info->cpu_clk));
+               return PTR_ERR(info->cpu_clk);
+       }
+       info->pll0_clk = devm_clk_get(dev, "pll0");
+       if (IS_ERR(info->pll0_clk)) {
+               dev_err(&pdev->dev, "Unable to obtain cpu_clk: %ld\n",
+                          PTR_ERR(info->pll0_clk));
+               return PTR_ERR(info->pll0_clk);
+       }
+
+       info->osc_clk = devm_clk_get(dev, "osc");
+       if (IS_ERR(info->osc_clk)) {
+               dev_err(&pdev->dev, "Unable to obtain osc_clk: %ld\n",
+                          PTR_ERR(info->osc_clk));
+               return PTR_ERR(info->osc_clk);
+       }
+
+       info->cpu_dev = get_cpu_device(1);
+       if (!info->cpu_dev) {
+               dev_err(&pdev->dev, "Failed to get cpu device\n");
+               return -ENODEV;
+       }
+       /* Get OPP-sharing information from "operating-points-v2" bindings */
+       ret = dev_pm_opp_of_get_sharing_cpus(info->cpu_dev, &info->cpus);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to get OPP-sharing information for cpu\n");
+               return -EINVAL;
+       }
+
+       ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);
+       if (ret) {
+               pr_warn("no OPP table for cpu\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct cpufreq_driver stf_cpufreq_driver = {
+       .flags          = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+       .verify         = cpufreq_generic_frequency_table_verify,
+       .target_index   = stf_cpufreq_set_target_index,
+       .get            = cpufreq_generic_get,
+       .init           = stf_cpufreq_driver_init,
+       .name           = "stf-cpufreq",
+       .attr           = cpufreq_generic_attr,
+};
+
+static int stf_cpufreq_probe(struct platform_device *pdev)
+{
+       struct stf_cpu_dvfs_info *info;
+       int ret;
+
+       info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       ret = stf_cpu_dvfs_info_init(pdev, info);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to init stf cpu dvfs info\n");
+               return ret;
+       }
+
+       stf_cpufreq_driver.driver_data = info;
+       ret = cpufreq_register_driver(&stf_cpufreq_driver);
+       if (ret)
+               dev_err(&pdev->dev, "Failed to register stf cpufreq driver\n");
+
+       return ret;
+
+}
+
+static const struct of_device_id stf_cpufreq_match_table[] = {
+       { .compatible = "starfive,stf-cpufreq" },
+       {}
+};
+
+static struct platform_driver stf_cpufreq_plat_driver = {
+       .probe = stf_cpufreq_probe,
+       .driver = {
+               .name = "stf-cpufreq",
+               .of_match_table = stf_cpufreq_match_table,
+       },
+};
+
+static int __init stf_cpufreq_init(void)
+{
+       return platform_driver_register(&stf_cpufreq_plat_driver);
+}
+postcore_initcall(stf_cpufreq_init);
+
+MODULE_DESCRIPTION("STARFIVE CPUFREQ Driver");
+MODULE_AUTHOR("Mason Huuo <mason.huo@starfivetech.com>");
+MODULE_LICENSE("GPL v2");
+
index 7c4b3eb..1831c30 100644 (file)
@@ -24,8 +24,8 @@
 #include "jh7110-str.h"
 
 #define JH7110_RSA_KEYSZ_LEN                   (2048 >> 2)
-#define JH7110_RSA_KEY_SIZE                            (JH7110_RSA_KEYSZ_LEN * 3)
-
+#define JH7110_RSA_KEY_SIZE                    (JH7110_RSA_KEYSZ_LEN * 3)
+#define JH7110_RSA_MAX_KEYSZ                   256
 #define swap32(val) (                                          \
                     (((u32)(val) << 24) & (u32)0xFF000000) |   \
                     (((u32)(val) <<  8) & (u32)0x00FF0000) |   \
@@ -107,7 +107,6 @@ static int jh7110_rsa_domain_transfer(struct jh7110_sec_ctx *ctx, u32 *result, u
                rctx->csr.pka_csr.ie = 1;
                rctx->csr.pka_csr.start = 0x1;
                rctx->csr.pka_csr.not_r2 = 0x1;
-               //rctx->csr.pka_csr.bigendian = 1;
                jh7110_sec_write(sdev, JH7110_CRYPTO_CACR_OFFSET, rctx->csr.pka_csr.v);
 
                jh7110_pka_wait_done(sdev);
@@ -387,6 +386,13 @@ static int jh7110_rsa_enc(struct akcipher_request *req)
        struct jh7110_sec_request_ctx *rctx = akcipher_request_ctx(req);
        int ret = 0;
 
+       if (key->key_sz > JH7110_RSA_MAX_KEYSZ) {
+               akcipher_request_set_tfm(req, ctx->soft_tfm);
+               ret = crypto_akcipher_encrypt(req);
+               akcipher_request_set_tfm(req, tfm);
+               return ret;
+       }
+
        if (unlikely(!key->n || !key->e))
                return -EINVAL;
 
@@ -420,6 +426,13 @@ static int jh7110_rsa_dec(struct akcipher_request *req)
        struct jh7110_sec_request_ctx *rctx = akcipher_request_ctx(req);
        int ret = 0;
 
+       if (key->key_sz > JH7110_RSA_MAX_KEYSZ) {
+               akcipher_request_set_tfm(req, ctx->soft_tfm);
+               ret = crypto_akcipher_decrypt(req);
+               akcipher_request_set_tfm(req, tfm);
+               return ret;
+       }
+
        if (unlikely(!key->n || !key->d))
                return -EINVAL;
 
@@ -452,10 +465,10 @@ static unsigned long jh7110_rsa_enc_fn_id(unsigned int len)
        if (bitslen & 0x1f)
                return -EINVAL;
 
-       if (bitslen < 32 || bitslen > 2048)
-               return -EINVAL;
+       if (bitslen > 2048)
+               return false;
 
-       return 0;
+       return true;
 }
 
 static int jh7110_rsa_set_n(struct jh7110_rsa_key *rsa_key, const char *value,
@@ -471,15 +484,15 @@ static int jh7110_rsa_set_n(struct jh7110_rsa_key *rsa_key, const char *value,
        rsa_key->key_sz = vlen;
        ret = -EINVAL;
        /* invalid key size provided */
-       if (jh7110_rsa_enc_fn_id(rsa_key->key_sz))
-               goto err;
+       if (!jh7110_rsa_enc_fn_id(rsa_key->key_sz))
+               return 0;
 
        ret = -ENOMEM;
        rsa_key->n = kmemdup(ptr, rsa_key->key_sz, GFP_KERNEL);
        if (!rsa_key->n)
                goto err;
 
-       return 0;
+       return 1;
  err:
        rsa_key->key_sz = 0;
        rsa_key->n = NULL;
@@ -578,8 +591,9 @@ static int jh7110_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
                goto err;
 
        ret = jh7110_rsa_set_n(rsa_key, raw_key.n, raw_key.n_sz);
-       if (ret < 0)
-               goto err;
+       if (ret <= 0)
+               return ret;
+
        ret = jh7110_rsa_set_e(rsa_key, raw_key.e, raw_key.e_sz);
        if (ret < 0)
                goto err;
@@ -610,12 +624,26 @@ static int jh7110_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
 static int jh7110_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
                               unsigned int keylen)
 {
+       struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
+       int ret;
+
+       ret = crypto_akcipher_set_pub_key(ctx->soft_tfm, key, keylen);
+       if (ret)
+               return ret;
+
        return jh7110_rsa_setkey(tfm, key, keylen, false);
 }
 
 static int jh7110_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
                                unsigned int keylen)
 {
+       struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
+       int ret;
+
+       ret = crypto_akcipher_set_priv_key(ctx->soft_tfm, key, keylen);
+       if (ret)
+               return ret;
+
        return jh7110_rsa_setkey(tfm, key, keylen, true);
 }
 
@@ -623,6 +651,10 @@ static unsigned int jh7110_rsa_max_size(struct crypto_akcipher *tfm)
 {
        struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
 
+       /* For key sizes > 2Kb, use software tfm */
+       if (ctx->rsa_key.key_sz > JH7110_RSA_MAX_KEYSZ)
+               return crypto_akcipher_maxsize(ctx->soft_tfm);
+
        return ctx->rsa_key.key_sz;
 }
 
@@ -631,9 +663,17 @@ static int jh7110_rsa_init_tfm(struct crypto_akcipher *tfm)
 {
        struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
 
+       ctx->soft_tfm = crypto_alloc_akcipher("rsa-generic", 0, 0);
+       if (IS_ERR(ctx->soft_tfm)) {
+               pr_err("Can not alloc_akcipher!\n");
+               return PTR_ERR(ctx->soft_tfm);
+       }
+
        ctx->sdev = jh7110_sec_find_dev(ctx);
-       if (!ctx->sdev)
+       if (!ctx->sdev) {
+               crypto_free_akcipher(ctx->soft_tfm);
                return -ENODEV;
+       }
 
        akcipher_set_reqsize(tfm, sizeof(struct jh7110_sec_request_ctx));
 
@@ -646,6 +686,7 @@ static void jh7110_rsa_exit_tfm(struct crypto_akcipher *tfm)
        struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
        struct jh7110_rsa_key *key = (struct jh7110_rsa_key *)&ctx->rsa_key;
 
+       crypto_free_akcipher(ctx->soft_tfm);
        jh7110_rsa_free_key(key);
 }
 
@@ -664,7 +705,8 @@ static struct akcipher_alg jh7110_rsa = {
                .cra_name = "rsa",
                .cra_driver_name = "rsa-jh7110",
                .cra_flags = CRYPTO_ALG_TYPE_AKCIPHER |
-                                               CRYPTO_ALG_ASYNC,
+                            CRYPTO_ALG_ASYNC |
+                            CRYPTO_ALG_NEED_FALLBACK,
                .cra_priority = 3000,
                .cra_module = THIS_MODULE,
                .cra_ctxsize = sizeof(struct jh7110_sec_ctx),
index c29d7c2..0be29a6 100644 (file)
@@ -41,6 +41,7 @@
 #define JH7110_MAX_ALIGN_SIZE  SHA512_BLOCK_SIZE
 
 #define JH7110_HASH_BUFLEN             8192
+#define JH7110_HASH_THRES              2048
 
 static inline int jh7110_hash_wait_hmac_done(struct jh7110_sec_ctx *ctx)
 {
@@ -249,13 +250,17 @@ static int jh7110_hash_xmit_cpu(struct jh7110_sec_ctx *ctx, int flags)
        mlen = total_len / sizeof(u32);// DIV_ROUND_UP(total_len, sizeof(u32));
        buffer = (unsigned int *)ctx->buffer;
 
-       for (loop = 0; loop < mlen; loop++, buffer++)
+       for (loop = 0; loop < mlen; loop++, buffer++) {
                jh7110_sec_write(sdev, JH7110_SHA_SHAWDR, *buffer);
+               udelay(2);
+       }
 
        if (total_len & 0x3) {
                cl = (unsigned char *)buffer;
-               for (loop = 0; loop < (total_len & 0x3); loop++, cl++)
+               for (loop = 0; loop < (total_len & 0x3); loop++, cl++) {
                        jh7110_sec_writeb(sdev, JH7110_SHA_SHAWDR, *cl);
+                       udelay(2);
+               }
        }
 
        return 0;
@@ -325,7 +330,6 @@ static int jh7110_hash_xmit(struct jh7110_sec_ctx *ctx, int flags)
        if (!rctx->csr.sha_csr.hmac) {
                rctx->csr.sha_csr.start = 1;
                rctx->csr.sha_csr.firstb = 1;
-               ctx->sec_init = 0;
                jh7110_sec_write(sdev, JH7110_SHA_SHACSR, rctx->csr.sha_csr.v);
        }
 
@@ -375,7 +379,7 @@ static int jh7110_hash_update_req(struct jh7110_sec_ctx *ctx)
 
        if (final) {
                err = jh7110_hash_xmit(ctx,
-                                       (rctx->flags & HASH_FLAGS_FINUP));
+                               (rctx->flags & HASH_FLAGS_FINUP));
                rctx->bufcnt = 0;
        }
 
@@ -563,9 +567,19 @@ static int jh7110_hash_update(struct ahash_request *req)
 static int jh7110_hash_final(struct ahash_request *req)
 {
        struct jh7110_sec_request_ctx *rctx = ahash_request_ctx(req);
+       struct jh7110_sec_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
 
        rctx->flags |= HASH_FLAGS_FINUP;
 
+       if (ctx->fallback_available && (rctx->bufcnt < JH7110_HASH_THRES)) {
+               if (ctx->sha_mode & JH7110_SHA_HMAC_FLAGS)
+                       crypto_shash_setkey(ctx->fallback, ctx->key,
+                                       ctx->keylen);
+
+               return crypto_shash_tfm_digest(ctx->fallback, ctx->buffer,
+                               rctx->bufcnt, req->result);
+       }
+
        return jh7110_hash_enqueue(req, HASH_OP_FINAL);
 }
 
@@ -621,16 +635,25 @@ static int jh7110_hash_cra_init_algs(struct crypto_tfm *tfm,
                                        unsigned int mode)
 {
        struct jh7110_sec_ctx *ctx = crypto_tfm_ctx(tfm);
+       const char *alg_name = crypto_tfm_alg_name(tfm);
 
        ctx->sdev = jh7110_sec_find_dev(ctx);
+       ctx->fallback_available = true;
 
        if (!ctx->sdev)
                return -ENODEV;
 
+       ctx->fallback = crypto_alloc_shash(alg_name, 0,
+                       CRYPTO_ALG_NEED_FALLBACK);
+       
+       if (IS_ERR(ctx->fallback)) {
+               pr_err("fallback unavailable for '%s'\n", alg_name);
+               ctx->fallback_available = false;
+       }
+
        crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
-                               sizeof(struct jh7110_sec_request_ctx));
+                       sizeof(struct jh7110_sec_request_ctx));
 
-       ctx->sec_init = 1;
        ctx->keylen   = 0;
        ctx->sha_mode = mode;
        ctx->sha_len_total = 0;
@@ -650,6 +673,9 @@ static void jh7110_hash_cra_exit(struct crypto_tfm *tfm)
 {
        struct jh7110_sec_ctx *ctx = crypto_tfm_ctx(tfm);
 
+       crypto_free_shash(ctx->fallback);
+
+       ctx->fallback = NULL;
        ctx->enginectx.op.do_one_request = NULL;
        ctx->enginectx.op.prepare_request = NULL;
        ctx->enginectx.op.unprepare_request = NULL;
@@ -886,193 +912,199 @@ static int jh7110_hash_cra_hmac_sm3_init(struct crypto_tfm *tfm)
 }
 
 static struct ahash_alg algs_sha0_sha512_sm3[] = {
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA1_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha1",
-                               .cra_driver_name        = "jh7110-sha1",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA1_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha1_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA1_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sha1",
+                       .cra_driver_name        = "jh7110-sha1",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA1_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sha1_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .setkey   = jh7110_hash1_setkey,
-               .halg = {
-                       .digestsize = SHA1_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sha1)",
-                               .cra_driver_name        = "jh7110-hmac-sha1",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA1_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha1_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .setkey   = jh7110_hash1_setkey,
+       .halg = {
+               .digestsize = SHA1_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sha1)",
+                       .cra_driver_name        = "jh7110-hmac-sha1",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA1_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sha1_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA224_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha224",
-                               .cra_driver_name        = "jh7110-sha224",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA224_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha224_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA224_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sha224",
+                       .cra_driver_name        = "jh7110-sha224",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA224_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sha224_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .setkey   = jh7110_hash224_setkey,
-               .halg = {
-                       .digestsize = SHA224_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sha224)",
-                               .cra_driver_name        = "jh7110-hmac-sha224",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA224_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha224_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .setkey   = jh7110_hash224_setkey,
+       .halg = {
+               .digestsize = SHA224_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sha224)",
+                       .cra_driver_name        = "jh7110-hmac-sha224",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA224_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sha224_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA256_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha256",
-                               .cra_driver_name        = "jh7110-sha256",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA256_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha256_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA256_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sha256",
+                       .cra_driver_name        = "jh7110-sha256",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA256_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sha256_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .setkey   = jh7110_hash256_setkey,
-               .halg = {
-                       .digestsize = SHA256_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sha256)",
-                               .cra_driver_name        = "jh7110-hmac-sha256",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA256_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha256_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .setkey   = jh7110_hash256_setkey,
+       .halg = {
+               .digestsize = SHA256_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sha256)",
+                       .cra_driver_name        = "jh7110-hmac-sha256",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA256_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sha256_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA384_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha384",
-                               .cra_driver_name        = "jh7110-sha384",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA384_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha384_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA384_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sha384",
+                       .cra_driver_name        = "jh7110-sha384",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA384_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sha384_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
+       }
+},
+{
                .init     = jh7110_hash_init,
                .update   = jh7110_hash_update,
                .final    = jh7110_hash_final,
@@ -1088,123 +1120,127 @@ static struct ahash_alg algs_sha0_sha512_sm3[] = {
                                .cra_name                       = "hmac(sha384)",
                                .cra_driver_name        = "jh7110-hmac-sha384",
                                .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
+                               .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                         CRYPTO_ALG_TYPE_AHASH |
+                                                         CRYPTO_ALG_NEED_FALLBACK,
                                .cra_blocksize          = SHA384_BLOCK_SIZE,
                                .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
                                .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha384_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
+                               .cra_init               = jh7110_hash_cra_hmac_sha384_init,
+                               .cra_exit               = jh7110_hash_cra_exit,
+                               .cra_module             = THIS_MODULE,
                        }
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA512_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha512",
-                               .cra_driver_name        = "jh7110-sha512",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA512_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha512_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA512_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name                       = "sha512",
+                       .cra_driver_name        = "jh7110-sha512",
+                       .cra_priority           = 200,
+                       .cra_flags                      = CRYPTO_ALG_ASYNC |
+                               CRYPTO_ALG_TYPE_AHASH,
+                       .cra_blocksize          = SHA512_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init                       = jh7110_hash_cra_sha512_init,
+                       .cra_exit                       = jh7110_hash_cra_exit,
+                       .cra_module                     = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .setkey   = jh7110_hash512_setkey,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA512_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sha512)",
-                               .cra_driver_name        = "jh7110-hmac-sha512",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA512_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha512_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .setkey   = jh7110_hash512_setkey,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA512_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sha512)",
+                       .cra_driver_name        = "jh7110-hmac-sha512",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA512_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sha512_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SM3_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sm3",
-                               .cra_driver_name        = "jh7110-sm3",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SM3_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sm3_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SM3_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sm3",
+                       .cra_driver_name        = "jh7110-sm3",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SM3_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sm3_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init           = jh7110_hash_init,
-               .update         = jh7110_hash_update,
-               .final          = jh7110_hash_final,
-               .finup          = jh7110_hash_finup,
-               .digest         = jh7110_hash_digest,
-               .setkey         = jh7110_sm3_setkey,
-               .export         = jh7110_hash_export,
-               .import         = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SM3_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sm3)",
-                               .cra_driver_name        = "jh7110-hmac-sm3",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SM3_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sm3_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init           = jh7110_hash_init,
+       .update         = jh7110_hash_update,
+       .final          = jh7110_hash_final,
+       .finup          = jh7110_hash_finup,
+       .digest         = jh7110_hash_digest,
+       .setkey         = jh7110_sm3_setkey,
+       .export         = jh7110_hash_export,
+       .import         = jh7110_hash_import,
+       .halg = {
+               .digestsize = SM3_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sm3)",
+                       .cra_driver_name        = "jh7110-hmac-sm3",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SM3_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sm3_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
+       }
+},
 };
 
 int jh7110_hash_register_algs(void)
index 085fa2e..5e7d896 100644 (file)
@@ -60,6 +60,9 @@ struct jh7110_sec_ctx {
        struct jh7110_rsa_key                   rsa_key;
        size_t                                  sha_len_total;
        u8                                      *buffer;
+       struct crypto_akcipher                  *soft_tfm;
+       struct crypto_shash                     *fallback;
+       bool                                    fallback_available;
 };
 
 struct jh7110_sec_dev {
index a2778c1..48f2a21 100755 (executable)
@@ -88,6 +88,7 @@ enum {
 };
 
 static const struct pre_pll_config pre_pll_cfg_table[] = {
+       { 25175000,  25175000, 1,  100, 2, 3, 3, 12, 3, 3, 4, 0, 0},
        { 25200000,  25200000, 1,  100, 2, 3, 3, 12, 3, 3, 4, 0, 0},
        { 27000000,  27000000, 1,  90, 3, 2, 2, 10, 3, 3, 4, 0, 0},
        { 27000000,  33750000, 1,  90, 1, 3, 3, 10, 3, 3, 4, 0, 0},
@@ -356,7 +357,7 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
        rate = (rate / 1000) * 1000;
 
        for (; cfg->pixclock != 0; cfg++)
-               if (cfg->tmdsclock == rate)
+               if (cfg->tmdsclock == rate && cfg->pixclock == rate)
                        break;
 
        if (cfg->pixclock == 0)
index bd151b5..1ae53ce 100755 (executable)
@@ -978,6 +978,12 @@ static void update_fb(struct vs_plane *plane, u8 display_id,
        update_swizzle(drm_fb->format->format, fb);
        update_watermark(plane_state->watermark, fb);
 
+       starfive_flush_dcache(fb->y_address, fb->height * fb->y_stride);
+       if (fb->u_address)
+               starfive_flush_dcache(fb->u_address, fb->height * fb->u_stride);
+       if (fb->v_address)
+               starfive_flush_dcache(fb->v_address, fb->height * fb->v_stride);
+
        plane_state->status.tile_mode = fb->tile_mode;
 }
 
@@ -1340,23 +1346,6 @@ static irqreturn_t dc_isr(int irq, void *data)
        for (i = 0; i < dc_info->panel_num; i++)
                vs_crtc_handle_vblank(&dc->crtc[i]->base, dc_hw_check_underflow(&dc->hw));
 
-       starfive_flush_dcache(dc->hw.plane[0].fb.y_address,
-                       dc->hw.plane[0].fb.width * dc->hw.plane[0].fb.height*4);
-       starfive_flush_dcache(dc->hw.plane[1].fb.y_address,
-                       dc->hw.plane[1].fb.width * dc->hw.plane[1].fb.height*4);
-       starfive_flush_dcache(dc->hw.plane[2].fb.y_address,
-                       dc->hw.plane[2].fb.width * dc->hw.plane[2].fb.height*4);
-       starfive_flush_dcache(dc->hw.plane[3].fb.y_address,
-                       dc->hw.plane[3].fb.width * dc->hw.plane[3].fb.height*4);
-       starfive_flush_dcache(dc->hw.plane[4].fb.y_address,
-                       dc->hw.plane[4].fb.width * dc->hw.plane[4].fb.height*4);
-       starfive_flush_dcache(dc->hw.plane[5].fb.y_address,
-                       dc->hw.plane[5].fb.width * dc->hw.plane[5].fb.height*4);
-       starfive_flush_dcache(dc->hw.plane[6].fb.y_address,
-                       dc->hw.plane[6].fb.width * dc->hw.plane[6].fb.height*4);
-       starfive_flush_dcache(dc->hw.plane[7].fb.y_address,
-                       dc->hw.plane[7].fb.width * dc->hw.plane[7].fb.height*4);
-
        return IRQ_HANDLED;
 }
 
index 2b07d6f..5e34b3e 100644 (file)
@@ -22,7 +22,7 @@
 #define RDMA_LINK                       (0xA2)
 #define RDMA_SINT                       (0xA3)
 #define RDMA_END                        (0xAF)
-
+#define ENABLE_SS0_SS1
 
 enum _STF_ISP_IOCTL {
        STF_ISP_IOCTL_LOAD_FW = BASE_VIDIOC_PRIVATE + 1,
index 1f03df8..7a634e9 100644 (file)
@@ -1827,7 +1827,7 @@ int stf_video_register(struct stfcamss_video *video,
        //strlcpy(vdev->name, name, sizeof(vdev->name));
        strscpy(vdev->name, name, sizeof(vdev->name));
 
-       ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+       ret = video_register_device(vdev, VFL_TYPE_VIDEO, video->id);
        if (ret < 0) {
                st_err(ST_VIDEO,
                        "Failed to register video device: %d\n",
index 524e19a..7625aad 100644 (file)
@@ -1160,12 +1160,8 @@ static void vin_change_buffer(struct vin_line *line)
        if (output->state == VIN_OUTPUT_OFF
                || output->state == VIN_OUTPUT_STOPPING
                || output->state == VIN_OUTPUT_RESERVED
-               || output->state == VIN_OUTPUT_IDLE) {
-               st_err_ratelimited(ST_VIN,
-                               "%s: output state no ready %d!, %d\n",
-                               __func__, output->state, line->id);
+               || output->state == VIN_OUTPUT_IDLE)
                return;
-       }
 
        spin_lock_irqsave(&line->output_lock, flags);
 
@@ -1373,6 +1369,11 @@ int stf_vin_register(struct stf_vin2_dev *vin_dev, struct v4l2_device *v4l2_dev)
                char *sub_name = get_line_subdevname(i);
                int is_mp;
 
+#ifdef STF_CAMSS_SKIP_ITI
+               if ((stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC_ITIW) ||
+                       (stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC_ITIR))
+                       continue;
+#endif
                is_mp = (stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC) ? true : false;
                is_mp = false;
                sd = &vin_dev->line[i].subdev;
index 66a40d2..63f0d8e 100644 (file)
@@ -450,6 +450,7 @@ static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
                goto err_link;
        }
 
+#ifndef        STF_CAMSS_SKIP_ITI
        ret = media_create_pad_link(
                &isp_dev->subdev.entity,
                STF_ISP_PAD_SRC_ITIW,
@@ -481,6 +482,7 @@ static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
                        ret);
                goto err_link;
        }
+#endif
 
        ret = media_create_pad_link(
                &isp_dev->subdev.entity,
index cd4fb31..186c03b 100644 (file)
@@ -32,6 +32,8 @@ enum subdev_type {
 #define STF_PAD_SRC    1
 #define STF_PADS_NUM   2
 
+#define STF_CAMSS_SKIP_ITI
+
 enum port_num {
        DVP_SENSOR_PORT_NUMBER = 0,
        CSI2RX_SENSOR_PORT_NUMBER
index e565523..03ce495 100755 (executable)
 #define JH7110_E2_IRQ_SYNC_CLK_CORE            324
 #define JH7110_STG_CRG_PCLK                    325
 #define JH7110_STG_SYSCON_PCLK                 326
+#define JH7110_STG_APB                         327
 
-#define JH7110_CLK_STG_END                     327
+#define JH7110_CLK_STG_END                     328
 
 /* aon other */
-#define JH7110_U0_GMAC5_CLK_PTP                        327
-#define JH7110_U0_GMAC5_CLK_RMII               328
-#define JH7110_AON_SYSCON_PCLK                 329
-#define JH7110_AON_IOMUX_PCLK                  330
-#define JH7110_AON_CRG_PCLK                    331
-#define JH7110_PMU_CLK_APB                     332
-#define JH7110_PMU_CLK_WKUP                    333
-#define JH7110_RTC_HMS_CLK_OSC32K_G            334
-#define JH7110_32K_OUT                         335
-#define JH7110_RESET0_CTRL_CLK_SRC             336
+#define JH7110_U0_GMAC5_CLK_PTP                        328
+#define JH7110_U0_GMAC5_CLK_RMII               329
+#define JH7110_AON_SYSCON_PCLK                 330
+#define JH7110_AON_IOMUX_PCLK                  331
+#define JH7110_AON_CRG_PCLK                    332
+#define JH7110_PMU_CLK_APB                     333
+#define JH7110_PMU_CLK_WKUP                    334
+#define JH7110_RTC_HMS_CLK_OSC32K_G            335
+#define JH7110_32K_OUT                         336
+#define JH7110_RESET0_CTRL_CLK_SRC             337
 /* aon other and source */
-#define JH7110_PCLK_MUX_FUNC_PCLK              337
-#define JH7110_PCLK_MUX_BIST_PCLK              338
+#define JH7110_PCLK_MUX_FUNC_PCLK              338
+#define JH7110_PCLK_MUX_BIST_PCLK              339
 
-#define JH7110_CLK_END                         339
+#define JH7110_CLK_END                         340
 
 #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_H__ */
index 0158a38..1a5a53f 100755 (executable)
@@ -820,6 +820,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
        int freq_out, freq_in;
        int i, j, k;
        u16 word_length = 0;
+       int ret;
 
        wm8960->bclk = snd_soc_params_to_bclk(params);
        if (params_channels(params) == 1)
@@ -930,34 +931,43 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
                snd_soc_component_write(component, WM8960_POWER2, 0x1f9);
        } else if (audio_format == 0x2) {//I2S Format
                if (!tx) {
-                       snd_soc_component_update_bits(component, WM8960_LINVOL, 0x3<<7, 0x2<<7);
-                       snd_soc_component_update_bits(component, WM8960_RINVOL, 0x3<<7, 0x2<<7);
-                       snd_soc_component_write(component, WM8960_CLOCK1, 0x00); //0xd8
+                       snd_soc_component_update_bits(component, WM8960_LINVOL, 0x1<<7, 0x1<<7);
+                       snd_soc_component_update_bits(component, WM8960_RINVOL, 0x1<<7, 0x1<<7);
                        snd_soc_component_write(component, WM8960_ALC1, 0x1bb);
                        snd_soc_component_write(component, WM8960_ALC2, 0x30);
                        snd_soc_component_write(component, WM8960_ALC3, 0x30);
                        snd_soc_component_write(component, WM8960_NOISEG, 0xf9);
-                       snd_soc_component_write(component, WM8960_LADC, 0x197);
-                       snd_soc_component_write(component, WM8960_RADC, 0x197);
-                       snd_soc_component_write(component, WM8960_ADDCTL1, 0xc0);
-                       snd_soc_component_write(component, WM8960_ADDCTL3, 0x03);
-                       snd_soc_component_write(component, WM8960_LOUT2, 0x1ff);
-                       snd_soc_component_write(component, WM8960_ROUT2, 0x1ff);
+                       snd_soc_component_update_bits(component, WM8960_ADDCTL1, 0x1cf, 0xc0);
+                       snd_soc_component_update_bits(component, WM8960_ADDCTL3, 0x47, 0x03);
                        snd_soc_component_write(component, WM8960_BYPASS1, 0x00);
                        snd_soc_component_write(component, WM8960_BYPASS2, 0x00);
-                       snd_soc_component_write(component, WM8960_ADDCTL4, 0x00);
+                       snd_soc_component_update_bits(component, WM8960_ADDCTL4, 0x73, 0);
                } else {
                        if (params_channels(params) == 1)
                                snd_soc_component_write(component, WM8960_LOUT1, 0x100);
-                       else
-                               snd_soc_component_update_bits(component, WM8960_LOUT1, 0x170, 0x170);
+                       else {
+                               if (snd_soc_component_read(component, WM8960_LOUT1) & 0x7f)
+                                       snd_soc_component_update_bits(component, WM8960_LOUT1, 0x100, 0x100);
+                               else
+                                       snd_soc_component_write(component, WM8960_LOUT1, 0x170);
+                       }
                }
        }
 
        wm8960->is_stream_in_use[tx] = true;
 
-       if (!wm8960->is_stream_in_use[!tx])
-               return wm8960_configure_clocking(component);
+       if (!wm8960->is_stream_in_use[!tx]) {
+               ret = wm8960_configure_clocking(component);
+               if (ret)
+                       return ret;
+       }
+
+       if (tx) {
+               snd_soc_component_update_bits(component, WM8960_POWER3, 0xc, 0xc);
+               msleep(100);
+               snd_soc_component_update_bits(component, WM8960_POWER2, 0x1e0, 0x1e0);
+               msleep(100);
+       }
 
        return 0;
 }
@@ -969,6 +979,8 @@ static int wm8960_hw_free(struct snd_pcm_substream *substream,
        struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
+       if (tx)
+               snd_soc_component_update_bits(component, WM8960_POWER2, 0x1e0, 0);
        wm8960->is_stream_in_use[tx] = false;
 
        return 0;
@@ -1013,6 +1025,8 @@ static int wm8960_set_bias_level_out3(struct snd_soc_component *component,
                        if (ret)
                                return ret;
 
+                       snd_soc_component_update_bits(component, WM8960_POWER3, 0xc, 0xc);
+                       msleep(100);
                        /* Set VMID to 2x50k */
                        snd_soc_component_update_bits(component, WM8960_POWER1, 0x180, 0x80);
                        break;
index 200838f..88042dd 100755 (executable)
@@ -247,7 +247,10 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
        struct i2s_clk_config_data *config = &dev->config;
        int ret;
        unsigned int txrx = substream->stream;
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+       struct snd_soc_dai_link *dai_link = rtd->dai_link;
 
+       dai_link->stop_dma_first = 1;
        config->chan_nr = params_channels(params);
 
        switch (params_format(params)) {