The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/mpc85xx/fsl_diu.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2016 Justin Hibbits
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/bus.h>
   33 #include <sys/endian.h>
   34 #include <sys/kernel.h>
   35 #include <sys/module.h>
   36 #include <sys/malloc.h>
   37 #include <sys/rman.h>
   38 #include <sys/fbio.h>
   39 #include <sys/consio.h>
   40 
   41 #include <vm/vm.h>
   42 #include <vm/pmap.h>
   43 
   44 #include <dev/fdt/fdt_common.h>
   45 #include <dev/ofw/openfirm.h>
   46 #include <dev/ofw/ofw_bus.h>
   47 #include <dev/ofw/ofw_bus_subr.h>
   48 
   49 #include <dev/videomode/videomode.h>
   50 #include <dev/videomode/edidvar.h>
   51 
   52 #include <dev/vt/vt.h>
   53 #include <dev/vt/colors/vt_termcolors.h>
   54 
   55 #include <powerpc/mpc85xx/mpc85xx.h>
   56 
   57 #include <machine/bus.h>
   58 #include <machine/cpu.h>
   59 
   60 #include "fb_if.h"
   61 
   62 #define DIU_DESC_1              0x000   /* Plane1 Area Descriptor Pointer Register */
   63 #define DIU_DESC_2              0x004   /* Plane2 Area Descriptor Pointer Register */
   64 #define DIU_DESC_3              0x008   /* Plane3 Area Descriptor Pointer Register */
   65 #define DIU_GAMMA               0x00C   /* Gamma Register */
   66 #define DIU_PALETTE             0x010   /* Palette Register */
   67 #define DIU_CURSOR              0x014   /* Cursor Register */
   68 #define DIU_CURS_POS            0x018   /* Cursor Position Register */
   69 #define  CURSOR_Y_SHIFT          16
   70 #define  CURSOR_X_SHIFT          0
   71 #define DIU_DIU_MODE            0x01C   /* DIU4 Mode */
   72 #define  DIU_MODE_M             0x7
   73 #define  DIU_MODE_S             0
   74 #define  DIU_MODE_NORMAL        0x1
   75 #define  DIU_MODE_2             0x2
   76 #define  DIU_MODE_3             0x3
   77 #define  DIU_MODE_COLBAR        0x4
   78 #define DIU_BGND                0x020   /* Background */
   79 #define DIU_BGND_WB             0x024   /* Background Color in write back Mode Register */
   80 #define DIU_DISP_SIZE           0x028   /* Display Size */
   81 #define  DELTA_Y_S              16
   82 #define  DELTA_X_S              0
   83 #define DIU_WB_SIZE             0x02C   /* Write back Plane Size Register */
   84 #define  DELTA_Y_WB_S           16
   85 #define  DELTA_X_WB_S           0
   86 #define DIU_WB_MEM_ADDR         0x030   /* Address to Store the write back Plane Register */
   87 #define DIU_HSYN_PARA           0x034   /* Horizontal Sync Parameter */
   88 #define  BP_H_SHIFT             22
   89 #define  PW_H_SHIFT             11
   90 #define  FP_H_SHIFT             0
   91 #define DIU_VSYN_PARA           0x038   /* Vertical Sync Parameter */
   92 #define  BP_V_SHIFT             22
   93 #define  PW_V_SHIFT             11
   94 #define  FP_V_SHIFT             0
   95 #define DIU_SYNPOL              0x03C   /* Synchronize Polarity */
   96 #define  BP_VS                  (1 << 4)
   97 #define  BP_HS                  (1 << 3)
   98 #define  INV_CS                 (1 << 2)
   99 #define  INV_VS                 (1 << 1)
  100 #define  INV_HS                 (1 << 0)
  101 #define  INV_PDI_VS             (1 << 8) /* Polarity of PDI input VSYNC. */
  102 #define  INV_PDI_HS             (1 << 9) /* Polarity of PDI input HSYNC. */
  103 #define  INV_PDI_DE             (1 << 10) /* Polarity of PDI input DE. */
  104 #define DIU_THRESHOLD           0x040   /* Threshold */
  105 #define  LS_BF_VS_SHIFT         16
  106 #define  OUT_BUF_LOW_SHIFT      0
  107 #define DIU_INT_STATUS          0x044   /* Interrupt Status */
  108 #define DIU_INT_MASK            0x048   /* Interrupt Mask */
  109 #define DIU_COLBAR_1            0x04C   /* COLBAR_1 */
  110 #define  DIU_COLORBARn_R(x)      ((x & 0xff) << 16)
  111 #define  DIU_COLORBARn_G(x)      ((x & 0xff) << 8)
  112 #define  DIU_COLORBARn_B(x)      ((x & 0xff) << 0)
  113 #define DIU_COLBAR_2            0x050   /* COLBAR_2 */
  114 #define DIU_COLBAR_3            0x054   /* COLBAR_3 */
  115 #define DIU_COLBAR_4            0x058   /* COLBAR_4 */
  116 #define DIU_COLBAR_5            0x05c   /* COLBAR_5 */
  117 #define DIU_COLBAR_6            0x060   /* COLBAR_6 */
  118 #define DIU_COLBAR_7            0x064   /* COLBAR_7 */
  119 #define DIU_COLBAR_8            0x068   /* COLBAR_8 */
  120 #define DIU_FILLING             0x06C   /* Filling Register */
  121 #define DIU_PLUT                0x070   /* Priority Look Up Table Register */
  122 
  123 /* Control Descriptor */
  124 #define DIU_CTRLDESCL(n, m)     0x200 + (0x40 * n) + 0x4 * (m - 1)
  125 #define DIU_CTRLDESCLn_1(n)     DIU_CTRLDESCL(n, 1)
  126 #define DIU_CTRLDESCLn_2(n)     DIU_CTRLDESCL(n, 2)
  127 #define DIU_CTRLDESCLn_3(n)     DIU_CTRLDESCL(n, 3)
  128 #define  TRANS_SHIFT            20
  129 #define DIU_CTRLDESCLn_4(n)     DIU_CTRLDESCL(n, 4)
  130 #define  BPP_MASK               0xf             /* Bit per pixel Mask */
  131 #define  BPP_SHIFT              16              /* Bit per pixel Shift */
  132 #define  BPP24                  0x5
  133 #define  EN_LAYER               (1 << 31)       /* Enable the layer */
  134 #define DIU_CTRLDESCLn_5(n)     DIU_CTRLDESCL(n, 5)
  135 #define DIU_CTRLDESCLn_6(n)     DIU_CTRLDESCL(n, 6)
  136 #define DIU_CTRLDESCLn_7(n)     DIU_CTRLDESCL(n, 7)
  137 #define DIU_CTRLDESCLn_8(n)     DIU_CTRLDESCL(n, 8)
  138 #define DIU_CTRLDESCLn_9(n)     DIU_CTRLDESCL(n, 9)
  139 
  140 #define NUM_LAYERS      1
  141 
  142 struct panel_info {
  143         uint32_t        panel_width;
  144         uint32_t        panel_height;
  145         uint32_t        panel_hbp;
  146         uint32_t        panel_hpw;
  147         uint32_t        panel_hfp;
  148         uint32_t        panel_vbp;
  149         uint32_t        panel_vpw;
  150         uint32_t        panel_vfp;
  151         uint32_t        panel_freq;
  152         uint32_t        clk_div;
  153 };
  154 
  155 struct diu_area_descriptor {
  156         uint32_t        pixel_format;
  157         uint32_t        bitmap_address;
  158         uint32_t        source_size;
  159         uint32_t        aoi_size;
  160         uint32_t        aoi_offset;
  161         uint32_t        display_offset;
  162         uint32_t        chroma_key_max;
  163         uint32_t        chroma_key_min;
  164         uint32_t        next_ad_addr;
  165 } __aligned(32);
  166 
  167 struct diu_softc {
  168         struct resource         *res[2];
  169         void                    *ih;
  170         device_t                sc_dev;
  171         device_t                sc_fbd;         /* fbd child */
  172         struct fb_info          sc_info;
  173         struct panel_info       sc_panel;
  174         struct diu_area_descriptor *sc_planes[3];
  175         uint8_t                 *sc_gamma;
  176         uint8_t                 *sc_cursor;
  177 };
  178 
  179 static struct resource_spec diu_spec[] = {
  180         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
  181         { SYS_RES_IRQ,          0,      RF_ACTIVE },
  182         { -1, 0 }
  183 };
  184 
  185 static int
  186 diu_probe(device_t dev)
  187 {
  188 
  189         if (!ofw_bus_status_okay(dev))
  190                 return (ENXIO);
  191 
  192         if (!ofw_bus_is_compatible(dev, "fsl,diu"))
  193                 return (ENXIO);
  194 
  195         device_set_desc(dev, "Freescale Display Interface Unit");
  196         return (BUS_PROBE_DEFAULT);
  197 }
  198 
  199 static void
  200 diu_intr(void *arg)
  201 {
  202         struct diu_softc *sc;
  203         int reg;
  204 
  205         sc = arg;
  206 
  207         /* Ack interrupts */
  208         reg = bus_read_4(sc->res[0], DIU_INT_STATUS);
  209         bus_write_4(sc->res[0], DIU_INT_STATUS, reg);
  210 
  211         /* TODO interrupt handler */
  212 }
  213 
  214 static int
  215 diu_set_pxclk(device_t dev, unsigned int freq)
  216 {
  217         unsigned long bus_freq;
  218         uint32_t pxclk_set;
  219         uint32_t clkdvd;
  220 
  221         if ((bus_freq = mpc85xx_get_platform_clock()) <= 0) {
  222                 device_printf(dev, "Unable to get bus frequency\n");
  223                 return (ENXIO);
  224         }
  225 
  226         /* freq is in kHz */
  227         freq *= 1000;
  228         /* adding freq/2 to round-to-closest */
  229         pxclk_set = min(max((bus_freq + freq/2) / freq, 2), 255) << 16;
  230         pxclk_set |= OCP85XX_CLKDVDR_PXCKEN;
  231         clkdvd = ccsr_read4(OCP85XX_CLKDVDR);
  232         clkdvd &= ~(OCP85XX_CLKDVDR_PXCKEN | OCP85XX_CLKDVDR_PXCKINV |
  233                 OCP85XX_CLKDVDR_PXCLK_MASK);
  234         ccsr_write4(OCP85XX_CLKDVDR, clkdvd);
  235         ccsr_write4(OCP85XX_CLKDVDR, clkdvd | pxclk_set);
  236 
  237         return (0);
  238 }
  239 
  240 static int
  241 diu_init(struct diu_softc *sc)
  242 {
  243         struct panel_info *panel;
  244         int reg;
  245 
  246         panel = &sc->sc_panel;
  247 
  248         /* Temporarily disable the DIU while configuring */
  249         reg = bus_read_4(sc->res[0], DIU_DIU_MODE);
  250         reg &= ~(DIU_MODE_M << DIU_MODE_S);
  251         bus_write_4(sc->res[0], DIU_DIU_MODE, reg);
  252 
  253         if (diu_set_pxclk(sc->sc_dev, panel->panel_freq) < 0) {
  254                 return (ENXIO);
  255         }
  256 
  257         /* Configure DIU */
  258         /* Need to set these somehow later... */
  259         bus_write_4(sc->res[0], DIU_GAMMA, vtophys(sc->sc_gamma));
  260         bus_write_4(sc->res[0], DIU_CURSOR, vtophys(sc->sc_cursor));
  261         bus_write_4(sc->res[0], DIU_CURS_POS, 0);
  262 
  263         reg = ((sc->sc_info.fb_height) << DELTA_Y_S);
  264         reg |= sc->sc_info.fb_width;
  265         bus_write_4(sc->res[0], DIU_DISP_SIZE, reg);
  266 
  267         reg = (panel->panel_hbp << BP_H_SHIFT);
  268         reg |= (panel->panel_hpw << PW_H_SHIFT);
  269         reg |= (panel->panel_hfp << FP_H_SHIFT);
  270         bus_write_4(sc->res[0], DIU_HSYN_PARA, reg);
  271 
  272         reg = (panel->panel_vbp << BP_V_SHIFT);
  273         reg |= (panel->panel_vpw << PW_V_SHIFT);
  274         reg |= (panel->panel_vfp << FP_V_SHIFT);
  275         bus_write_4(sc->res[0], DIU_VSYN_PARA, reg);
  276 
  277         bus_write_4(sc->res[0], DIU_BGND, 0);
  278 
  279         /* Mask all the interrupts */
  280         bus_write_4(sc->res[0], DIU_INT_MASK, 0x3f);
  281 
  282         /* Reset all layers */
  283         sc->sc_planes[0] = contigmalloc(sizeof(struct diu_area_descriptor),
  284                 M_DEVBUF, M_ZERO, 0, BUS_SPACE_MAXADDR_32BIT, 32, 0);
  285         bus_write_4(sc->res[0], DIU_DESC_1, vtophys(sc->sc_planes[0]));
  286         bus_write_4(sc->res[0], DIU_DESC_2, 0);
  287         bus_write_4(sc->res[0], DIU_DESC_3, 0);
  288 
  289         /* Setup first plane */
  290         /* Area descriptor fields are little endian, so byte swap. */
  291         /* Word 0: Pixel format */
  292         /* Set to 8:8:8:8 ARGB, 4 bytes per pixel, no flip. */
  293 #define MAKE_PXLFMT(as,rs,gs,bs,a,r,g,b,f,s)    \
  294                 htole32((as << (4 * a)) | (rs << 4 * r) | \
  295                     (gs << 4 * g) | (bs << 4 * b) | \
  296                     (f << 28) | (s << 16) | \
  297                     (a << 25) | (r << 19) | \
  298                     (g << 21) | (b << 24))
  299         reg = MAKE_PXLFMT(8, 8, 8, 8, 3, 2, 1, 0, 1, 3);
  300         sc->sc_planes[0]->pixel_format = reg;
  301         /* Word 1: Bitmap address */
  302         sc->sc_planes[0]->bitmap_address = htole32(sc->sc_info.fb_pbase);
  303         /* Word 2: Source size/global alpha */
  304         reg = (sc->sc_info.fb_width | (sc->sc_info.fb_height << 12));
  305         sc->sc_planes[0]->source_size = htole32(reg);
  306         /* Word 3: AOI Size */
  307         reg = (sc->sc_info.fb_width | (sc->sc_info.fb_height << 16));
  308         sc->sc_planes[0]->aoi_size = htole32(reg);
  309         /* Word 4: AOI Offset */
  310         sc->sc_planes[0]->aoi_offset = 0;
  311         /* Word 5: Display offset */
  312         sc->sc_planes[0]->display_offset = 0;
  313         /* Word 6: Chroma key max */
  314         sc->sc_planes[0]->chroma_key_max = 0;
  315         /* Word 7: Chroma key min */
  316         reg = 255 << 16 | 255 << 8 | 255;
  317         sc->sc_planes[0]->chroma_key_min = htole32(reg);
  318         /* Word 8: Next AD */
  319         sc->sc_planes[0]->next_ad_addr = 0;
  320 
  321         /* TODO: derive this from the panel size */
  322         bus_write_4(sc->res[0], DIU_PLUT, 0x1f5f666);
  323 
  324         /* Enable DIU in normal mode */
  325         reg = bus_read_4(sc->res[0], DIU_DIU_MODE);
  326         reg &= ~(DIU_MODE_M << DIU_MODE_S);
  327         reg |= (DIU_MODE_NORMAL << DIU_MODE_S);
  328         bus_write_4(sc->res[0], DIU_DIU_MODE, reg);
  329 
  330         return (0);
  331 }
  332 
  333 static int
  334 diu_attach(device_t dev)
  335 {
  336         struct edid_info edid;
  337         struct diu_softc *sc;
  338         const struct videomode *videomode;
  339         void *edid_cells;
  340         const char *vm_name;
  341         phandle_t node;
  342         int h, r, w;
  343         int err, i;
  344 
  345         sc = device_get_softc(dev);
  346         sc->sc_dev = dev;
  347 
  348         if (bus_alloc_resources(dev, diu_spec, sc->res)) {
  349                 device_printf(dev, "could not allocate resources\n");
  350                 return (ENXIO);
  351         }
  352 
  353         node = ofw_bus_get_node(dev);
  354         /* Setup interrupt handler */
  355         err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_BIO | INTR_MPSAFE,
  356             NULL, diu_intr, sc, &sc->ih);
  357         if (err) {
  358                 device_printf(dev, "Unable to alloc interrupt resource.\n");
  359                 return (ENXIO);
  360         }
  361 
  362         /* TODO: Eventually, allow EDID to be dynamically provided. */
  363         if (OF_getprop_alloc(node, "edid", &edid_cells) <= 0) {
  364                 /* Get a resource hint: hint.fb.N.mode */
  365                 if (resource_string_value(device_get_name(dev),
  366                     device_get_unit(dev), "mode", &vm_name) != 0) {
  367                         device_printf(dev,
  368                             "No EDID data and no video-mode env set\n");
  369                         return (ENXIO);
  370                 }
  371         }
  372         if (edid_cells != NULL) {
  373                 if (edid_parse(edid_cells, &edid) != 0) {
  374                         device_printf(dev, "Error parsing EDID\n");
  375                         OF_prop_free(edid_cells);
  376                         return (ENXIO);
  377                 }
  378                 videomode = edid.edid_preferred_mode;
  379         } else {
  380                 /* Parse video-mode kenv variable. */
  381                 if ((err = sscanf(vm_name, "%dx%d@%d", &w, &h, &r)) != 3) {
  382                         device_printf(dev,
  383                             "Cannot parse video mode: %s\n", vm_name);
  384                         return (ENXIO);
  385                 }
  386                 videomode = pick_mode_by_ref(w, h, r);
  387                 if (videomode == NULL) {
  388                         device_printf(dev,
  389                             "Cannot find mode for %dx%d@%d", w, h, r);
  390                         return (ENXIO);
  391                 }
  392         }
  393 
  394         sc->sc_panel.panel_width = videomode->hdisplay;
  395         sc->sc_panel.panel_height = videomode->vdisplay;
  396         sc->sc_panel.panel_hbp = videomode->hsync_start - videomode->hdisplay;
  397         sc->sc_panel.panel_hfp = videomode->htotal - videomode->hsync_end;
  398         sc->sc_panel.panel_hpw = videomode->hsync_end - videomode->hsync_start;
  399         sc->sc_panel.panel_vbp = videomode->vsync_start - videomode->vdisplay;
  400         sc->sc_panel.panel_vfp = videomode->vtotal - videomode->vsync_end;
  401         sc->sc_panel.panel_vpw = videomode->vsync_end - videomode->vsync_start;
  402         sc->sc_panel.panel_freq = videomode->dot_clock;
  403 
  404         sc->sc_info.fb_width = sc->sc_panel.panel_width;
  405         sc->sc_info.fb_height = sc->sc_panel.panel_height;
  406         sc->sc_info.fb_stride = sc->sc_info.fb_width * 4;
  407         sc->sc_info.fb_bpp = sc->sc_info.fb_depth = 32;
  408         sc->sc_info.fb_size = sc->sc_info.fb_height * sc->sc_info.fb_stride;
  409         sc->sc_info.fb_vbase = (intptr_t)contigmalloc(sc->sc_info.fb_size,
  410             M_DEVBUF, M_ZERO, 0, BUS_SPACE_MAXADDR_32BIT, PAGE_SIZE, 0);
  411         sc->sc_info.fb_pbase = (intptr_t)vtophys(sc->sc_info.fb_vbase);
  412         sc->sc_info.fb_flags = FB_FLAG_MEMATTR;
  413         sc->sc_info.fb_memattr = VM_MEMATTR_DEFAULT;
  414 
  415         /* Gamma table is 3 consecutive segments of 256 bytes. */
  416         sc->sc_gamma = contigmalloc(3 * 256, M_DEVBUF, 0, 0,
  417             BUS_SPACE_MAXADDR_32BIT, PAGE_SIZE, 0);
  418         /* Initialize gamma to default */
  419         for (i = 0; i < 3 * 256; i++)
  420                 sc->sc_gamma[i] = (i % 256);
  421 
  422         /* Cursor format is 32x32x16bpp */
  423         sc->sc_cursor = contigmalloc(32 * 32 * 2, M_DEVBUF, M_ZERO, 0,
  424             BUS_SPACE_MAXADDR_32BIT, PAGE_SIZE, 0);
  425 
  426         diu_init(sc);
  427 
  428         sc->sc_info.fb_name = device_get_nameunit(dev);
  429 
  430         /* Ask newbus to attach framebuffer device to me. */
  431         sc->sc_fbd = device_add_child(dev, "fbd", device_get_unit(dev));
  432         if (sc->sc_fbd == NULL)
  433                 device_printf(dev, "Can't attach fbd device\n");
  434 
  435         if ((err = device_probe_and_attach(sc->sc_fbd)) != 0) {
  436                 device_printf(dev, "Failed to attach fbd device: %d\n", err);
  437         }
  438 
  439         return (0);
  440 }
  441 
  442 static struct fb_info *
  443 diu_fb_getinfo(device_t dev)
  444 {
  445         struct diu_softc *sc = device_get_softc(dev);
  446 
  447         return (&sc->sc_info);
  448 }
  449 
  450 static device_method_t diu_methods[] = {
  451         DEVMETHOD(device_probe,         diu_probe),
  452         DEVMETHOD(device_attach,        diu_attach),
  453 
  454         /* Framebuffer service methods */
  455         DEVMETHOD(fb_getinfo,           diu_fb_getinfo),
  456         { 0, 0 }
  457 };
  458 
  459 static driver_t diu_driver = {
  460         "fb",
  461         diu_methods,
  462         sizeof(struct diu_softc),
  463 };
  464 
  465 DRIVER_MODULE(fb, simplebus, diu_driver, 0, 0);

Cache object: 7a6c6587a9ecd006f8032a236cedd8a0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.