Add devicetree mail list.
On 01/09/2014 01:13 PM, Zhou Zhu wrote:
add device tree support for mmp fb/controller
the description at Documentation/devicetree/bindings/fb/mmp-disp.txt

Signed-off-by: Zhou Zhu <[email protected]>
---
  Documentation/devicetree/bindings/fb/mmp-disp.txt |   71 ++++++++++++
  drivers/video/mmp/fb/mmpfb.c                      |   71 ++++++++----
  drivers/video/mmp/hw/mmp_ctrl.c                   |  120 ++++++++++++++++-----
  3 files changed, 217 insertions(+), 45 deletions(-)
  create mode 100644 Documentation/devicetree/bindings/fb/mmp-disp.txt

diff --git a/Documentation/devicetree/bindings/fb/mmp-disp.txt 
b/Documentation/devicetree/bindings/fb/mmp-disp.txt
new file mode 100644
index 0000000..3cf2903
--- /dev/null
+++ b/Documentation/devicetree/bindings/fb/mmp-disp.txt
@@ -0,0 +1,71 @@
+* Marvell MMP Display (MMP_DISP)
+
+To config mmp display, 3 parts are required to be set in dts:
+1. mmp fb
+Required properties:
+- compatible: Should be "marvell,mmp-fb".
+- marvell,fb-name: Should be the name of this fb.
+- marvell,path-name: Should be the name of path this fb connecting to.
+- marvell,overlay-id: Should be the id of overlay this fb is on.
+- marvell,dmafetch-id: Should be the dma fetch id this fb using.
+- marvell,default-pixfmt: Should be the default pixel format when this fb is
+turned on.
+
+2. mmp controller
+Required properties:
+- compatible: Should be "marvell,mmp-disp".
+- reg: Should be address and length of the register set for this controller.
+- interrupts: Should be interrupt of this controller.
+- marvell,disp-name: Should be name of this controller
+- marvell,path-num: Should be path number exists in this controller.
+- marvell,clk-name: Should be name of clock this controller using.
+
+Required sub-node:
+- path:
+Required properties in this sub-node:
+-- marvell,path-name: Should be name of this path, fb/panel uses this name to
+connect to this path.
+-- marvell,overlay_num: Should be number of overlay this path has.
+-- marvell,output-type: Should be output-type settings
+-- marvell,path-config: Should be path-config settings
+-- marvell,link-config: Should be link-config settings
+-- marvell,rbswap: Should be rbswap settings
+
+3. panel
+Required properties:
+- marvell,path-name: Should be path name that this panel connected to.
+- other properties each panel has.
+
+Examples:
+
+fb: fb {
+       compatible = "marvell,mmp-fb";
+       marvell,fb-name = "mmp_fb";
+       marvell,path-name = "mmp_pnpath";
+       marvell,overlay-id = <0>;
+       marvell,dmafetch-id = <1>;
+       marvell,default-pixfmt = <0x108>;
+};
+
+disp: disp@d420b000 {
+       compatible = "marvell,mmp-disp";
+       reg = <0xd420b000 0x1fc>;
+       interrupts = <0 41 0x4>;
+       marvell,disp-name = "mmp_disp";
+       marvell,path-num = <1>;
+       marvell,clk-name = "LCDCIHCLK";
+       path1 {
+               marvell,path-name = "mmp_pnpath";
+               marvell,overlay-num = <2>;
+               marvell,output-type = <0>;
+               marvell,path-config = <0x20000000>;
+               marvell,link-config = <0x60000001>;
+               marvell,rbswap = <0>;
+       };
+};
+
+panel: <panel-name> {
+       ...
+       marvell,path-name = "mmp_pnpath";
+       ...
+};
diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/mmp/fb/mmpfb.c
index 7ab31eb..e84a411 100644
--- a/drivers/video/mmp/fb/mmpfb.c
+++ b/drivers/video/mmp/fb/mmpfb.c
@@ -22,6 +22,8 @@
  #include <linux/module.h>
  #include <linux/dma-mapping.h>
  #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
  #include "mmpfb.h"

  static int var_to_pixfmt(struct fb_var_screeninfo *var)
