[PATCH 4/4] [POWERPC] Xilinx: Framebuffer: Use dcr infrastructure.

Grant Likely grant.likely at secretlab.ca
Tue May 6 14:55:53 EST 2008


On Mon, May 5, 2008 at 11:56 AM, Stephen Neuendorffer
<stephen.neuendorffer at xilinx.com> wrote:
> This device contains a dcr interface.  Previously, the dcr interface
>  was assumed to be used in mmio mode, and the register space of the dcr
>  interface was precomputed and stuffed in the device tree.  This patch
>  makes use of the new dcr infrastructure to represent the dcr interface
>  as any other dcr interface in the device tree.  This enables the dcr
>  interface to be connected directly to a native dcr interface in a
>  clean way.
>
>  In particular, the device tree expected looks like:
>
>                         dcr_v29_0: dcr at 0 {
>                                 #address-cells = <1>;
>                                 #size-cells = <1>;
>                                 compatible = "xlnx,dcr-v29-1.00.a";
>                                 VGA_FrameBuffer: tft at 80 {
>                                         compatible = "xlnx,plb-tft-cntlr-ref-1.00.a";
>                                         dcr-parent = <&opb2dcr_bridge_0>;
>                                         dcr-reg = < 80 2 >;
>                                         xlnx,default-tft-base-addr = <7f>;
>                                         xlnx,dps-init = <1>;
>                                         xlnx,on-init = <1>;
>                                         xlnx,pixclk-is-busclk-divby4 = <1>;
>                                 } ;
>                         } ;
>
>                         opb2dcr_bridge_0: opb2dcr-bridge at 40700000 {
>                                 compatible = "xlnx,opb2dcr-bridge-1.00.b";
>                                 dcr-access-method = "mmio";
>                                 dcr-controller ;
>                                 dcr-mmio-range = < 40700000 1000 >;
>                                 dcr-mmio-stride = <4>;
>                                 reg = < 40700000 1000 >;
>                                 xlnx,family = "virtex2p";
>                         } ;

Hmmm, something doesn't quite feel right about this.  The node
describing the tft device is a child of the dcr at 0 node which is the
dcr bus.  However, dcr bindings use dcr-bus and dcr-reg instead of
parent-child relationship to specify how to access the dcr registers.
So, in this example; if the device is described by tft at 80, and the dcr
bus is described by opb2dcr-bridge at 40700000, then what does dcr at 0
describe?  (I do understand what they really describe in EDK terms;
but I'm looking at it through device tree glasses).

I don't think the presence of a dcr at 0 node is a problem, but in this
case #size/address-cells doesn't have any meaning (the child doesn't
have a reg property) and it looks like it should be a child of the
opb2dcr-bridge node (otherwise, what is it attached to?).

Cheers,
g.

