|
@@ -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 */
|