Browse Source

Merge branch 'CR_2848_Venc_devfreq_515_samin.guo' into 'jh7110-devel'

CR_2848: wave420l: set devfreq for wave420l

See merge request sdk/soft_3rdpart!1
andy.hu 1 year ago
parent
commit
35379f3fa1

+ 0 - 2
wave420l/code/build.sh

@@ -7,7 +7,6 @@ DRI_SRC=./vdi/linux/driver/
 
 ENC_BIN=w4_enc_test
 STEAM=./stream
-YUV=./yuv
 CFG=./cfg
 FIRMWARE=../firmware/monet.bin
 
@@ -25,7 +24,6 @@ make -f  Wave420Enc.mak clean
 
 $CP $FIRMWARE $OUTPUT
 $CP $STEAM $OUTPUT
-$CP $YUV $OUTPUT
 $CP $CFG $OUTPUT
 $CP script/* $OUTPUT
 mkdir -p $OUTPUT/output

+ 156 - 0
wave420l/code/vdi/linux/driver/venc.c

@@ -110,6 +110,41 @@ struct clk_bulk_data vpu_clks[] = {
 		{ .id = "vce_clk" },
 		{ .id = "noc_bus" },
 };
+#define FRAMSIZE_1080P	(1920*1080)
+#define FRAMSIZE_720P	(1280*720)
+#define FRAMSIZE_480P	(720*480)
+
+struct vpu_devfreq_t {
+	struct clk *axi_clk;
+	struct clk *bpu_clk;
+	struct clk *vce_clk;
+};
+
+enum VPU_DEV_FREQ {
+	VPU_DEV_FREQ_80 = 80000000,
+	VPU_DEV_FREQ_100 = 100000000,
+	VPU_DEV_FREQ_150 = 150000000,
+	VPU_DEV_FREQ_200 = 200000000,
+	VPU_DEV_FREQ_237 = 237600000,
+	VPU_DEV_FREQ_300 = 300000000,
+	VPU_DEV_FREQ_MAX = VPU_DEV_FREQ_300,
+};
+
+enum VPU_DEV_FREQ_MODE {
+	MODE_480P_30F,
+	MODE_480P_60F,
+	MODE_720P_30F,
+	MODE_720P_60F,
+	MODE_1080P_30F,
+	MODE_MAX,
+};
+
+struct vpu_dev_freq_list {
+	int mode;
+	unsigned long axi_rate;
+	unsigned long bpu_rate;
+	unsigned long vce_rate;
+};
 
 typedef struct vpu_clk_t{
 #ifndef STARFIVE_VPU_SUPPORT_CLOCK_CONTROL
@@ -127,6 +162,7 @@ typedef struct vpu_clk_t{
 #else
 		struct clk_bulk_data *clks;
 		struct reset_control *resets;
+		struct vpu_devfreq_t vpu_devfreq;
 		int nr_clks;
 #endif
 		struct device *dev;
@@ -177,6 +213,7 @@ static vpu_clk_t *vpu_clk_get(struct platform_device *pdev);
 static void vpu_clk_put(vpu_clk_t *clk);
 static int vpu_pmu_enable(struct device *dev);
 static void vpu_pmu_disable(struct device *dev);
+static int vpu_devfreq_select(struct vpudrv_devfreq_info_t *info);
 
 /* end customer definition */
 static vpudrv_buffer_t s_instance_pool = {0};
@@ -828,6 +865,17 @@ static long vpu_ioctl(struct file *filp, u_int cmd, u_long arg)
             DPRINTK("[JPUDRV][-]VDI_IOCTL_FLUSH_DCACHE\n");
             break;
         }