@@ -551,56 +553,86 @@ static void fb_info_clear(struct fb_info *info)
        fb_dealloc_cmap(&info->cmap);
  }

+#ifdef CONFIG_OF
+static const struct of_device_id mmp_fb_dt_match[] = {
+       { .compatible = "marvell,mmp-fb" },
+       {},
+};
+#endif
+
  static int mmpfb_probe(struct platform_device *pdev)
  {
+#ifdef CONFIG_OF
+       struct device_node *np;
+#else
        struct mmp_buffer_driver_mach_info *mi;
+#endif
        struct fb_info *info = 0;
        struct mmpfb_info *fbi = 0;
-       int ret, modes_num;
-
-       mi = pdev->dev.platform_data;
-       if (mi == NULL) {
-               dev_err(&pdev->dev, "no platform data defined\n");
-               return -EINVAL;
-       }
+       int ret = -EINVAL, modes_num;
+       int overlay_id, dmafetch_id;
+       const char *path_name;

        /* initialize fb */
        info = framebuffer_alloc(sizeof(struct mmpfb_info), &pdev->dev);
        if (info == NULL)
                return -ENOMEM;
        fbi = info->par;
-       if (!fbi) {
-               ret = -EINVAL;
+       if (!fbi)
+               goto failed;
+
+#ifdef CONFIG_OF
+       np = pdev->dev.of_node;
+
+       if (!np || of_property_read_string(np,
+                               "marvell,fb-name", &fbi->name) ||
+                       of_property_read_string(np,
+                               "marvell,path-name", &path_name) ||
+                       of_property_read_u32(np,
+                               "marvell,overlay-id", &overlay_id) ||
+                       of_property_read_u32(np,
+                               "marvell,dmafetch-id", &dmafetch_id) ||
+                       of_property_read_u32(np,
+                               "marvell,default-pixfmt", &fbi->pix_fmt)) {
+               dev_err(&pdev->dev, "unable to get fb setting from dt\n");
                goto failed;
        }
+#else
+       mi = pdev->dev.platform_data;
+       if (mi == NULL) {
+               dev_err(&pdev->dev, "no platform data defined\n");
+               goto failed;
+       }
+       fbi->name = mi->name;
+       path_name = mi->path_name;
+       overlay_id = mi->overlay_id;
+       dmafetch_id = mi->dmafetch_id;
+       fbi->pix_fmt = mi->default_pixfmt;
+#endif

        /* init fb */
        fbi->fb_info = info;
        platform_set_drvdata(pdev, fbi);
        fbi->dev = &pdev->dev;
-       fbi->name = mi->name;
-       fbi->pix_fmt = mi->default_pixfmt;
        pixfmt_to_var(&info->var, fbi->pix_fmt);
        mutex_init(&fbi->access_ok);

        /* get display path by name */
-       fbi->path = mmp_get_path(mi->path_name);
+       fbi->path = mmp_get_path(path_name);
        if (!fbi->path) {
-               dev_err(&pdev->dev, "can't get the path %s\n", mi->path_name);
-               ret = -EINVAL;
+               dev_err(&pdev->dev, "can't get the path %s\n", path_name);
                goto failed_destroy_mutex;
        }

        dev_info(fbi->dev, "path %s get\n", fbi->path->name);

        /* get overlay */
-       fbi->overlay = mmp_path_get_overlay(fbi->path, mi->overlay_id);
-       if (!fbi->overlay) {
-               ret = -EINVAL;
+       fbi->overlay = mmp_path_get_overlay(fbi->path, overlay_id);
+       if (!fbi->overlay)
                goto failed_destroy_mutex;
-       }
+
        /* set fetch used */
-       mmp_overlay_set_fetch(fbi->overlay, mi->dmafetch_id);
+       mmp_overlay_set_fetch(fbi->overlay, dmafetch_id);

        modes_num = modes_setup(fbi);
        if (modes_num < 0) {
@@ -679,6 +711,7 @@ static struct platform_driver mmpfb_driver = {
        .driver         = {
                .name   = "mmp-fb",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(mmp_fb_dt_match),
        },
        .probe          = mmpfb_probe,
  };
diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c
index 8621a9f..19d68bc 100644
--- a/drivers/video/mmp/hw/mmp_ctrl.c
+++ b/drivers/video/mmp/hw/mmp_ctrl.c
@@ -37,6 +37,8 @@
  #include <linux/uaccess.h>
  #include <linux/kthread.h>
  #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>

  #include "mmp_ctrl.h"

@@ -396,26 +398,57 @@ static void path_set_default(struct mmp_path *path)
        writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));
  }