>
>  Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer at xilinx.com>
>  ---
>   drivers/video/xilinxfb.c |   54 +++++++++++++++++-----------------------------
>   1 files changed, 20 insertions(+), 34 deletions(-)
>
>  diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
>  index 4d64402..848752e 100644
>  --- a/drivers/video/xilinxfb.c
>  +++ b/drivers/video/xilinxfb.c
>  @@ -37,6 +37,7 @@
>   #endif
>   #include <asm/io.h>
>   #include <linux/xilinxfb.h>
>  +#include <asm/dcr.h>
>
>   #define DRIVER_NAME            "xilinxfb"
>   #define DRIVER_DESCRIPTION     "Xilinx TFT LCD frame buffer driver"
>  @@ -111,8 +112,9 @@ struct xilinxfb_drvdata {
>
>         struct fb_info  info;           /* FB driver info record */
>
>  -       u32             regs_phys;      /* phys. address of the control registers */
>  -       u32 __iomem     *regs;          /* virt. address of the control registers */
>  +       dcr_host_t      dcr_host;
>  +       unsigned int    dcr_start;
>  +       unsigned int    dcr_len;
>
>         void            *fb_virt;       /* virt. address of the frame buffer */
>         dma_addr_t      fb_phys;        /* phys. address of the frame buffer */
>  @@ -135,7 +137,7 @@ struct xilinxfb_drvdata {
>   * when it's needed.
>   */
>   #define xilinx_fb_out_be32(driverdata, offset, val) \
>  -       out_be32(driverdata->regs + offset, val)
>  +       dcr_write(driverdata->dcr_host, offset, val)
>
>   static int
>   xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
>  @@ -203,7 +205,8 @@ static struct fb_ops xilinxfb_ops =
>   * Bus independent setup/teardown
>   */
>
>  -static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
>  +static int xilinxfb_assign(struct device *dev, dcr_host_t dcr_host,
>  +                          unsigned int dcr_start, unsigned int dcr_len,
>                            struct xilinxfb_platform_data *pdata)
>   {
>         struct xilinxfb_drvdata *drvdata;
>  @@ -218,21 +221,9 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
>         }
>         dev_set_drvdata(dev, drvdata);
>
>  -       /* Map the control registers in */
>  -       if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
>  -               dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
>  -                       physaddr);
>  -               rc = -ENODEV;
>  -               goto err_region;
>  -       }
>  -       drvdata->regs_phys = physaddr;
>  -       drvdata->regs = ioremap(physaddr, 8);
>  -       if (!drvdata->regs) {
>  -               dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
>  -                       physaddr);
>  -               rc = -ENODEV;
>  -               goto err_map;
>  -       }
>  +       drvdata->dcr_start = dcr_start;
>  +       drvdata->dcr_len = dcr_len;
>  +       drvdata->dcr_host = dcr_host;
>
>         /* Allocate the framebuffer memory */
>         if (pdata->fb_phys) {
>  @@ -247,7 +238,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
>         if (!drvdata->fb_virt) {
>                 dev_err(dev, "Could not allocate frame buffer memory\n");
>                 rc = -ENOMEM;
>  -               goto err_fbmem;
>  +               goto err_region;
>         }
>
>         /* Clear (turn to black) the framebuffer */
>  @@ -297,7 +288,6 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
>         }
>
>         /* Put a banner in the log (for DEBUG) */
>  -       dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs);
>         dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n",
>                 (void*)drvdata->fb_phys, drvdata->fb_virt, fbsize);
>
>  @@ -313,12 +303,6 @@ err_cmap:
>         /* Turn off the display */
>         xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
>
>  -err_fbmem:
>  -       iounmap(drvdata->regs);
>  -
>  -err_map:
>  -       release_mem_region(physaddr, 8);
>  -
>   err_region:
>         kfree(drvdata);
>         dev_set_drvdata(dev, NULL);
>  @@ -344,9 +328,8 @@ static int xilinxfb_release(struct device *dev)
>
>         /* Turn off the display */
>         xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
>  -       iounmap(drvdata->regs);
>
>  -       release_mem_region(drvdata->regs_phys, 8);
>  +       dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
>
>         kfree(drvdata);
>         dev_set_drvdata(dev, NULL);
>  @@ -362,20 +345,23 @@ static int xilinxfb_release(struct device *dev)
>   static int __devinit
>   xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match)
>   {
>  -       struct resource res;
>         const u32 *prop;
>         struct xilinxfb_platform_data pdata;
>         int size, rc;
>  +       int start, len;
>  +       dcr_host_t dcr_host;
>
>         /* Copy with the default pdata (not a ptr reference!) */
>         pdata = xilinx_fb_default_pdata;
>
>         dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match);
>
>  -       rc = of_address_to_resource(op->node, 0, &res);
>  -       if (rc) {
>  +       start = dcr_resource_start(op->node, 0);
>  +       len = dcr_resource_len(op->node, 0);
>  +       dcr_host = dcr_map(op->node, start, len);
>  +       if (!DCR_MAP_OK(dcr_host)) {
>                 dev_err(&op->dev, "invalid address\n");
>  -               return rc;
>  +               return -ENODEV;
>         }
>
>         prop = of_get_property(op->node, "phys-size", &size);
>  @@ -399,7 +385,7 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match)
>         if (of_find_property(op->node, "rotate-display", NULL))
>                 pdata.rotate_screen = 1;
>
>  -       return xilinxfb_assign(&op->dev, res.start, &pdata);
>  +       return xilinxfb_assign(&op->dev, dcr_host, start, len, &pdata);
>   }
>
>   static int __devexit xilinxfb_of_remove(struct of_device *op)
>  --
>  1.5.3.4-dirty
>
>
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.



More information about the Linuxppc-dev mailing list