video: exynos_fimd: Add framework to disable FIMD sysmmu
authorAjay Kumar <ajaykumar.rs@samsung.com>
Fri, 5 Sep 2014 11:23:33 +0000 (16:53 +0530)
committerMinkyu Kang <mk7.kang@samsung.com>
Fri, 5 Sep 2014 11:37:07 +0000 (20:37 +0900)
On Exynos5420 and newer versions, the FIMD sysmmus are in
"on state" by default.
We have to disable them in order to make FIMD DMA work.
This patch adds the required framework to exynos_fimd driver,
and disables FIMD sysmmu on Exynos5420.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
arch/arm/dts/exynos54xx.dtsi
doc/device-tree-bindings/video/exynos-fb.txt
drivers/video/exynos_fimd.c
include/fdtdec.h
lib/fdtdec.c

index b9f8e0bd3dafe711c8cb1e2b6a374f699b51f949..c21d798a23d0b54a295d6f0a90a8f5c578f925dc 100644 (file)
                status = "disabled";
        };
 
+       fimdm0_sysmmu@0x14640000 {
+               compatible = "samsung,sysmmu-v3.3";
+               reg = <0x14640000 0x100>;
+       };
+
+       fimdm1_sysmmu@0x14680000 {
+               compatible = "samsung,sysmmu-v3.3";
+               reg = <0x14680000 0x100>;
+       };
+
        fimd@14400000 {
                /* sysmmu is not used in U-Boot */
                samsung,disable-sysmmu;
index bb7441cbbedf06286d36edf9fa8c574df078833c..dc4e44fbc52b319f3480e00ea2e16c15121b4def 100644 (file)
@@ -55,6 +55,12 @@ Board(panel specific):
        samsung,pclk-name: parent clock identifier: 1(MPLL), 2(EPLL), 3(VPLL)
        samsung,sclk-div: parent_clock/source_clock ratio
        samsung,dual-lcd-enabled: 1 if you support two LCD, else 0
+       samsung,disable-sysmmu: Define this if you want to disable FIMD sysmmu.
+                               (needed for Exynos5420 and newer versions)
+                               Add the required FIMD sysmmu nodes to be
+                               disabled with compatible string
+                               "samsung,sysmmu-v3.3", with a "reg" property
+                               holding the register address of FIMD sysmmu.
 
 Example:
 SOC specific part:
index cebbba7581e40c26992c6388c3d0552dac76c14b..f67fa817ed13938a1965046b24dfe0c7364ef389 100644 (file)
@@ -251,6 +251,45 @@ void exynos_fimd_window_off(unsigned int win_id)
        writel(cfg, &fimd_ctrl->winshmap);
 }
 
+#ifdef CONFIG_OF_CONTROL
+/*
+* The reset value for FIMD SYSMMU register MMU_CTRL is 3
+* on Exynos5420 and newer versions.
+* This means FIMD SYSMMU is on by default on Exynos5420
+* and newer versions.
+* Since in u-boot we don't use SYSMMU, we should disable
+* those FIMD SYSMMU.
+* Note that there are 2 SYSMMU for FIMD: m0 and m1.
+* m0 handles windows 0 and 4, and m1 handles windows 1, 2 and 3.
+* We disable both of them here.
+*/
+void exynos_fimd_disable_sysmmu(void)
+{
+       u32 *sysmmufimd;
+       unsigned int node;
+       int node_list[2];
+       int count;
+       int i;
+
+       count = fdtdec_find_aliases_for_id(gd->fdt_blob, "fimd",
+                               COMPAT_SAMSUNG_EXYNOS_SYSMMU, node_list, 2);
+       for (i = 0; i < count; i++) {
+               node = node_list[i];
+               if (node <= 0) {
+                       debug("Can't get device node for fimd sysmmu\n");
+                       return;
+               }
+
+               sysmmufimd = (u32 *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
+               if (!sysmmufimd) {
+                       debug("Can't get base address for sysmmu fimdm0");
+                       return;
+               }
+
+               writel(0x0, sysmmufimd);
+       }
+}
+#endif
 
 void exynos_fimd_lcd_init(vidinfo_t *vid)
 {
@@ -268,6 +307,10 @@ void exynos_fimd_lcd_init(vidinfo_t *vid)
                                                                node, "reg");
        if (fimd_ctrl == NULL)
                debug("Can't get the FIMD base address\n");
+
+       if (fdtdec_get_bool(gd->fdt_blob, node, "samsung,disable-sysmmu"))
+               exynos_fimd_disable_sysmmu();
+
 #else
        fimd_ctrl = (struct exynos_fb *)samsung_get_base_fimd();
 #endif
index 856e6cf766dea73ac3de4e009391052a891fd9e8..d883bd263e66b41d266965bf4cfb6be737707f5a 100644 (file)
@@ -94,6 +94,7 @@ enum fdt_compat_id {
        COMPAT_SANDBOX_LCD_SDL,         /* Sandbox LCD emulation with SDL */
        COMPAT_TI_TPS65090,             /* Texas Instrument TPS65090 */
        COMPAT_NXP_PTN3460,             /* NXP PTN3460 DP/LVDS bridge */
+       COMPAT_SAMSUNG_EXYNOS_SYSMMU,   /* Exynos sysmmu */
 
        COMPAT_COUNT,
 };
index eb5aa20526fd509618311fdb3b4aab3c6379d46d..d95135d6e7ec187e39435086304b7474bd5e9897 100644 (file)
@@ -70,6 +70,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
        COMPAT(TI_TPS65090, "ti,tps65090"),
        COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"),
+       COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)