-static int path_init(struct mmphw_path_plat *path_plat,
-               struct mmp_mach_path_config *config)
+static int path_init(struct mmphw_path_plat *path_plat, void *arg)
  {
        struct mmphw_ctrl *ctrl = path_plat->ctrl;
        struct mmp_path_info *path_info;
        struct mmp_path *path = NULL;
-
-       dev_info(ctrl->dev, "%s: %s\n", __func__, config->name);
+#ifdef CONFIG_OF
+       struct device_node *path_np = arg;
+#else
+       struct mmp_mach_path_config *config = arg;
+#endif

        /* init driver data */
        path_info = kzalloc(sizeof(struct mmp_path_info), GFP_KERNEL);
        if (!path_info) {
-               dev_err(ctrl->dev, "%s: unable to alloc path_info for %s\n",
-                               __func__, config->name);
-               return 0;
+               dev_err(ctrl->dev, "%s: unable to alloc path_info\n",
+                               __func__);
+               return -ENOMEM;
+       }
+
+#ifdef CONFIG_OF
+       if (!path_np || of_property_read_string(path_np, "marvell,path-name",
+                               &path_info->name) ||
+                       of_property_read_u32(path_np, "marvell,overlay-num",
+                               &path_info->output_type) ||
+                       of_property_read_u32(path_np, "marvell,output-type",
+                               &path_info->overlay_num)) {
+               dev_err(ctrl->dev, "%s: unable to get path setting from dt\n",
+                       __func__);
+               kfree(path_info);
+               return -EINVAL;
        }
+       /* allow these settings not set */
+       of_property_read_u32(path_np, "marvell,path-config",
+               &path_plat->path_config);
+       of_property_read_u32(path_np, "marvell,link-config",
+               &path_plat->link_config);
+       of_property_read_u32(path_np, "marvell,rbswap",
+               &path_plat->dsi_rbswap);
+#else
        path_info->name = config->name;
+       path_info->overlay_num = config->overlay_num;
+       path_info->output_type = config->output_type;
+       path_plat->path_config = config->path_config;
+       path_plat->link_config = config->link_config;
+       path_plat->dsi_rbswap = config->dsi_rbswap;
+#endif
+
+       dev_info(ctrl->dev, "%s: %s\n", __func__, path_info->name);
+
        path_info->id = path_plat->id;
        path_info->dev = ctrl->dev;
-       path_info->overlay_num = config->overlay_num;
        path_info->overlay_ops = &mmphw_overlay_ops;
        path_info->set_mode = path_set_mode;
        path_info->plat_data = path_plat;
@@ -424,16 +457,13 @@ static int path_init(struct mmphw_path_plat *path_plat,
        path = mmp_register_path(path_info);
        if (!path) {
                kfree(path_info);
-               return 0;
+               return -EINVAL;
        }
        path_plat->path = path;
-       path_plat->path_config = config->path_config;
-       path_plat->link_config = config->link_config;
-       path_plat->dsi_rbswap = config->dsi_rbswap;
        path_set_default(path);

        kfree(path_info);
-       return 1;
+       return 0;
  }

  static void path_deinit(struct mmphw_path_plat *path_plat)
@@ -445,13 +475,25 @@ static void path_deinit(struct mmphw_path_plat *path_plat)
                mmp_unregister_path(path_plat->path);
  }

