dmc: add function to set up dmc from bootargs [1/1]
authorTao Zeng <tao.zeng@amlogic.com>
Thu, 22 Aug 2019 06:06:03 +0000 (14:06 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Thu, 22 Aug 2019 06:06:03 +0000 (14:06 +0800)
PD#TV-8696

Problem:
DMC can't set up from bootargs. For easy debug, we need
set a monitor from bootargs.

Solution:
Add a funciton for this feature. You can using following patten
to set up a DMC monitor:

dmc_montiro=[start_addr],[end_addr],[mask]

Example:
setenv initargs $initargs dmc_monitor=0x0,0x20000000,0xff58
This command set up monitor for following device on GXL:
RANGE:0 - 20000000
MONITOR DEVICE:
    HDCP
    HEVC
    USB3.0
    VPU READ1
    VPU READ2
    VPU READ3
    VPU WRITE1
    VPU WRITE2
    VDEC
    HCODEC
    GE2DV

Verify:
P212

Change-Id: I864ff97325981fe62f18a4a4a24700b6b6ea7482
Signed-off-by: Tao Zeng <tao.zeng@amlogic.com>
drivers/amlogic/ddr_tool/dmc_monitor.c

index 61b38a0..60308fd 100644 (file)
 
 static struct dmc_monitor *dmc_mon;
 
+static unsigned long init_dev_mask   __initdata;
+static unsigned long init_start_addr __initdata;
+static unsigned long init_end_addr   __initdata;
+
+static int __init early_dmc_param(char *buf)
+{
+       unsigned long s_addr, e_addr, mask;
+       /*
+        * Patten:  dmc_montiro=[start_addr],[end_addr],[mask]
+        * Example: dmc_monitor=0x00000000,0x20000000,0x7fce
+        */
+       if (!buf)
+               return -EINVAL;
+
+       if (sscanf(buf, "%lx,%lx,%lx", &s_addr, &e_addr, &mask) != 3)
+               return -EINVAL;
+
+       init_start_addr = s_addr;
+       init_end_addr   = e_addr;
+       init_dev_mask   = mask;
+
+       pr_info("%s, buf:%s, %lx-%lx, %lx\n",
+               __func__, buf, s_addr, e_addr, mask);
+
+       return 0;
+}
+early_param("dmc_monitor", early_dmc_param);
+
 unsigned long dmc_rw(unsigned long addr, unsigned long value, int rw)
 {
        struct arm_smccc_res smccc;
@@ -343,6 +371,10 @@ static int dmc_monitor_probe(struct platform_device *pdev)
        INIT_DELAYED_WORK(&dmc_mon->work, clear_irq_work);
        schedule_delayed_work(&dmc_mon->work, HZ);
 
+       if (init_dev_mask)
+               dmc_set_monitor(init_start_addr,
+                               init_end_addr, init_dev_mask, 1);
+
        return 0;
 inval:
        kfree(dmc_mon);