+	case VDI_IOCTL_DEVFREQ_SET:
+	{
+		vpudrv_devfreq_info_t devfreq_info;
+
+		ret = copy_from_user(&devfreq_info, (vpudrv_devfreq_info_t *)arg, sizeof(vpudrv_devfreq_info_t));
+		if (ret != 0)
+			ret = -EFAULT;
+
+		vpu_devfreq_select(&devfreq_info);
+		break;
+	}
 	default:
 		{
 			printk(KERN_ERR "[VPUDRV] No such IOCTL, cmd is %d\n", cmd);
@@ -1806,6 +1854,113 @@ void vpu_clk_disable(struct vpu_clk_t *clk)
 
 #else /*STARFIVE_VPU_SUPPORT_CLOCK_CONTROL*/
 
+static const struct vpu_dev_freq_list wave420l_dev_freq_lists[MODE_MAX+1] = {
+	[MODE_480P_30F] = {
+		.mode = MODE_480P_30F,
+		.axi_rate = VPU_DEV_FREQ_80,
+		.bpu_rate = VPU_DEV_FREQ_80,
+		.vce_rate = VPU_DEV_FREQ_80,
+	},
+	[MODE_480P_60F] = {
+		.mode = MODE_480P_60F,
+		.axi_rate = VPU_DEV_FREQ_100,
+		.bpu_rate = VPU_DEV_FREQ_100,
+		.vce_rate = VPU_DEV_FREQ_100,
+	},
+	[MODE_720P_30F] = {
+		.mode = MODE_720P_30F,
+		.axi_rate = VPU_DEV_FREQ_150,
+		.bpu_rate = VPU_DEV_FREQ_150,
+		.vce_rate = VPU_DEV_FREQ_150,
+	},
+	[MODE_720P_60F] = {
+		.mode = MODE_720P_60F,
+		.axi_rate = VPU_DEV_FREQ_237,
+		.bpu_rate = VPU_DEV_FREQ_237,
+		.vce_rate = VPU_DEV_FREQ_237,
+	},
+	[MODE_1080P_30F] = {
+		.mode = MODE_1080P_30F,
+		.axi_rate = VPU_DEV_FREQ_300,
+		.bpu_rate = VPU_DEV_FREQ_300,
+		.vce_rate = VPU_DEV_FREQ_300,
+	},
+	[MODE_MAX] = {
+		.mode = MODE_MAX,
+		.axi_rate = VPU_DEV_FREQ_MAX,
+		.bpu_rate = VPU_DEV_FREQ_MAX,
+		.vce_rate = VPU_DEV_FREQ_MAX,
+	},
+};
+
+static int vpu_devfreq_init(vpu_clk_t *vpu_clk)
+{
+	struct vpu_devfreq_t *dev_freq = &vpu_clk->vpu_devfreq;
+
+	dev_freq->axi_clk = devm_clk_get_optional(vpu_clk->dev, "axi_clk");
+	if (IS_ERR(dev_freq->axi_clk))
+		return PTR_ERR(dev_freq->axi_clk);
+
+	dev_freq->bpu_clk = devm_clk_get_optional(vpu_clk->dev, "bpu_clk");
+	if (IS_ERR(dev_freq->bpu_clk))
+		return PTR_ERR(dev_freq->bpu_clk);
+
+	dev_freq->vce_clk = devm_clk_get_optional(vpu_clk->dev, "vce_clk");
+	if (IS_ERR(dev_freq->vce_clk))
+		return PTR_ERR(dev_freq->vce_clk);
+
+	return 0;
+}
+
+static int vpu_devfreq_set(vpu_clk_t *vpu_clk, const struct vpu_dev_freq_list *freq_list)
+{
+	struct vpu_devfreq_t *dev_freq = &vpu_clk->vpu_devfreq;
+	int ret;
+
+	dev_dbg(vpu_clk->dev, "axi_clk:%ld bpu_clk:%ld vce_clk:%ld\n",
+		freq_list->axi_rate, freq_list->bpu_rate, freq_list->vce_rate);
+	ret = clk_set_rate(dev_freq->axi_clk, freq_list->axi_rate);
+	if (ret)
+		dev_err(vpu_clk->dev, "set clk error, ret:%d \n", ret);
+
+	ret = clk_set_rate(dev_freq->bpu_clk, freq_list->bpu_rate);
+	if (ret)
+		dev_err(vpu_clk->dev, "set clk error, ret:%d \n", ret);
+
+	ret = clk_set_rate(dev_freq->vce_clk, freq_list->vce_rate);
+	if (ret)
+		dev_err(vpu_clk->dev, "set clk error, ret:%d \n", ret);
+
+	return ret;
+}
+
+static int vpu_devfreq_select(struct vpudrv_devfreq_info_t *info)
+{
+	unsigned long framsize = info->picWidth*info->picHeight;
+	int frameRateInfo = info->frameRateInfo;
+	int mode;
+
+	if (frameRateInfo <= 30) {
+		if (framsize <= FRAMSIZE_480P)
+			mode = MODE_480P_30F;
+		else if (framsize <= FRAMSIZE_720P)
+			mode = MODE_720P_30F;
+		else if (framsize <= FRAMSIZE_1080P)
+			mode = MODE_1080P_30F;
+		else
+			mode = MODE_MAX;
+	} else {
+		if (framsize <= FRAMSIZE_480P)
+			mode = MODE_480P_60F;
+		else if (framsize <= FRAMSIZE_720P)
+			mode = MODE_720P_60F;
+		else
+			mode = MODE_MAX;
+	}
+
+	return vpu_devfreq_set(s_vpu_clk, &wave420l_dev_freq_lists[mode]);
+}
+
 int vpu_hw_reset(void)
 {
 	DPRINTK("[VPUDRV] reset vpu hardware. \n");
@@ -1852,6 +2007,7 @@ static vpu_clk_t *vpu_clk_get(struct platform_device *pdev)
 	if (vpu_of_clk_get(pdev, vpu_clk))
 		goto err_of_clk_get;
 
+	vpu_devfreq_init(vpu_clk);
 	return vpu_clk;
 
 err_of_clk_get:

+ 6 - 1
wave420l/code/vdi/linux/driver/vpu.h

@@ -37,7 +37,7 @@
 #define VDI_IOCTL_GET_INSTANCE_NUM			_IO(VDI_IOCTL_MAGIC, 11)
 #define VDI_IOCTL_GET_REGISTER_INFO			_IO(VDI_IOCTL_MAGIC, 12)
 #define VDI_IOCTL_FLUSH_DCACHE				_IO(VDI_IOCTL_MAGIC, 14)
-
+#define VDI_IOCTL_DEVFREQ_SET				_IO(VDI_IOCTL_MAGIC, 15)
 
 #define DRAM_MEM2SYS(addr) ((addr) > 0x40000000 && (addr) < 0x43FFFFFFF ? ((addr)+0x400000000):(addr))
 
@@ -49,6 +49,11 @@ typedef struct vpudrv_flush_cache_t {
     unsigned char flag;
 } vpudrv_flush_cache_t;
 
+typedef struct vpudrv_devfreq_info_t {
+    int picWidth;
+    int picHeight;
+    int frameRateInfo;
+} vpudrv_devfreq_info_t;
 
 typedef struct vpudrv_buffer_t {
 	unsigned int size;

+ 13 - 0
wave420l/code/vdi/linux/vdi.c

@@ -96,6 +96,19 @@ void vdi_flush_ddr(unsigned long core_idx,unsigned long start,unsigned long size
     ioctl(vdi->vpu_fd, VDI_IOCTL_FLUSH_DCACHE, &cache_info);
 }
 
+void vdi_devfreq_set(unsigned long core_idx, int picHeight, int picWidth, int frameRateInfo)
+{
+    vdi_info_t *vdi;
+    vpudrv_devfreq_info_t devfreq_info;
+
+    vdi = &s_vdi_info[core_idx];
+    devfreq_info.picHeight = picHeight;
+    devfreq_info.picWidth = picWidth;
+    devfreq_info.frameRateInfo = frameRateInfo;
+
+    ioctl(vdi->vpu_fd, VDI_IOCTL_DEVFREQ_SET, &devfreq_info);
+}
+
 int vdi_probe(unsigned long core_idx)
 {
     int ret;

+ 1 - 0
wave420l/code/vdi/vdi.h

@@ -157,6 +157,7 @@ extern "C" {
     int vdi_convert_endian(unsigned long core_idx, unsigned int endian);
 	void vdi_print_vpu_status(unsigned long coreIdx);
 	void vdi_flush_ddr(unsigned long core_idx,unsigned long start,unsigned long size,unsigned char flag);
+	void vdi_devfreq_set(unsigned long core_idx,int picHeight, int picWidth, int frameRateInfo);
 
 
 #if defined (__cplusplus)

+ 1 - 0
wave420l/code/vpuapi/vpuapi.c

@@ -2633,6 +2633,7 @@ RetCode VPU_EncOpen(EncHandle* pHandle, EncOpenParam * pop)
     }
     SetClockGate(pop->coreIdx, FALSE);
 
+    vdi_devfreq_set(pop->coreIdx, pop->picWidth, pop->picHeight, pop->frameRateInfo);
     LeaveLock(pCodecInst->coreIdx);
 
     return ret;