浏览代码

Merge branch 'CR_835_JPU_samin.guo' into 'jh7110_fpga_dev'

Cr 835 jpu samin.guo

See merge request sdk/sft-riscvpi-freedom-u-sdk!8
andy.hu 2 年之前
父节点
当前提交
abb550d495
共有 2 个文件被更改,包括 94 次插入89 次删除
  1. 3 0
      codaj12/README.md
  2. 91 89
      codaj12/jdi/linux/driver/jpu.c

+ 3 - 0
codaj12/README.md

@@ -76,5 +76,8 @@ $./run_dec.sh   #解码测试,解码后的文件存在output/dec中
 $./run_multi.sh #多路编解码测试,编解码后的文件存在output/multi中
 ```
 
+#### 验证
 
+*.yuv:解码后的文件使用yuvplayer.exe查看,需要根据文件名称手动指定分辨率、yuv格式等。注意,该工具不支持12bit的yuv文件查看。
 
+*.jpg:使用NewView.exe程序打开查看

+ 91 - 89
codaj12/jdi/linux/driver/jpu.c

@@ -33,8 +33,9 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/sched/signal.h>
+#include <linux/reset.h>
 #include <linux/version.h>
-#include <soc/starfive/vic7100.h>
+#include <soc/sifive/sifive_l2_cache.h>
 
 #include "../../../jpuapi/jpuconfig.h"
 #include "jpu.h"
@@ -52,8 +53,15 @@
 #define JPU_SUPPORT_ISR
 //#define JPU_IRQ_CONTROL
 
+/* jpu pmu */
+#define STARFIVE_JPU_PMU
+
+#ifdef STARFIVE_JPU_PMU
+#include <soc/starfive/jh7110_pmu.h>
+#endif
+
 /* if clktree is work,try this...*/
-//#define STARFIVE_JPU_SUPPORT_CLOCK_CONTROL
+#define STARFIVE_JPU_SUPPORT_CLOCK_CONTROL
 
 /* if the platform driver knows the name of this driver */
 /* JPU_PLATFORM_DEVICE_NAME */
@@ -63,6 +71,10 @@
 
 //#define JPU_SUPPORT_RESERVED_VIDEO_MEMORY        //if this driver knows the dedicated video memory address
 
+static void starfive_flush_dcache(unsigned long start, unsigned long len)
+{
+	sifive_l2_flush64_range(start, len);
+}
 
 #define JPU_PLATFORM_DEVICE_NAME    "cnm_jpu"
 #define JPU_CLK_NAME                "jpege"
@@ -117,8 +129,21 @@ typedef struct jpu_clkgen_t {
 } jpu_clkgen_t;
 #endif
 
+struct reset_control_bulk_data jpu_resets[] = {
+		{ .id = "rst_axi" },
+		{ .id = "rst_core" },
+		{ .id = "rst_apb" },
+};
+
+struct clk_bulk_data jpu_clks[] = {
+		{ .id = "axi_clk" },
+		{ .id = "core_clk" },
+		{ .id = "apb_clk" },
+};
+
 typedef struct jpu_clk_t {
 #ifndef STARFIVE_JPU_SUPPORT_CLOCK_CONTROL
+	void __iomem *clkgen;
 	void __iomem *rst_ctrl;
 	void __iomem *rst_status;
 	uint32_t en_shift;
@@ -127,12 +152,12 @@ typedef struct jpu_clk_t {
 	jpu_clkgen_t axi_clk;
 	jpu_clkgen_t core_clk;
 #else
-	struct clk *apb_clk;
-	struct clk *axi_clk;
-	struct clk *core_clk;
+	struct clk_bulk_data *clks;
+	struct reset_control_bulk_data *resets;
+	int nr_rstcs;
+	int nr_clks;
 #endif
-	void __iomem *clkgen;
-	phys_addr_t pmu_base;
+	struct device *dev;
 } jpu_clk_t;
 
 #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
@@ -144,7 +169,7 @@ static jpudrv_buffer_t  s_video_memory = {0};
 
 static int jpu_hw_reset(void);
 static void jpu_clk_disable(jpu_clk_t *clk);
-static void jpu_clk_enable(jpu_clk_t *clk);
+static int jpu_clk_enable(jpu_clk_t *clk);
 static jpu_clk_t *jpu_clk_get(struct platform_device *pdev);
 static void jpu_clk_put(jpu_clk_t *clk);
 // end customer definition
@@ -671,6 +696,8 @@ static int jpu_release(struct inode *inode, struct file *filp)
 
     DPRINTK("[JPUDRV][-] jpu_release\n");
 
+    jpu_hw_reset();
+
     return 0;
 }
 
@@ -913,6 +940,7 @@ static int jpu_remove(struct platform_device *pdev)
     if (s_jpu_register.virt_addr)
         iounmap((void*)s_jpu_register.virt_addr);
 
+    jpu_clk_disable(s_jpu_clk);
     jpu_clk_put(s_jpu_clk);
 
 #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
@@ -1031,28 +1059,17 @@ MODULE_LICENSE("GPL");
 module_init(jpu_init);
 module_exit(jpu_exit);
 
-/*pmu define*/
-#define PMU_BASE_ADDR		0x17030000
-#define PMU_JPU_MASK		(0x1 << 3)
-
-static void pmu_pd_set(jpu_clk_t *clk, int on_off, uint32_t pd_flag)
+#ifdef STARFIVE_JPU_PMU
+static void jpu_pmu_enable(bool enable)
 {
-	const uint32_t flag_off = 0x0c;
-	const uint32_t sw_off = 0x44;
-	void __iomem *base = ioremap(clk->pmu_base, 0x100);
-
-	writel(pd_flag, base + flag_off);
-	writel(0xff, base + sw_off);
-	if (on_off) {
-		writel(0x05, base + sw_off);
-		writel(0x50, base + sw_off);
-	} else {
-		writel(0x0a, base + sw_off);
-		writel(0xa0, base + sw_off);
-	}
-
-	iounmap(base);
+	starfive_power_domain_set(POWER_DOMAIN_JPU, enable);
+}
+#else
+static void jpu_pmu_enable(bool enable)
+{
+	return;
 }
+#endif
 
 #ifndef STARFIVE_JPU_SUPPORT_CLOCK_CONTROL
 #define CLK_ENABLE_DATA		1
@@ -1136,6 +1153,7 @@ static void jpu_clk_control(jpu_clk_t *clk, bool enable)
 		saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->apb_clk.rst_mask);
 		saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->axi_clk.rst_mask);
 		saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->core_clk.rst_mask);
+
 		/*disable*/
 		saif_set_reg(clk->apb_clk.en_ctrl, CLK_DISABLE_DATA, clk->en_shift, clk->en_mask);
 		saif_set_reg(clk->axi_clk.en_ctrl, CLK_DISABLE_DATA, clk->en_shift, clk->en_mask);
@@ -1172,8 +1190,6 @@ static int jpu_of_clk_get(struct platform_device *pdev, jpu_clk_t *jpu_clk)
 	if (!pdev)
 		return -ENXIO;
 
-	jpu_clk->pmu_base = PMU_BASE_ADDR;
-
 	jpu_clk->clkgen = ioremap(SAIF_BD_APBS_BASE, 0x400);
 	if (IS_ERR(jpu_clk->clkgen)) {
 		dev_err(&pdev->dev, "ioremap clkgen failed.\n");
@@ -1210,24 +1226,28 @@ static jpu_clk_t *jpu_clk_get(struct platform_device *pdev)
 
 	return jpu_clk;
 err_get_clk:
-	kfree(jpu_clk);
+	devm_kfree(&pdev->dev, jpu_clk);
 	return NULL;
 }
 
 static void jpu_clk_put(jpu_clk_t *clk)
 {
-	iounmap(clk->clkgen);
+	if (clk->clkgen) {
+		iounmap(clk->clkgen);
+		clk->clkgen = NULL;
+	}
 }
 
-static void jpu_clk_enable(jpu_clk_t *clk)
+static int jpu_clk_enable(jpu_clk_t *clk)
 {
 	if (clk == NULL || IS_ERR(clk))
-		return;
+		return -1;
 
-	pmu_pd_set(clk, true, PMU_JPU_MASK);
+	jpu_pmu_enable(true);
 	jpu_clk_control(clk, true);
 
 	DPRINTK("[VPUDRV] vpu_clk_enable\n");
+	return 0;
 }
 
 static void jpu_clk_disable(jpu_clk_t *clk)
@@ -1236,7 +1256,7 @@ static void jpu_clk_disable(jpu_clk_t *clk)
 		return;
 
 	jpu_clk_control(clk, false);
-	pmu_pd_set(clk, false, PMU_JPU_MASK);
+	jpu_pmu_enable(false);
 
 	DPRINTK("[VPUDRV] vpu_clk_disable\n");
 }
@@ -1245,47 +1265,31 @@ static void jpu_clk_disable(jpu_clk_t *clk)
 
 static int jpu_hw_reset(void)
 {
-    DPRINTK("[JPUDRV] request jpu reset from application. \n");
-    return 0;
-}
-
-static int clk_check_err(struct clk *clk)
-{
-	return !!(clk == NULL || IS_ERR(clk));
+    return reset_control_bulk_reset(s_jpu_clk->nr_rstcs, s_jpu_clk->resets);
 }
 
 static int jpu_of_clk_get(struct platform_device *pdev, jpu_clk_t *jpu_clk)
 {
-	struct resource *pmu;
 	struct device *dev = &pdev->dev;
+	int ret;
 
-	pmu = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pmu");
-	if (IS_ERR(pmu))
-		dev_warn(dev, "get pmu failed.\n");
+	jpu_clk->dev = dev;
+	jpu_clk->resets = jpu_resets;
+	jpu_clk->clks = jpu_clks;
+	jpu_clk->nr_rstcs = ARRAY_SIZE(jpu_resets);
+	jpu_clk->nr_clks = ARRAY_SIZE(jpu_clks);
 
-	jpu_clk->pmu_base = pmu->start;
+	ret = devm_reset_control_bulk_get_exclusive(dev, jpu_clk->nr_rstcs, jpu_clk->resets);
+	if (ret)
+		dev_err(dev, "faied to get jpu reset controls\n");
 
-	jpu_clk->apb_clk = devm_clk_get(dev, "apb_clk");
-	if (clk_check_err(jpu_clk->apb_clk)) {
-		dev_err(dev, "apb_clk get failed.\n");
-		return PTR_ERR(jpu_clk->apb_clk);
-	}
+	ret = devm_clk_bulk_get(dev, jpu_clk->nr_clks, jpu_clk->clks);
+	if (ret)
+		dev_err(dev, "faied to get jpu clk controls\n");
 
-	jpu_clk->axi_clk = devm_clk_get(dev, "axi_clk");
-	if (clk_check_err(jpu_clk->axi_clk)) {
-		dev_err(dev, "axi_clk get failed.\n");
-		return PTR_ERR(jpu_clk->axi_clk);
-	}
-
-	jpu_clk->core_clk = devm_clk_get(dev, "core_clk");
-	if (clk_check_err(jpu_clk->core_clk)) {
-		dev_err(dev, "core_clk get failed.\n");
-		return PTR_ERR(jpu_clk->core_clk);
-	}
 	return 0;
 }
 
-
 static jpu_clk_t *jpu_clk_get(struct platform_device *pdev)
 {
 	jpu_clk_t *jpu_clk;
@@ -1303,44 +1307,42 @@ static jpu_clk_t *jpu_clk_get(struct platform_device *pdev)
 	return jpu_clk;
 
 err_of_clk_get:
-	kfree(jpu_clk);
+	devm_kfree(&pdev->dev, jpu_clk);
 	return NULL;
 
 }
 
 static void jpu_clk_put(jpu_clk_t *clk)
 {
-	if (!(clk_check_err(clk->apb_clk)))
-		clk_put(clk->apb_clk);
-	if (!(clk_check_err(clk->axi_clk)))
-		clk_put(clk->axi_clk);
-	if (!(clk_check_err(clk->core_clk)))
-		clk_put(clk->core_clk);
+	clk_bulk_put(clk->nr_clks, clk->clks);
 }
 
-static void jpu_clk_enable(jpu_clk_t *clk)
+static int jpu_clk_enable(jpu_clk_t *clk)
 {
-	pmu_pd_set(clk, true, PMU_JPU_MASK);
+	int ret;
 
-	if (!(clk_check_err(clk->apb_clk)))
-		clk_prepare_enable(clk->apb_clk);
-	if (!(clk_check_err(clk->axi_clk)))
-		clk_prepare_enable(clk->axi_clk);
-	if (!(clk_check_err(clk->core_clk)))
-		clk_prepare_enable(clk->core_clk);
+	jpu_pmu_enable(true);
+	ret = clk_bulk_prepare_enable(clk->nr_clks, clk->clks);
+	if (ret)
+		dev_err(clk->dev, "enable clk error.\n");
 
-	DPRINTK("[VPUDRV] vpu_clk_enable\n");
+	ret = reset_control_bulk_deassert(clk->nr_rstcs, clk->resets);
+	if (ret)
+		dev_err(clk->dev, "deassert jpu error.\n");
+
+	DPRINTK("[VPUDRV] jpu_clk_enable\n");
+	return ret;
 }
 
 static void jpu_clk_disable(jpu_clk_t *clk)
 {
-	if (!(clk_check_err(clk->apb_clk)))
-		clk_disable_unprepare(clk->apb_clk);
-	if (!(clk_check_err(clk->axi_clk)))
-		clk_disable_unprepare(clk->axi_clk);
-	if (!(clk_check_err(clk->core_clk)))
-		clk_disable_unprepare(clk->core_clk);
-
-	pmu_pd_set(clk, false, PMU_JPU_MASK);
+	int ret;
+
+	ret = reset_control_bulk_assert(clk->nr_rstcs, clk->resets);
+	if (ret)
+		dev_err(clk->dev, "assert jpu error.\n");
+
+	clk_bulk_disable_unprepare(clk->nr_clks, clk->clks);
+	jpu_pmu_enable(false);
 }
 #endif /* STARFIVE_JPU_SUPPORT_CLOCK_CONTROL */