+#ifdef CONFIG_OF
+static const struct of_device_id mmp_disp_dt_match[] = {
+       { .compatible = "marvell,mmp-disp" },
+       {},
+};
+#endif
+
  static int mmphw_probe(struct platform_device *pdev)
  {
-       struct mmp_mach_plat_info *mi;
        struct resource *res;
-       int ret, i, size, irq;
+       int ret, i, size, irq, path_num;
+       const char *clk_name, *disp_name;
        struct mmphw_path_plat *path_plat;
        struct mmphw_ctrl *ctrl = NULL;
+#ifdef CONFIG_OF
+       struct device_node *np, *path_np = NULL;
+#else
+       struct mmp_mach_plat_info *mi;
+#endif

        /* get resources from platform data */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -468,6 +510,22 @@ static int mmphw_probe(struct platform_device *pdev)
                goto failed;
        }

+#ifdef CONFIG_OF
+       np = pdev->dev.of_node;
+
+       if (!np || of_property_read_u32(np,
+                               "marvell,path-num", &path_num) ||
+                       of_property_read_string(np,
+                               "marvell,disp-name", &disp_name) ||
+                       of_property_read_string(np,
+                               "marvell,clk-name", &clk_name) ||
+                       of_get_child_count(np) != ctrl->path_num) {
+               dev_err(&pdev->dev, "%s: failed to get settings from dt\n",
+                       __func__);
+               ret = -EINVAL;
+               goto failed;
+       }
+#else
        /* get configs from platform data */
        mi = pdev->dev.platform_data;
        if (mi == NULL || !mi->path_num || !mi->paths) {
@@ -476,17 +534,21 @@ static int mmphw_probe(struct platform_device *pdev)
                goto failed;
        }

-       /* allocate */
+       disp_name = mi->name;
+       path_num = mi->path_num;
+       clk_name = mi->clk_name;
+#endif
+
+       /* allocate ctrl */
        size = sizeof(struct mmphw_ctrl) + sizeof(struct mmphw_path_plat) *
-              mi->path_num;
+              path_num;
        ctrl = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
        if (!ctrl) {
                ret = -ENOMEM;
                goto failed;
        }
-
-       ctrl->name = mi->name;
-       ctrl->path_num = mi->path_num;
+       ctrl->path_num = path_num;
+       ctrl->name = disp_name;
        ctrl->dev = &pdev->dev;
        ctrl->irq = irq;
        platform_set_drvdata(pdev, ctrl);
@@ -521,9 +583,9 @@ static int mmphw_probe(struct platform_device *pdev)
        }

        /* get clock */
-       ctrl->clk = devm_clk_get(ctrl->dev, mi->clk_name);
+       ctrl->clk = devm_clk_get(ctrl->dev, clk_name);
        if (IS_ERR(ctrl->clk)) {
-               dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name);
+               dev_err(ctrl->dev, "unable to get clk %s\n", clk_name);
                ret = -ENOENT;
                goto failed;
        }
@@ -539,11 +601,16 @@ static int mmphw_probe(struct platform_device *pdev)
                path_plat->id = i;
                path_plat->ctrl = ctrl;

-               /* path init */
-               if (!path_init(path_plat, &mi->paths[i])) {
-                       ret = -EINVAL;
+               /* path init from mach info or dt */
+#ifdef CONFIG_OF
+               path_np = of_get_next_child(np, path_np);
+               ret = path_init(path_plat, path_np);
+#else
+               ret = path_init(path_plat, &mi->paths[i]);
+#endif
+
+               if (ret)
                        goto failed_path_init;
-               }
        }

  #ifdef CONFIG_MMP_DISP_SPI
@@ -573,6 +640,7 @@ static struct platform_driver mmphw_driver = {
        .driver         = {
                .name   = "mmp-disp",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(mmp_disp_dt_match),
        },
        .probe          = mmphw_probe,
  };


--
Thanks, -Zhou
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to