From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anatolij Gustschin Date: Fri, 30 Apr 2010 10:19:47 +0000 Subject: Re: [PATCH 3/5] powerpc/mpc5121: shared DIU framebuffer support Message-Id: <20100430121947.1d265ca6@wker> List-Id: References: <1272584978-19063-1-git-send-email-agust@denx.de> <1272584978-19063-4-git-send-email-agust@denx.de> In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit To: Timur Tabi Cc: linux-fbdev@vger.kernel.org, wd@denx.de, dzu@denx.de, John Rigby , devicetree-discuss@lists.ozlabs.org, linuxppc-dev@ozlabs.org, yorksun@freescale.com On Thu, 29 Apr 2010 21:05:26 -0500 Timur Tabi wrote: > On Thu, Apr 29, 2010 at 6:49 PM, Anatolij Gustschin wrote: > > > > +void __init mpc5121_ads_init_early(void) > > +{ > > +       mpc512x_init_diu(); > > +} > > + > >  define_machine(mpc5121_ads) { > >        .name                   = "MPC5121 ADS", > >        .probe                  = mpc5121_ads_probe, > >        .setup_arch             = mpc5121_ads_setup_arch, > >        .init                   = mpc512x_init, > > +       .init_early             = mpc5121_ads_init_early, > > How about just doing this? > > .init_early = mpc512x_init_diu, I thought it should be prepared for adding other code here. mpc5121_ads_init_early() is generic and could contain other things as well. I would vote for current version. > > +void __init mpc512x_generic_init_early(void) > > +{ > > +       mpc512x_init_diu(); > > +} > > + > > +void __init mpc512x_generic_setup_arch(void) > > +{ > > +       mpc512x_setup_diu(); > > +} > > + > >  define_machine(mpc5121_generic) { > >        .name                   = "MPC5121 generic", > >        .probe                  = mpc5121_generic_probe, > >        .init                   = mpc512x_init, > > +       .init_early             = mpc512x_generic_init_early, > > +       .setup_arch             = mpc512x_generic_setup_arch, > > And a similar change here. Same here. ... > > diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c > > index b7f518a..8e297fa 100644 > > --- a/arch/powerpc/platforms/512x/mpc512x_shared.c > > +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c > > @@ -16,7 +16,11 @@ > >  #include > >  #include > >  #include > > +#include > > +#include > > +#include > > > > +#include > >  #include > >  #include > >  #include > > @@ -53,6 +57,286 @@ void mpc512x_restart(char *cmd) > >                ; > >  } > > > > +struct fsl_diu_shared_fb { > > +       char            gamma[0x300];   /* 32-bit aligned! */ > > char or u8? Will use u8. > > +       struct diu_ad   ad0;            /* 32-bit aligned! */ > > +       phys_addr_t     fb_phys; > > +       size_t          fb_len; > > +       bool            in_use; > > +}; > > Where did "bool" come from? Use "int" instead. It is common practise to use "bool" type, grep in drivers dir. > > +unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel, > > +                                     int monitor_port) > > +{ > > +       unsigned int pix_fmt; > > + > > +       switch (bits_per_pixel) { > > +       case 32: > > +               pix_fmt = 0x88883316; > > +               break; > > +       case 24: > > +               pix_fmt = 0x88082219; > > +               break; > > +       case 16: > > +               pix_fmt = 0x65053118; > > +               break; > > +       default: > > +               pix_fmt = 0x00000400; > > +       } > > +       return pix_fmt; > > +} > > This is simpler: > > switch (bits_per_pixel) { > case 32: > return 0x88883316; > case 24: > return 0x88082219; > case 16: > return = 0x65053118; > } > > return 0x00000400; > } Will simplify as suggested, thanks! > > +       ccm = of_iomap(np, 0); > > +       if (!ccm) { > > +               pr_err("Can't map clock control module reg.\n"); > > +               of_node_put(np); > > +               return; > > +       } > > +       of_node_put(np); > > This is simpler: > > ccm = of_iomap(np, 0); > of_node_put(np); > if (!ccm) { > pr_err("Can't map clock control module reg.\n"); > return; > } OK, will fix, thanks. > > > +       np = of_find_node_by_type(NULL, "cpu"); > > +       if (np) { > > +               unsigned int size; > > +               const unsigned int *prop > > +                       of_get_property(np, "bus-frequency", &size); > > Since you don't use 'size', you can skip it: > > const unsigned int *prop > of_get_property(np, "bus-frequency", NULL); > > > +       } else { > > +               pr_err("Can't find \"cpu\" node.\n"); > > 'cpu' is simpler than \"cpu\" Will simplify, too. > > +       /* Calculate the pixel clock with the smallest error */ > > +       /* calculate the following in steps to avoid overflow */ > > +       pr_debug("DIU pixclock in ps - %d\n", pixclock); > > +       temp = (1000000000 / pixclock) * 1000; > > I'm pretty sure the compiler will optimize this to: > > temp = (1000000000000UL / pixclock); > > so you may as well do it that way. ?? 1000000000000 is _not_ UL, but UUL. > > > +       pixclock = temp; > > +       pr_debug("DIU pixclock freq - %u\n", pixclock); > > + > > +       temp = (temp * 5) / 100; /* pixclock * 0.05 */ > > The compiler will optimize this to: > > temp /= 20; Can do it, too. Thanks. > > +       pr_debug("deviation = %d\n", temp); > > +       minpixclock = pixclock - temp; > > +       maxpixclock = pixclock + temp; > > +       pr_debug("DIU minpixclock - %lu\n", minpixclock); > > +       pr_debug("DIU maxpixclock - %lu\n", maxpixclock); > > +       pixval = speed_ccb/pixclock; > > +       pr_debug("DIU pixval = %lu\n", pixval); > > + > > +       err = 100000000; > > Why do you assign err to this arbitrary value? Dunno. It is Freescale's code and I do not have time to check and understand each bit of it and to explain it. > > +       bestval = pixval; > > +       pr_debug("DIU bestval = %lu\n", bestval); > > + > > +       bestfreq = 0; > > +       for (i = -1; i <= 1; i++) { > > +               temp = speed_ccb / (pixval+i); > > +               pr_debug("DIU test pixval i=%d, pixval=%lu, temp freq. = %u\n", > > +                       i, pixval, temp); > > +               if ((temp < minpixclock) || (temp > maxpixclock)) > > +                       pr_debug("DIU exceeds monitor range (%lu to %lu)\n", > > +                               minpixclock, maxpixclock); > > +               else if (abs(temp - pixclock) < err) { > > +                       pr_debug("Entered the else if block %d\n", i); > > +                       err = abs(temp - pixclock); > > +                       bestval = pixval + i; > > +                       bestfreq = temp; > > +               } > > +       } > > + > > +       pr_debug("DIU chose = %lx\n", bestval); > > +       pr_debug("DIU error = %ld\n NomPixClk ", err); > > +       pr_debug("DIU: Best Freq = %lx\n", bestfreq); > > +       /* Modify DIU_DIV in CCM SCFR1 */ > > +       temp = in_be32(ccm + CCM_SCFR1); > > Don't use offsets like + CCM_SCFR1. Create a structure and use that instead. Done in next patch version. > > +       pr_debug("DIU: Current value of SCFR1: 0x%08x\n", temp); > > +       temp &= ~DIU_DIV_MASK; > > +       temp |= (bestval & DIU_DIV_MASK); > > +       out_be32(ccm + CCM_SCFR1, temp); > > +       pr_debug("DIU: Modified value of SCFR1: 0x%08x\n", temp); > > +       iounmap(ccm); > > +} > > + > > +ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf) > > +{ > > +       return snprintf(buf, PAGE_SIZE, "0 - 5121 LCD\n"); > > There's no point in using snprintf since you're printing a string > literal. You can use sprintf. Will do, thanks. > > +} > > + > > +int mpc512x_set_sysfs_monitor_port(int val) > > +{ > > +       return 0; > > +} > > + > > +static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb; > > + > > +#if defined(CONFIG_FB_FSL_DIU) || \ > > +    defined(CONFIG_FB_FSL_DIU_MODULE) > > +static inline void mpc512x_free_bootmem(struct page *page) > > +{ > > +       __ClearPageReserved(page); > > +       BUG_ON(PageTail(page)); > > +       BUG_ON(atomic_read(&page->_count) > 1); > > +       atomic_set(&page->_count, 1); > > +       __free_page(page); > > +       totalram_pages++; > > +} > > + > > +void mpc512x_release_bootmem(void) > > +{ > > +       unsigned long addr = diu_shared_fb.fb_phys & PAGE_MASK; > > +       unsigned long size = diu_shared_fb.fb_len; > > +       unsigned long start, end; > > + > > +       if (diu_shared_fb.in_use) { > > +               start = PFN_UP(addr); > > +               end = PFN_DOWN(addr + size); > > + > > +               for (; start < end; start++) > > +                       mpc512x_free_bootmem(pfn_to_page(start)); > > + > > +               diu_shared_fb.in_use = false; > > +       } > > +       diu_ops.release_bootmem = NULL; > > +} > > +#endif > > Do you really need to use reserve_bootmem? Have you tried kmalloc or > alloc_pages_exact()? Yes. No, it is too early to use them here. > > + > > +/* > > + * Check if DIU was pre-initialized. If so, perform steps > > + * needed to continue displaying through the whole boot process. > > + * Move area descriptor and gamma table elsewhere, they are > > + * destroyed by bootmem allocator otherwise. The frame buffer > > + * address range will be reserved in setup_arch() after bootmem > > + * allocator is up. > > + */ > > +void __init mpc512x_init_diu(void) > > +{ > > +       struct device_node *np; > > +       void __iomem *diu_reg; > > +       phys_addr_t desc; > > +       void __iomem *vaddr; > > +       unsigned long mode, pix_fmt, res, bpp; > > +       unsigned long dst; > > + > > +       np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu"); > > +       if (!np) { > > +               pr_err("No DIU node\n"); > > +               return; > > +       } > > Shouldn't you be probing as an OF driver instead of manually searching > for the DIU node? No, not here. > > + > > +       diu_reg = of_iomap(np, 0); > > +       of_node_put(np); > > +       if (!diu_reg) { > > +               pr_err("Can't map DIU\n"); > > +               return; > > +       } > > + > > +       mode = in_be32(diu_reg + 0x1c); > > +       if (mode != 1) { > > How can in_be32() return a -1? It is a 1, not -1. I will use appropriate macro here and also change to use a struct instead of adding offset to register base. Thanks for your review and comments! Anatolij From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by ozlabs.org (Postfix) with ESMTP id 163E4B7D45 for ; Fri, 30 Apr 2010 20:19:51 +1000 (EST) Date: Fri, 30 Apr 2010 12:19:47 +0200 From: Anatolij Gustschin To: Timur Tabi Subject: Re: [PATCH 3/5] powerpc/mpc5121: shared DIU framebuffer support Message-ID: <20100430121947.1d265ca6@wker> In-Reply-To: References: <1272584978-19063-1-git-send-email-agust@denx.de> <1272584978-19063-4-git-send-email-agust@denx.de> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Cc: linux-fbdev@vger.kernel.org, wd@denx.de, dzu@denx.de, John Rigby , devicetree-discuss@lists.ozlabs.org, linuxppc-dev@ozlabs.org, yorksun@freescale.com List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Thu, 29 Apr 2010 21:05:26 -0500 Timur Tabi wrote: > On Thu, Apr 29, 2010 at 6:49 PM, Anatolij Gustschin wrote: >=20 >=20 > > +void __init mpc5121_ads_init_early(void) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 mpc512x_init_diu(); > > +} > > + > > =C2=A0define_machine(mpc5121_ads) { > > =C2=A0 =C2=A0 =C2=A0 =C2=A0.name =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =3D "MPC5121 ADS", > > =C2=A0 =C2=A0 =C2=A0 =C2=A0.probe =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D mpc5121_ads_probe, > > =C2=A0 =C2=A0 =C2=A0 =C2=A0.setup_arch =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =3D mpc5121_ads_setup_arch, > > =C2=A0 =C2=A0 =C2=A0 =C2=A0.init =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =3D mpc512x_init, > > + =C2=A0 =C2=A0 =C2=A0 .init_early =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D mpc5121_ads_init_early, >=20 > How about just doing this? >=20 > .init_early =3D mpc512x_init_diu, I thought it should be prepared for adding other code here. mpc5121_ads_init_early() is generic and could contain other things as well. I would vote for current version. > > +void __init mpc512x_generic_init_early(void) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 mpc512x_init_diu(); > > +} > > + > > +void __init mpc512x_generic_setup_arch(void) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 mpc512x_setup_diu(); > > +} > > + > > =C2=A0define_machine(mpc5121_generic) { > > =C2=A0 =C2=A0 =C2=A0 =C2=A0.name =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =3D "MPC5121 generic", > > =C2=A0 =C2=A0 =C2=A0 =C2=A0.probe =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D mpc5121_generic_probe, > > =C2=A0 =C2=A0 =C2=A0 =C2=A0.init =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =3D mpc512x_init, > > + =C2=A0 =C2=A0 =C2=A0 .init_early =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D mpc512x_generic_init_early, > > + =C2=A0 =C2=A0 =C2=A0 .setup_arch =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D mpc512x_generic_setup_arch, >=20 > And a similar change here. Same here. ... > > diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerp= c/platforms/512x/mpc512x_shared.c > > index b7f518a..8e297fa 100644 > > --- a/arch/powerpc/platforms/512x/mpc512x_shared.c > > +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c > > @@ -16,7 +16,11 @@ > > =C2=A0#include > > =C2=A0#include > > =C2=A0#include > > +#include > > +#include > > +#include > > > > +#include > > =C2=A0#include > > =C2=A0#include > > =C2=A0#include > > @@ -53,6 +57,286 @@ void mpc512x_restart(char *cmd) > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0; > > =C2=A0} > > > > +struct fsl_diu_shared_fb { > > + =C2=A0 =C2=A0 =C2=A0 char =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ga= mma[0x300]; =C2=A0 /* 32-bit aligned! */ >=20 > char or u8? Will use u8. > > + =C2=A0 =C2=A0 =C2=A0 struct diu_ad =C2=A0 ad0; =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0/* 32-bit aligned! */ > > + =C2=A0 =C2=A0 =C2=A0 phys_addr_t =C2=A0 =C2=A0 fb_phys; > > + =C2=A0 =C2=A0 =C2=A0 size_t =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fb_len; > > + =C2=A0 =C2=A0 =C2=A0 bool =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0in= _use; > > +}; >=20 > Where did "bool" come from? Use "int" instead. It is common practise to use "bool" type, grep in drivers dir. > > +unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel, > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int monitor_port) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 unsigned int pix_fmt; > > + > > + =C2=A0 =C2=A0 =C2=A0 switch (bits_per_pixel) { > > + =C2=A0 =C2=A0 =C2=A0 case 32: > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pix_fmt =3D 0x888833= 16; > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > > + =C2=A0 =C2=A0 =C2=A0 case 24: > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pix_fmt =3D 0x880822= 19; > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > > + =C2=A0 =C2=A0 =C2=A0 case 16: > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pix_fmt =3D 0x650531= 18; > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > > + =C2=A0 =C2=A0 =C2=A0 default: > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pix_fmt =3D 0x000004= 00; > > + =C2=A0 =C2=A0 =C2=A0 } > > + =C2=A0 =C2=A0 =C2=A0 return pix_fmt; > > +} >=20 > This is simpler: >=20 > switch (bits_per_pixel) { > case 32: > return 0x88883316; > case 24: > return 0x88082219; > case 16: > return =3D 0x65053118; > } >=20 > return 0x00000400; > } Will simplify as suggested, thanks! > > + =C2=A0 =C2=A0 =C2=A0 ccm =3D of_iomap(np, 0); > > + =C2=A0 =C2=A0 =C2=A0 if (!ccm) { > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_err("Can't map cl= ock control module reg.\n"); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 of_node_put(np); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return; > > + =C2=A0 =C2=A0 =C2=A0 } > > + =C2=A0 =C2=A0 =C2=A0 of_node_put(np); >=20 > This is simpler: >=20 > ccm =3D of_iomap(np, 0); > of_node_put(np); > if (!ccm) { > pr_err("Can't map clock control module reg.\n"); > return; > } OK, will fix, thanks. >=20 > > + =C2=A0 =C2=A0 =C2=A0 np =3D of_find_node_by_type(NULL, "cpu"); > > + =C2=A0 =C2=A0 =C2=A0 if (np) { > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 unsigned int size; > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const unsigned int *= prop =3D > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 of_get_property(np, "bus-frequency", &size); >=20 > Since you don't use 'size', you can skip it: >=20 > const unsigned int *prop =3D > of_get_property(np, "bus-frequency", NULL); >=20 > > + =C2=A0 =C2=A0 =C2=A0 } else { > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_err("Can't find \= "cpu\" node.\n"); >=20 > 'cpu' is simpler than \"cpu\" Will simplify, too. > > + =C2=A0 =C2=A0 =C2=A0 /* Calculate the pixel clock with the smallest e= rror */ > > + =C2=A0 =C2=A0 =C2=A0 /* calculate the following in steps to avoid ove= rflow */ > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU pixclock in ps - %d\n", pixclock); > > + =C2=A0 =C2=A0 =C2=A0 temp =3D (1000000000 / pixclock) * 1000; >=20 > I'm pretty sure the compiler will optimize this to: >=20 > temp =3D (1000000000000UL / pixclock); >=20 > so you may as well do it that way. ?? 1000000000000 is _not_ UL, but UUL. >=20 > > + =C2=A0 =C2=A0 =C2=A0 pixclock =3D temp; > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU pixclock freq - %u\n", pixclock); > > + > > + =C2=A0 =C2=A0 =C2=A0 temp =3D (temp * 5) / 100; /* pixclock * 0.05 */ >=20 > The compiler will optimize this to: >=20 > temp /=3D 20; Can do it, too. Thanks. > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("deviation =3D %d\n", temp); > > + =C2=A0 =C2=A0 =C2=A0 minpixclock =3D pixclock - temp; > > + =C2=A0 =C2=A0 =C2=A0 maxpixclock =3D pixclock + temp; > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU minpixclock - %lu\n", minpixclock); > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU maxpixclock - %lu\n", maxpixclock); > > + =C2=A0 =C2=A0 =C2=A0 pixval =3D speed_ccb/pixclock; > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU pixval =3D %lu\n", pixval); > > + > > + =C2=A0 =C2=A0 =C2=A0 err =3D 100000000; >=20 > Why do you assign err to this arbitrary value? Dunno. It is Freescale's code and I do not have time to check and understand each bit of it and to explain it. > > + =C2=A0 =C2=A0 =C2=A0 bestval =3D pixval; > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU bestval =3D %lu\n", bestval); > > + > > + =C2=A0 =C2=A0 =C2=A0 bestfreq =3D 0; > > + =C2=A0 =C2=A0 =C2=A0 for (i =3D -1; i <=3D 1; i++) { > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 temp =3D speed_ccb /= (pixval+i); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU test p= ixval i=3D%d, pixval=3D%lu, temp freq. =3D %u\n", > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 i, pixval, temp); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if ((temp < minpixcl= ock) || (temp > maxpixclock)) > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 pr_debug("DIU exceeds monitor range (%lu to %lu)\n", > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 minpixclock, maxpixclock); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else if (abs(temp - = pixclock) < err) { > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 pr_debug("Entered the else if block %d\n", i); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 err =3D abs(temp - pixclock); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 bestval =3D pixval + i; > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 bestfreq =3D temp; > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > > + =C2=A0 =C2=A0 =C2=A0 } > > + > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU chose =3D %lx\n", bestval); > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU error =3D %ld\n NomPixClk ", err); > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU: Best Freq =3D %lx\n", bestfreq); > > + =C2=A0 =C2=A0 =C2=A0 /* Modify DIU_DIV in CCM SCFR1 */ > > + =C2=A0 =C2=A0 =C2=A0 temp =3D in_be32(ccm + CCM_SCFR1); >=20 > Don't use offsets like + CCM_SCFR1. Create a structure and use that inst= ead. Done in next patch version. > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU: Current value of SCFR1: 0x%08x\n"= , temp); > > + =C2=A0 =C2=A0 =C2=A0 temp &=3D ~DIU_DIV_MASK; > > + =C2=A0 =C2=A0 =C2=A0 temp |=3D (bestval & DIU_DIV_MASK); > > + =C2=A0 =C2=A0 =C2=A0 out_be32(ccm + CCM_SCFR1, temp); > > + =C2=A0 =C2=A0 =C2=A0 pr_debug("DIU: Modified value of SCFR1: 0x%08x\n= ", temp); > > + =C2=A0 =C2=A0 =C2=A0 iounmap(ccm); > > +} > > + > > +ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 return snprintf(buf, PAGE_SIZE, "0 - 5121 LCD\n"= ); >=20 > There's no point in using snprintf since you're printing a string > literal. You can use sprintf. Will do, thanks. > > +} > > + > > +int mpc512x_set_sysfs_monitor_port(int val) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 return 0; > > +} > > + > > +static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_s= hared_fb; > > + > > +#if defined(CONFIG_FB_FSL_DIU) || \ > > + =C2=A0 =C2=A0defined(CONFIG_FB_FSL_DIU_MODULE) > > +static inline void mpc512x_free_bootmem(struct page *page) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 __ClearPageReserved(page); > > + =C2=A0 =C2=A0 =C2=A0 BUG_ON(PageTail(page)); > > + =C2=A0 =C2=A0 =C2=A0 BUG_ON(atomic_read(&page->_count) > 1); > > + =C2=A0 =C2=A0 =C2=A0 atomic_set(&page->_count, 1); > > + =C2=A0 =C2=A0 =C2=A0 __free_page(page); > > + =C2=A0 =C2=A0 =C2=A0 totalram_pages++; > > +} > > + > > +void mpc512x_release_bootmem(void) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 unsigned long addr =3D diu_shared_fb.fb_phys & P= AGE_MASK; > > + =C2=A0 =C2=A0 =C2=A0 unsigned long size =3D diu_shared_fb.fb_len; > > + =C2=A0 =C2=A0 =C2=A0 unsigned long start, end; > > + > > + =C2=A0 =C2=A0 =C2=A0 if (diu_shared_fb.in_use) { > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 start =3D PFN_UP(add= r); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end =3D PFN_DOWN(add= r + size); > > + > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for (; start < end; = start++) > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 mpc512x_free_bootmem(pfn_to_page(start)); > > + > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 diu_shared_fb.in_use= =3D false; > > + =C2=A0 =C2=A0 =C2=A0 } > > + =C2=A0 =C2=A0 =C2=A0 diu_ops.release_bootmem =3D NULL; > > +} > > +#endif >=20 > Do you really need to use reserve_bootmem? Have you tried kmalloc or > alloc_pages_exact()? Yes. No, it is too early to use them here. > > + > > +/* > > + * Check if DIU was pre-initialized. If so, perform steps > > + * needed to continue displaying through the whole boot process. > > + * Move area descriptor and gamma table elsewhere, they are > > + * destroyed by bootmem allocator otherwise. The frame buffer > > + * address range will be reserved in setup_arch() after bootmem > > + * allocator is up. > > + */ > > +void __init mpc512x_init_diu(void) > > +{ > > + =C2=A0 =C2=A0 =C2=A0 struct device_node *np; > > + =C2=A0 =C2=A0 =C2=A0 void __iomem *diu_reg; > > + =C2=A0 =C2=A0 =C2=A0 phys_addr_t desc; > > + =C2=A0 =C2=A0 =C2=A0 void __iomem *vaddr; > > + =C2=A0 =C2=A0 =C2=A0 unsigned long mode, pix_fmt, res, bpp; > > + =C2=A0 =C2=A0 =C2=A0 unsigned long dst; > > + > > + =C2=A0 =C2=A0 =C2=A0 np =3D of_find_compatible_node(NULL, NULL, "fsl,= mpc5121-diu"); > > + =C2=A0 =C2=A0 =C2=A0 if (!np) { > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_err("No DIU node\= n"); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return; > > + =C2=A0 =C2=A0 =C2=A0 } >=20 > Shouldn't you be probing as an OF driver instead of manually searching > for the DIU node? No, not here. > > + > > + =C2=A0 =C2=A0 =C2=A0 diu_reg =3D of_iomap(np, 0); > > + =C2=A0 =C2=A0 =C2=A0 of_node_put(np); > > + =C2=A0 =C2=A0 =C2=A0 if (!diu_reg) { > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_err("Can't map DI= U\n"); > > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return; > > + =C2=A0 =C2=A0 =C2=A0 } > > + > > + =C2=A0 =C2=A0 =C2=A0 mode =3D in_be32(diu_reg + 0x1c); > > + =C2=A0 =C2=A0 =C2=A0 if (mode !=3D 1) { >=20 > How can in_be32() return a -1? It is a 1, not -1. I will use appropriate macro here and also change to use a struct instead of adding offset to register base. Thanks for your review and comments! Anatolij From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anatolij Gustschin Subject: Re: [PATCH 3/5] powerpc/mpc5121: shared DIU framebuffer support Date: Fri, 30 Apr 2010 12:19:47 +0200 Message-ID: <20100430121947.1d265ca6@wker> References: <1272584978-19063-1-git-send-email-agust@denx.de> <1272584978-19063-4-git-send-email-agust@denx.de> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linuxppc-dev-bounces+glppe-linuxppc-embedded-2=m.gmane.org@lists.ozlabs.org Errors-To: linuxppc-dev-bounces+glppe-linuxppc-embedded-2=m.gmane.org@lists.ozlabs.org To: Timur Tabi Cc: linux-fbdev@vger.kernel.org, wd@denx.de, dzu@denx.de, John Rigby , devicetree-discuss@lists.ozlabs.org, linuxppc-dev@ozlabs.org, yorksun@freescale.com List-Id: devicetree@vger.kernel.org T24gVGh1LCAyOSBBcHIgMjAxMCAyMTowNToyNiAtMDUwMApUaW11ciBUYWJpIDx0aW11ci50YWJp QGdtYWlsLmNvbT4gd3JvdGU6Cgo+IE9uIFRodSwgQXByIDI5LCAyMDEwIGF0IDY6NDkgUE0sIEFu YXRvbGlqIEd1c3RzY2hpbiA8YWd1c3RAZGVueC5kZT4gd3JvdGU6Cj4gCj4gCj4gPiArdm9pZCBf X2luaXQgbXBjNTEyMV9hZHNfaW5pdF9lYXJseSh2b2lkKQo+ID4gK3sKPiA+ICsgwqAgwqAgwqAg bXBjNTEyeF9pbml0X2RpdSgpOwo+ID4gK30KPiA+ICsKPiA+IMKgZGVmaW5lX21hY2hpbmUobXBj NTEyMV9hZHMpIHsKPiA+IMKgIMKgIMKgIMKgLm5hbWUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgPSAiTVBDNTEyMSBBRFMiLAo+ID4gwqAgwqAgwqAgwqAucHJvYmUgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqA9IG1wYzUxMjFfYWRzX3Byb2JlLAo+ID4gwqAgwqAgwqAgwqAuc2V0dXBfYXJj aCDCoCDCoCDCoCDCoCDCoCDCoCA9IG1wYzUxMjFfYWRzX3NldHVwX2FyY2gsCj4gPiDCoCDCoCDC oCDCoC5pbml0IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgID0gbXBjNTEyeF9pbml0LAo+ID4g KyDCoCDCoCDCoCAuaW5pdF9lYXJseSDCoCDCoCDCoCDCoCDCoCDCoCA9IG1wYzUxMjFfYWRzX2lu aXRfZWFybHksCj4gCj4gSG93IGFib3V0IGp1c3QgZG9pbmcgdGhpcz8KPiAKPiAuaW5pdF9lYXJs eSAgICAgICAgICAgICA9IG1wYzUxMnhfaW5pdF9kaXUsCgpJIHRob3VnaHQgaXQgc2hvdWxkIGJl IHByZXBhcmVkIGZvciBhZGRpbmcgb3RoZXIgY29kZSBoZXJlLgptcGM1MTIxX2Fkc19pbml0X2Vh cmx5KCkgaXMgZ2VuZXJpYyBhbmQgY291bGQgY29udGFpbiBvdGhlcgp0aGluZ3MgYXMgd2VsbC4g SSB3b3VsZCB2b3RlIGZvciBjdXJyZW50IHZlcnNpb24uCgo+ID4gK3ZvaWQgX19pbml0IG1wYzUx MnhfZ2VuZXJpY19pbml0X2Vhcmx5KHZvaWQpCj4gPiArewo+ID4gKyDCoCDCoCDCoCBtcGM1MTJ4 X2luaXRfZGl1KCk7Cj4gPiArfQo+ID4gKwo+ID4gK3ZvaWQgX19pbml0IG1wYzUxMnhfZ2VuZXJp Y19zZXR1cF9hcmNoKHZvaWQpCj4gPiArewo+ID4gKyDCoCDCoCDCoCBtcGM1MTJ4X3NldHVwX2Rp dSgpOwo+ID4gK30KPiA+ICsKPiA+IMKgZGVmaW5lX21hY2hpbmUobXBjNTEyMV9nZW5lcmljKSB7 Cj4gPiDCoCDCoCDCoCDCoC5uYW1lIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgID0gIk1QQzUx MjEgZ2VuZXJpYyIsCj4gPiDCoCDCoCDCoCDCoC5wcm9iZSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoD0gbXBjNTEyMV9nZW5lcmljX3Byb2JlLAo+ID4gwqAgwqAgwqAgwqAuaW5pdCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCA9IG1wYzUxMnhfaW5pdCwKPiA+ICsgwqAgwqAgwqAgLmluaXRf ZWFybHkgwqAgwqAgwqAgwqAgwqAgwqAgPSBtcGM1MTJ4X2dlbmVyaWNfaW5pdF9lYXJseSwKPiA+ ICsgwqAgwqAgwqAgLnNldHVwX2FyY2ggwqAgwqAgwqAgwqAgwqAgwqAgPSBtcGM1MTJ4X2dlbmVy aWNfc2V0dXBfYXJjaCwKPiAKPiBBbmQgYSBzaW1pbGFyIGNoYW5nZSBoZXJlLgoKU2FtZSBoZXJl LgoKLi4uCj4gPiBkaWZmIC0tZ2l0IGEvYXJjaC9wb3dlcnBjL3BsYXRmb3Jtcy81MTJ4L21wYzUx Mnhfc2hhcmVkLmMgYi9hcmNoL3Bvd2VycGMvcGxhdGZvcm1zLzUxMngvbXBjNTEyeF9zaGFyZWQu Ywo+ID4gaW5kZXggYjdmNTE4YS4uOGUyOTdmYSAxMDA2NDQKPiA+IC0tLSBhL2FyY2gvcG93ZXJw Yy9wbGF0Zm9ybXMvNTEyeC9tcGM1MTJ4X3NoYXJlZC5jCj4gPiArKysgYi9hcmNoL3Bvd2VycGMv cGxhdGZvcm1zLzUxMngvbXBjNTEyeF9zaGFyZWQuYwo+ID4gQEAgLTE2LDcgKzE2LDExIEBACj4g PiDCoCNpbmNsdWRlIDxsaW51eC9pby5oPgo+ID4gwqAjaW5jbHVkZSA8bGludXgvaXJxLmg+Cj4g PiDCoCNpbmNsdWRlIDxsaW51eC9vZl9wbGF0Zm9ybS5oPgo+ID4gKyNpbmNsdWRlIDxsaW51eC9m c2wtZGl1LWZiLmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L2Jvb3RtZW0uaD4KPiA+ICsjaW5jbHVk ZSA8c3lzZGV2L2ZzbF9zb2MuaD4KPiA+Cj4gPiArI2luY2x1ZGUgPGFzbS9jYWNoZWZsdXNoLmg+ Cj4gPiDCoCNpbmNsdWRlIDxhc20vbWFjaGRlcC5oPgo+ID4gwqAjaW5jbHVkZSA8YXNtL2lwaWMu aD4KPiA+IMKgI2luY2x1ZGUgPGFzbS9wcm9tLmg+Cj4gPiBAQCAtNTMsNiArNTcsMjg2IEBAIHZv aWQgbXBjNTEyeF9yZXN0YXJ0KGNoYXIgKmNtZCkKPiA+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg Owo+ID4gwqB9Cj4gPgo+ID4gK3N0cnVjdCBmc2xfZGl1X3NoYXJlZF9mYiB7Cj4gPiArIMKgIMKg IMKgIGNoYXIgwqAgwqAgwqAgwqAgwqAgwqBnYW1tYVsweDMwMF07IMKgIC8qIDMyLWJpdCBhbGln bmVkISAqLwo+IAo+IGNoYXIgb3IgdTg/CgpXaWxsIHVzZSB1OC4KCj4gPiArIMKgIMKgIMKgIHN0 cnVjdCBkaXVfYWQgwqAgYWQwOyDCoCDCoCDCoCDCoCDCoCDCoC8qIDMyLWJpdCBhbGlnbmVkISAq Lwo+ID4gKyDCoCDCoCDCoCBwaHlzX2FkZHJfdCDCoCDCoCBmYl9waHlzOwo+ID4gKyDCoCDCoCDC oCBzaXplX3QgwqAgwqAgwqAgwqAgwqBmYl9sZW47Cj4gPiArIMKgIMKgIMKgIGJvb2wgwqAgwqAg wqAgwqAgwqAgwqBpbl91c2U7Cj4gPiArfTsKPiAKPiBXaGVyZSBkaWQgImJvb2wiIGNvbWUgZnJv bT8gIFVzZSAiaW50IiBpbnN0ZWFkLgoKSXQgaXMgY29tbW9uIHByYWN0aXNlIHRvIHVzZSAiYm9v bCIgdHlwZSwgZ3JlcCBpbiBkcml2ZXJzIGRpci4KCj4gPiArdW5zaWduZWQgaW50IG1wYzUxMnhf Z2V0X3BpeGVsX2Zvcm1hdCh1bnNpZ25lZCBpbnQgYml0c19wZXJfcGl4ZWwsCj4gPiArIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGludCBtb25p dG9yX3BvcnQpCj4gPiArewo+ID4gKyDCoCDCoCDCoCB1bnNpZ25lZCBpbnQgcGl4X2ZtdDsKPiA+ ICsKPiA+ICsgwqAgwqAgwqAgc3dpdGNoIChiaXRzX3Blcl9waXhlbCkgewo+ID4gKyDCoCDCoCDC oCBjYXNlIDMyOgo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwaXhfZm10ID0gMHg4ODg4MzMx NjsKPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYnJlYWs7Cj4gPiArIMKgIMKgIMKgIGNhc2Ug MjQ6Cj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHBpeF9mbXQgPSAweDg4MDgyMjE5Owo+ID4g KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBicmVhazsKPiA+ICsgwqAgwqAgwqAgY2FzZSAxNjoKPiA+ ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcGl4X2ZtdCA9IDB4NjUwNTMxMTg7Cj4gPiArIMKgIMKg IMKgIMKgIMKgIMKgIMKgIGJyZWFrOwo+ID4gKyDCoCDCoCDCoCBkZWZhdWx0Ogo+ID4gKyDCoCDC oCDCoCDCoCDCoCDCoCDCoCBwaXhfZm10ID0gMHgwMDAwMDQwMDsKPiA+ICsgwqAgwqAgwqAgfQo+ ID4gKyDCoCDCoCDCoCByZXR1cm4gcGl4X2ZtdDsKPiA+ICt9Cj4gCj4gVGhpcyBpcyBzaW1wbGVy Ogo+IAo+ICAgICAgICBzd2l0Y2ggKGJpdHNfcGVyX3BpeGVsKSB7Cj4gICAgICAgIGNhc2UgMzI6 Cj4gICAgICAgICAgICAgICAgcmV0dXJuIDB4ODg4ODMzMTY7Cj4gICAgICAgIGNhc2UgMjQ6Cj4g ICAgICAgICAgICAgICAgcmV0dXJuIDB4ODgwODIyMTk7Cj4gICAgICAgIGNhc2UgMTY6Cj4gICAg ICAgICAgICAgICAgcmV0dXJuID0gMHg2NTA1MzExODsKPiAgICAgICB9Cj4gCj4gICAgICAgcmV0 dXJuIDB4MDAwMDA0MDA7Cj4gfQoKV2lsbCBzaW1wbGlmeSBhcyBzdWdnZXN0ZWQsIHRoYW5rcyEK Cj4gPiArIMKgIMKgIMKgIGNjbSA9IG9mX2lvbWFwKG5wLCAwKTsKPiA+ICsgwqAgwqAgwqAgaWYg KCFjY20pIHsKPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcHJfZXJyKCJDYW4ndCBtYXAgY2xv Y2sgY29udHJvbCBtb2R1bGUgcmVnLlxuIik7Cj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG9m X25vZGVfcHV0KG5wKTsKPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuOwo+ID4gKyDC oCDCoCDCoCB9Cj4gPiArIMKgIMKgIMKgIG9mX25vZGVfcHV0KG5wKTsKPiAKPiBUaGlzIGlzIHNp bXBsZXI6Cj4gCj4gICAgICAgIGNjbSA9IG9mX2lvbWFwKG5wLCAwKTsKPiAgICAgICAgb2Zfbm9k ZV9wdXQobnApOwo+ICAgICAgICBpZiAoIWNjbSkgewo+ICAgICAgICAgICAgICAgIHByX2Vycigi Q2FuJ3QgbWFwIGNsb2NrIGNvbnRyb2wgbW9kdWxlIHJlZy5cbiIpOwo+ICAgICAgICAgICAgICAg IHJldHVybjsKPiAgICAgICAgfQoKT0ssIHdpbGwgZml4LCB0aGFua3MuCgo+IAo+ID4gKyDCoCDC oCDCoCBucCA9IG9mX2ZpbmRfbm9kZV9ieV90eXBlKE5VTEwsICJjcHUiKTsKPiA+ICsgwqAgwqAg wqAgaWYgKG5wKSB7Cj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHVuc2lnbmVkIGludCBzaXpl Owo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjb25zdCB1bnNpZ25lZCBpbnQgKnByb3AgPQo+ ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBvZl9nZXRfcHJvcGVydHkobnAs ICJidXMtZnJlcXVlbmN5IiwgJnNpemUpOwo+IAo+IFNpbmNlIHlvdSBkb24ndCB1c2UgJ3NpemUn LCB5b3UgY2FuIHNraXAgaXQ6Cj4gCj4gICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBpbnQg KnByb3AgPQo+ICAgICAgICAgICAgICAgICAgICAgICBvZl9nZXRfcHJvcGVydHkobnAsICJidXMt ZnJlcXVlbmN5IiwgTlVMTCk7Cj4gCj4gPiArIMKgIMKgIMKgIH0gZWxzZSB7Cj4gPiArIMKgIMKg IMKgIMKgIMKgIMKgIMKgIHByX2VycigiQ2FuJ3QgZmluZCBcImNwdVwiIG5vZGUuXG4iKTsKPiAK PiAnY3B1JyBpcyBzaW1wbGVyIHRoYW4gXCJjcHVcIgoKV2lsbCBzaW1wbGlmeSwgdG9vLgoKPiA+ ICsgwqAgwqAgwqAgLyogQ2FsY3VsYXRlIHRoZSBwaXhlbCBjbG9jayB3aXRoIHRoZSBzbWFsbGVz dCBlcnJvciAqLwo+ID4gKyDCoCDCoCDCoCAvKiBjYWxjdWxhdGUgdGhlIGZvbGxvd2luZyBpbiBz dGVwcyB0byBhdm9pZCBvdmVyZmxvdyAqLwo+ID4gKyDCoCDCoCDCoCBwcl9kZWJ1ZygiRElVIHBp eGNsb2NrIGluIHBzIC0gJWRcbiIsIHBpeGNsb2NrKTsKPiA+ICsgwqAgwqAgwqAgdGVtcCA9ICgx MDAwMDAwMDAwIC8gcGl4Y2xvY2spICogMTAwMDsKPiAKPiBJJ20gcHJldHR5IHN1cmUgdGhlIGNv bXBpbGVyIHdpbGwgb3B0aW1pemUgdGhpcyB0bzoKPiAKPiAgICAgdGVtcCA9ICgxMDAwMDAwMDAw MDAwVUwgLyBwaXhjbG9jayk7Cj4gCj4gc28geW91IG1heSBhcyB3ZWxsIGRvIGl0IHRoYXQgd2F5 LgoKPz8KMTAwMDAwMDAwMDAwMCBpcyBfbm90XyBVTCwgYnV0IFVVTC4KCj4gCj4gPiArIMKgIMKg IMKgIHBpeGNsb2NrID0gdGVtcDsKPiA+ICsgwqAgwqAgwqAgcHJfZGVidWcoIkRJVSBwaXhjbG9j ayBmcmVxIC0gJXVcbiIsIHBpeGNsb2NrKTsKPiA+ICsKPiA+ICsgwqAgwqAgwqAgdGVtcCA9ICh0 ZW1wICogNSkgLyAxMDA7IC8qIHBpeGNsb2NrICogMC4wNSAqLwo+IAo+IFRoZSBjb21waWxlciB3 aWxsIG9wdGltaXplIHRoaXMgdG86Cj4gCj4gICAgIHRlbXAgLz0gMjA7CgpDYW4gZG8gaXQsIHRv by4gVGhhbmtzLgoKPiA+ICsgwqAgwqAgwqAgcHJfZGVidWcoImRldmlhdGlvbiA9ICVkXG4iLCB0 ZW1wKTsKPiA+ICsgwqAgwqAgwqAgbWlucGl4Y2xvY2sgPSBwaXhjbG9jayAtIHRlbXA7Cj4gPiAr IMKgIMKgIMKgIG1heHBpeGNsb2NrID0gcGl4Y2xvY2sgKyB0ZW1wOwo+ID4gKyDCoCDCoCDCoCBw cl9kZWJ1ZygiRElVIG1pbnBpeGNsb2NrIC0gJWx1XG4iLCBtaW5waXhjbG9jayk7Cj4gPiArIMKg IMKgIMKgIHByX2RlYnVnKCJESVUgbWF4cGl4Y2xvY2sgLSAlbHVcbiIsIG1heHBpeGNsb2NrKTsK PiA+ICsgwqAgwqAgwqAgcGl4dmFsID0gc3BlZWRfY2NiL3BpeGNsb2NrOwo+ID4gKyDCoCDCoCDC oCBwcl9kZWJ1ZygiRElVIHBpeHZhbCA9ICVsdVxuIiwgcGl4dmFsKTsKPiA+ICsKPiA+ICsgwqAg wqAgwqAgZXJyID0gMTAwMDAwMDAwOwo+IAo+IFdoeSBkbyB5b3UgYXNzaWduIGVyciB0byB0aGlz IGFyYml0cmFyeSB2YWx1ZT8KCkR1bm5vLiBJdCBpcyBGcmVlc2NhbGUncyBjb2RlIGFuZCBJIGRv IG5vdCBoYXZlIHRpbWUgdG8gY2hlY2sKYW5kIHVuZGVyc3RhbmQgZWFjaCBiaXQgb2YgaXQgYW5k IHRvIGV4cGxhaW4gaXQuCgo+ID4gKyDCoCDCoCDCoCBiZXN0dmFsID0gcGl4dmFsOwo+ID4gKyDC oCDCoCDCoCBwcl9kZWJ1ZygiRElVIGJlc3R2YWwgPSAlbHVcbiIsIGJlc3R2YWwpOwo+ID4gKwo+ ID4gKyDCoCDCoCDCoCBiZXN0ZnJlcSA9IDA7Cj4gPiArIMKgIMKgIMKgIGZvciAoaSA9IC0xOyBp IDw9IDE7IGkrKykgewo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB0ZW1wID0gc3BlZWRfY2Ni IC8gKHBpeHZhbCtpKTsKPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcHJfZGVidWcoIkRJVSB0 ZXN0IHBpeHZhbCBpPSVkLCBwaXh2YWw9JWx1LCB0ZW1wIGZyZXEuID0gJXVcbiIsCj4gPiArIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGksIHBpeHZhbCwgdGVtcCk7Cj4gPiArIMKg IMKgIMKgIMKgIMKgIMKgIMKgIGlmICgodGVtcCA8IG1pbnBpeGNsb2NrKSB8fCAodGVtcCA+IG1h eHBpeGNsb2NrKSkKPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcHJfZGVi dWcoIkRJVSBleGNlZWRzIG1vbml0b3IgcmFuZ2UgKCVsdSB0byAlbHUpXG4iLAo+ID4gKyDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBtaW5waXhjbG9jaywgbWF4 cGl4Y2xvY2spOwo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBlbHNlIGlmIChhYnModGVtcCAt IHBpeGNsb2NrKSA8IGVycikgewo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCBwcl9kZWJ1ZygiRW50ZXJlZCB0aGUgZWxzZSBpZiBibG9jayAlZFxuIiwgaSk7Cj4gPiArIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGVyciA9IGFicyh0ZW1wIC0gcGl4Y2xvY2sp Owo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBiZXN0dmFsID0gcGl4dmFs ICsgaTsKPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYmVzdGZyZXEgPSB0 ZW1wOwo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9Cj4gPiArIMKgIMKgIMKgIH0KPiA+ICsK PiA+ICsgwqAgwqAgwqAgcHJfZGVidWcoIkRJVSBjaG9zZSA9ICVseFxuIiwgYmVzdHZhbCk7Cj4g PiArIMKgIMKgIMKgIHByX2RlYnVnKCJESVUgZXJyb3IgPSAlbGRcbiBOb21QaXhDbGsgIiwgZXJy KTsKPiA+ICsgwqAgwqAgwqAgcHJfZGVidWcoIkRJVTogQmVzdCBGcmVxID0gJWx4XG4iLCBiZXN0 ZnJlcSk7Cj4gPiArIMKgIMKgIMKgIC8qIE1vZGlmeSBESVVfRElWIGluIENDTSBTQ0ZSMSAqLwo+ ID4gKyDCoCDCoCDCoCB0ZW1wID0gaW5fYmUzMihjY20gKyBDQ01fU0NGUjEpOwo+IAo+IERvbid0 IHVzZSBvZmZzZXRzIGxpa2UgKyBDQ01fU0NGUjEuICBDcmVhdGUgYSBzdHJ1Y3R1cmUgYW5kIHVz ZSB0aGF0IGluc3RlYWQuCgpEb25lIGluIG5leHQgcGF0Y2ggdmVyc2lvbi4KCj4gPiArIMKgIMKg IMKgIHByX2RlYnVnKCJESVU6IEN1cnJlbnQgdmFsdWUgb2YgU0NGUjE6IDB4JTA4eFxuIiwgdGVt cCk7Cj4gPiArIMKgIMKgIMKgIHRlbXAgJj0gfkRJVV9ESVZfTUFTSzsKPiA+ICsgwqAgwqAgwqAg dGVtcCB8PSAoYmVzdHZhbCAmIERJVV9ESVZfTUFTSyk7Cj4gPiArIMKgIMKgIMKgIG91dF9iZTMy KGNjbSArIENDTV9TQ0ZSMSwgdGVtcCk7Cj4gPiArIMKgIMKgIMKgIHByX2RlYnVnKCJESVU6IE1v ZGlmaWVkIHZhbHVlIG9mIFNDRlIxOiAweCUwOHhcbiIsIHRlbXApOwo+ID4gKyDCoCDCoCDCoCBp b3VubWFwKGNjbSk7Cj4gPiArfQo+ID4gKwo+ID4gK3NzaXplX3QgbXBjNTEyeF9zaG93X21vbml0 b3JfcG9ydChpbnQgbW9uaXRvcl9wb3J0LCBjaGFyICpidWYpCj4gPiArewo+ID4gKyDCoCDCoCDC oCByZXR1cm4gc25wcmludGYoYnVmLCBQQUdFX1NJWkUsICIwIC0gNTEyMSBMQ0RcbiIpOwo+IAo+ IFRoZXJlJ3Mgbm8gcG9pbnQgaW4gdXNpbmcgc25wcmludGYgc2luY2UgeW91J3JlIHByaW50aW5n IGEgc3RyaW5nCj4gbGl0ZXJhbC4gIFlvdSBjYW4gdXNlIHNwcmludGYuCgpXaWxsIGRvLCB0aGFu a3MuCgo+ID4gK30KPiA+ICsKPiA+ICtpbnQgbXBjNTEyeF9zZXRfc3lzZnNfbW9uaXRvcl9wb3J0 KGludCB2YWwpCj4gPiArewo+ID4gKyDCoCDCoCDCoCByZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4g PiArc3RhdGljIHN0cnVjdCBmc2xfZGl1X3NoYXJlZF9mYiBfX2F0dHJpYnV0ZV9fICgoX19hbGln bmVkX18oOCkpKSBkaXVfc2hhcmVkX2ZiOwo+ID4gKwo+ID4gKyNpZiBkZWZpbmVkKENPTkZJR19G Ql9GU0xfRElVKSB8fCBcCj4gPiArIMKgIMKgZGVmaW5lZChDT05GSUdfRkJfRlNMX0RJVV9NT0RV TEUpCj4gPiArc3RhdGljIGlubGluZSB2b2lkIG1wYzUxMnhfZnJlZV9ib290bWVtKHN0cnVjdCBw YWdlICpwYWdlKQo+ID4gK3sKPiA+ICsgwqAgwqAgwqAgX19DbGVhclBhZ2VSZXNlcnZlZChwYWdl KTsKPiA+ICsgwqAgwqAgwqAgQlVHX09OKFBhZ2VUYWlsKHBhZ2UpKTsKPiA+ICsgwqAgwqAgwqAg QlVHX09OKGF0b21pY19yZWFkKCZwYWdlLT5fY291bnQpID4gMSk7Cj4gPiArIMKgIMKgIMKgIGF0 b21pY19zZXQoJnBhZ2UtPl9jb3VudCwgMSk7Cj4gPiArIMKgIMKgIMKgIF9fZnJlZV9wYWdlKHBh Z2UpOwo+ID4gKyDCoCDCoCDCoCB0b3RhbHJhbV9wYWdlcysrOwo+ID4gK30KPiA+ICsKPiA+ICt2 b2lkIG1wYzUxMnhfcmVsZWFzZV9ib290bWVtKHZvaWQpCj4gPiArewo+ID4gKyDCoCDCoCDCoCB1 bnNpZ25lZCBsb25nIGFkZHIgPSBkaXVfc2hhcmVkX2ZiLmZiX3BoeXMgJiBQQUdFX01BU0s7Cj4g PiArIMKgIMKgIMKgIHVuc2lnbmVkIGxvbmcgc2l6ZSA9IGRpdV9zaGFyZWRfZmIuZmJfbGVuOwo+ ID4gKyDCoCDCoCDCoCB1bnNpZ25lZCBsb25nIHN0YXJ0LCBlbmQ7Cj4gPiArCj4gPiArIMKgIMKg IMKgIGlmIChkaXVfc2hhcmVkX2ZiLmluX3VzZSkgewo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC oCBzdGFydCA9IFBGTl9VUChhZGRyKTsKPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZW5kID0g UEZOX0RPV04oYWRkciArIHNpemUpOwo+ID4gKwo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBm b3IgKDsgc3RhcnQgPCBlbmQ7IHN0YXJ0KyspCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIG1wYzUxMnhfZnJlZV9ib290bWVtKHBmbl90b19wYWdlKHN0YXJ0KSk7Cj4gPiAr Cj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRpdV9zaGFyZWRfZmIuaW5fdXNlID0gZmFsc2U7 Cj4gPiArIMKgIMKgIMKgIH0KPiA+ICsgwqAgwqAgwqAgZGl1X29wcy5yZWxlYXNlX2Jvb3RtZW0g PSBOVUxMOwo+ID4gK30KPiA+ICsjZW5kaWYKPiAKPiBEbyB5b3UgcmVhbGx5IG5lZWQgdG8gdXNl IHJlc2VydmVfYm9vdG1lbT8gIEhhdmUgeW91IHRyaWVkIGttYWxsb2Mgb3IKPiBhbGxvY19wYWdl c19leGFjdCgpPwoKWWVzLiBObywgaXQgaXMgdG9vIGVhcmx5IHRvIHVzZSB0aGVtIGhlcmUuCgo+ ID4gKwo+ID4gKy8qCj4gPiArICogQ2hlY2sgaWYgRElVIHdhcyBwcmUtaW5pdGlhbGl6ZWQuIElm IHNvLCBwZXJmb3JtIHN0ZXBzCj4gPiArICogbmVlZGVkIHRvIGNvbnRpbnVlIGRpc3BsYXlpbmcg dGhyb3VnaCB0aGUgd2hvbGUgYm9vdCBwcm9jZXNzLgo+ID4gKyAqIE1vdmUgYXJlYSBkZXNjcmlw dG9yIGFuZCBnYW1tYSB0YWJsZSBlbHNld2hlcmUsIHRoZXkgYXJlCj4gPiArICogZGVzdHJveWVk IGJ5IGJvb3RtZW0gYWxsb2NhdG9yIG90aGVyd2lzZS4gVGhlIGZyYW1lIGJ1ZmZlcgo+ID4gKyAq IGFkZHJlc3MgcmFuZ2Ugd2lsbCBiZSByZXNlcnZlZCBpbiBzZXR1cF9hcmNoKCkgYWZ0ZXIgYm9v dG1lbQo+ID4gKyAqIGFsbG9jYXRvciBpcyB1cC4KPiA+ICsgKi8KPiA+ICt2b2lkIF9faW5pdCBt cGM1MTJ4X2luaXRfZGl1KHZvaWQpCj4gPiArewo+ID4gKyDCoCDCoCDCoCBzdHJ1Y3QgZGV2aWNl X25vZGUgKm5wOwo+ID4gKyDCoCDCoCDCoCB2b2lkIF9faW9tZW0gKmRpdV9yZWc7Cj4gPiArIMKg IMKgIMKgIHBoeXNfYWRkcl90IGRlc2M7Cj4gPiArIMKgIMKgIMKgIHZvaWQgX19pb21lbSAqdmFk ZHI7Cj4gPiArIMKgIMKgIMKgIHVuc2lnbmVkIGxvbmcgbW9kZSwgcGl4X2ZtdCwgcmVzLCBicHA7 Cj4gPiArIMKgIMKgIMKgIHVuc2lnbmVkIGxvbmcgZHN0Owo+ID4gKwo+ID4gKyDCoCDCoCDCoCBu cCA9IG9mX2ZpbmRfY29tcGF0aWJsZV9ub2RlKE5VTEwsIE5VTEwsICJmc2wsbXBjNTEyMS1kaXUi KTsKPiA+ICsgwqAgwqAgwqAgaWYgKCFucCkgewo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBw cl9lcnIoIk5vIERJVSBub2RlXG4iKTsKPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJu Owo+ID4gKyDCoCDCoCDCoCB9Cj4gCj4gU2hvdWxkbid0IHlvdSBiZSBwcm9iaW5nIGFzIGFuIE9G IGRyaXZlciBpbnN0ZWFkIG9mIG1hbnVhbGx5IHNlYXJjaGluZwo+IGZvciB0aGUgRElVIG5vZGU/ CgpObywgbm90IGhlcmUuCgo+ID4gKwo+ID4gKyDCoCDCoCDCoCBkaXVfcmVnID0gb2ZfaW9tYXAo bnAsIDApOwo+ID4gKyDCoCDCoCDCoCBvZl9ub2RlX3B1dChucCk7Cj4gPiArIMKgIMKgIMKgIGlm ICghZGl1X3JlZykgewo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwcl9lcnIoIkNhbid0IG1h cCBESVVcbiIpOwo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm47Cj4gPiArIMKgIMKg IMKgIH0KPiA+ICsKPiA+ICsgwqAgwqAgwqAgbW9kZSA9IGluX2JlMzIoZGl1X3JlZyArIDB4MWMp Owo+ID4gKyDCoCDCoCDCoCBpZiAobW9kZSAhPSAxKSB7Cj4gCj4gSG93IGNhbiBpbl9iZTMyKCkg cmV0dXJuIGEgLTE/CgpJdCBpcyBhIDEsIG5vdCAtMS4gSSB3aWxsIHVzZSBhcHByb3ByaWF0ZSBt YWNybyBoZXJlIGFuZCBhbHNvCmNoYW5nZSB0byB1c2UgYSBzdHJ1Y3QgaW5zdGVhZCBvZiBhZGRp bmcgb2Zmc2V0IHRvIHJlZ2lzdGVyIGJhc2UuCgpUaGFua3MgZm9yIHlvdXIgcmV2aWV3IGFuZCBj b21tZW50cyEKQW5hdG9saWoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KTGludXhwcGMtZGV2IG1haWxpbmcgbGlzdApMaW51eHBwYy1kZXZAbGlzdHMub3ps YWJzLm9yZwpodHRwczovL2xpc3RzLm96bGFicy5vcmcvbGlzdGluZm8vbGludXhwcGMtZGV2