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/arm/freescale/imx/imx51_ipuv3.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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
    5  * Copyright (c) 2012, 2013 The FreeBSD Foundation
    6  * All rights reserved.
    7  *
    8  * Portions of this software were developed by Oleksandr Rybalko
    9  * under sponsorship from the FreeBSD Foundation.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  */
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/bio.h>
   39 #include <sys/bus.h>
   40 #include <sys/conf.h>
   41 #include <sys/endian.h>
   42 #include <sys/kernel.h>
   43 #include <sys/kthread.h>
   44 #include <sys/lock.h>
   45 #include <sys/malloc.h>
   46 #include <sys/module.h>
   47 #include <sys/mutex.h>
   48 #include <sys/queue.h>
   49 #include <sys/resource.h>
   50 #include <sys/rman.h>
   51 #include <sys/time.h>
   52 #include <sys/timetc.h>
   53 #include <sys/fbio.h>
   54 #include <sys/consio.h>
   55 
   56 #include <sys/kdb.h>
   57 
   58 #include <vm/vm.h>
   59 #include <vm/pmap.h>
   60 
   61 #include <machine/bus.h>
   62 #include <machine/fdt.h>
   63 #include <machine/resource.h>
   64 #include <machine/intr.h>
   65 
   66 #include <dev/ofw/ofw_bus.h>
   67 #include <dev/ofw/ofw_bus_subr.h>
   68 
   69 #include <dev/fb/fbreg.h>
   70 #include <dev/syscons/syscons.h>
   71 
   72 #include <arm/freescale/imx/imx51_ccmvar.h>
   73 
   74 #include <arm/freescale/imx/imx51_ipuv3reg.h>
   75 
   76 #define IMX51_IPU_HSP_CLOCK     665000000
   77 #define IPU3FB_FONT_HEIGHT      16
   78 
   79 struct ipu3sc_softc {
   80         device_t                dev;
   81         bus_addr_t              pbase;
   82         bus_addr_t              vbase;
   83 
   84         bus_space_tag_t         iot;
   85         bus_space_handle_t      ioh;
   86         bus_space_handle_t      cm_ioh;
   87         bus_space_handle_t      dp_ioh;
   88         bus_space_handle_t      di0_ioh;
   89         bus_space_handle_t      di1_ioh;
   90         bus_space_handle_t      dctmpl_ioh;
   91         bus_space_handle_t      dc_ioh;
   92         bus_space_handle_t      dmfc_ioh;
   93         bus_space_handle_t      idmac_ioh;
   94         bus_space_handle_t      cpmem_ioh;
   95 };
   96 
   97 struct video_adapter_softc {
   98         /* Videoadpater part */
   99         video_adapter_t va;
  100 
  101         intptr_t        fb_addr;
  102         intptr_t        fb_paddr;
  103         unsigned int    fb_size;
  104 
  105         int             bpp;
  106         int             depth;
  107         unsigned int    height;
  108         unsigned int    width;
  109         unsigned int    stride;
  110 
  111         unsigned int    xmargin;
  112         unsigned int    ymargin;
  113 
  114         unsigned char   *font;
  115         int             initialized;
  116 };
  117 
  118 static struct ipu3sc_softc *ipu3sc_softc;
  119 static struct video_adapter_softc va_softc;
  120 
  121 /* FIXME: not only 2 bytes color supported */
  122 static uint16_t colors[16] = {
  123         0x0000, /* black */
  124         0x001f, /* blue */
  125         0x07e0, /* green */
  126         0x07ff, /* cyan */
  127         0xf800, /* red */
  128         0xf81f, /* magenta */
  129         0x3800, /* brown */
  130         0xc618, /* light grey */
  131         0xc618, /* XXX: dark grey */
  132         0x001f, /* XXX: light blue */
  133         0x07e0, /* XXX: light green */
  134         0x07ff, /* XXX: light cyan */
  135         0xf800, /* XXX: light red */
  136         0xf81f, /* XXX: light magenta */
  137         0xffe0, /* yellow */
  138         0xffff, /* white */
  139 };
  140 static uint32_t colors_24[16] = {
  141         0x000000,/* Black       */
  142         0x000080,/* Blue        */
  143         0x008000,/* Green       */
  144         0x008080,/* Cyan        */
  145         0x800000,/* Red         */
  146         0x800080,/* Magenta     */
  147         0xcc6600,/* brown       */
  148         0xC0C0C0,/* Silver      */
  149         0x808080,/* Gray        */
  150         0x0000FF,/* Light Blue  */
  151         0x00FF00,/* Light Green */
  152         0x00FFFF,/* Light Cyan  */
  153         0xFF0000,/* Light Red   */
  154         0xFF00FF,/* Light Magenta */
  155         0xFFFF00,/* Yellow      */
  156         0xFFFFFF,/* White       */
  157 
  158 };
  159 
  160 #define IPUV3_READ(ipuv3, module, reg)                                  \
  161         bus_space_read_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg))
  162 #define IPUV3_WRITE(ipuv3, module, reg, val)                            \
  163         bus_space_write_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg), (val))
  164 
  165 #define CPMEM_CHANNEL_OFFSET(_c)        ((_c) * 0x40)
  166 #define CPMEM_WORD_OFFSET(_w)           ((_w) * 0x20)
  167 #define CPMEM_DP_OFFSET(_d)             ((_d) * 0x10000)
  168 #define IMX_IPU_DP0             0
  169 #define IMX_IPU_DP1             1
  170 #define CPMEM_CHANNEL(_dp, _ch, _w)                                     \
  171             (CPMEM_DP_OFFSET(_dp) + CPMEM_CHANNEL_OFFSET(_ch) +         \
  172                 CPMEM_WORD_OFFSET(_w))
  173 #define CPMEM_OFFSET(_dp, _ch, _w, _o)                                  \
  174             (CPMEM_CHANNEL((_dp), (_ch), (_w)) + (_o))
  175 
  176 #define IPUV3_DEBUG 100
  177 
  178 #ifdef IPUV3_DEBUG
  179 #define SUBMOD_DUMP_REG(_sc, _m, _l)                                    \
  180         {                                                               \
  181                 int i;                                                  \
  182                 printf("*** " #_m " ***\n");                            \
  183                 for (i = 0; i <= (_l); i += 4) {                        \
  184                         if ((i % 32) == 0)                              \
  185                                 printf("%04x: ", i & 0xffff);           \
  186                         printf("0x%08x%c", IPUV3_READ((_sc), _m, i),    \
  187                             ((i + 4) % 32)?' ':'\n');                   \
  188                 }                                                       \
  189                 printf("\n");                                           \
  190         }
  191 #endif
  192 
  193 #ifdef IPUV3_DEBUG
  194 int ipuv3_debug = IPUV3_DEBUG;
  195 #define DPRINTFN(n,x)   if (ipuv3_debug>(n)) printf x; else
  196 #else
  197 #define DPRINTFN(n,x)
  198 #endif
  199 
  200 static int      ipu3_fb_probe(device_t);
  201 static int      ipu3_fb_attach(device_t);
  202 
  203 static int
  204 ipu3_fb_malloc(struct ipu3sc_softc *sc, size_t size)
  205 {
  206 
  207         sc->vbase = (uint32_t)contigmalloc(size, M_DEVBUF, M_ZERO, 0, ~0,
  208             PAGE_SIZE, 0);
  209         sc->pbase = vtophys(sc->vbase);
  210 
  211         return (0);
  212 }
  213 
  214 static void
  215 ipu3_fb_init(void *arg)
  216 {
  217         struct ipu3sc_softc *sc = arg;
  218         struct video_adapter_softc *va_sc = &va_softc;
  219         uint64_t w0sh96;
  220         uint32_t w1sh96;
  221 
  222         /* FW W0[137:125] - 96 = [41:29] */
  223         /* FH W0[149:138] - 96 = [53:42] */
  224         w0sh96 = IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 0, 16));
  225         w0sh96 <<= 32;
  226         w0sh96 |= IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 0, 12));
  227 
  228         va_sc->width = ((w0sh96 >> 29) & 0x1fff) + 1;
  229         va_sc->height = ((w0sh96 >> 42) & 0x0fff) + 1;
  230 
  231         /* SLY W1[115:102] - 96 = [19:6] */
  232         w1sh96 = IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 12));
  233         va_sc->stride = ((w1sh96 >> 6) & 0x3fff) + 1;
  234 
  235         printf("%dx%d [%d]\n", va_sc->width, va_sc->height, va_sc->stride);
  236         va_sc->fb_size = va_sc->height * va_sc->stride;
  237 
  238         ipu3_fb_malloc(sc, va_sc->fb_size);
  239 
  240         /* DP1 + config_ch_23 + word_2 */
  241         IPUV3_WRITE(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 0),
  242             ((sc->pbase >> 3) | ((sc->pbase >> 3) << 29)) & 0xffffffff);
  243 
  244         IPUV3_WRITE(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 4),
  245             ((sc->pbase >> 3) >> 3) & 0xffffffff);
  246 
  247         va_sc->fb_addr = (intptr_t)sc->vbase;
  248         va_sc->fb_paddr = (intptr_t)sc->pbase;
  249         va_sc->bpp = va_sc->stride / va_sc->width;
  250         va_sc->depth = va_sc->bpp * 8;
  251 }
  252 
  253 static int
  254 ipu3_fb_probe(device_t dev)
  255 {
  256         int error;
  257 
  258         if (!ofw_bus_status_okay(dev))
  259                 return (ENXIO);
  260 
  261         if (!ofw_bus_is_compatible(dev, "fsl,ipu3"))
  262                 return (ENXIO);
  263 
  264         device_set_desc(dev, "i.MX5x Image Processing Unit v3 (FB)");
  265 
  266         error = sc_probe_unit(device_get_unit(dev), 
  267             device_get_flags(dev) | SC_AUTODETECT_KBD);
  268 
  269         if (error != 0)
  270                 return (error);
  271 
  272         return (BUS_PROBE_DEFAULT);
  273 }
  274 
  275 static int
  276 ipu3_fb_attach(device_t dev)
  277 {
  278         struct ipu3sc_softc *sc = device_get_softc(dev);
  279         bus_space_tag_t iot;
  280         bus_space_handle_t ioh;
  281         phandle_t node;
  282         pcell_t reg;
  283         int err;
  284         uintptr_t base;
  285 
  286         if (ipu3sc_softc)
  287                 return (ENXIO);
  288 
  289         ipu3sc_softc = sc;
  290 
  291         if (bootverbose)
  292                 device_printf(dev, "clock gate status is %d\n",
  293                     imx51_get_clk_gating(IMX51CLK_IPU_HSP_CLK_ROOT));
  294 
  295         sc->dev = dev;
  296 
  297         err = (sc_attach_unit(device_get_unit(dev),
  298             device_get_flags(dev) | SC_AUTODETECT_KBD));
  299 
  300         if (err) {
  301                 device_printf(dev, "failed to attach syscons\n");
  302                 goto fail;
  303         }
  304 
  305         sc = device_get_softc(dev);
  306         sc->iot = iot = fdtbus_bs_tag;
  307 
  308         /*
  309          * Retrieve the device address based on the start address in the
  310          * DTS.  The DTS for i.MX51 specifies 0x5e000000 as the first register
  311          * address, so we just subtract IPU_CM_BASE to get the offset at which
  312          * the IPU device was memory mapped.
  313          * On i.MX53, the offset is 0.
  314          */
  315         node = ofw_bus_get_node(dev);
  316         if ((OF_getencprop(node, "reg", &reg, sizeof(reg))) <= 0)
  317                 base = 0;
  318         else
  319                 base = reg - IPU_CM_BASE(0);
  320         /* map controller registers */
  321         err = bus_space_map(iot, IPU_CM_BASE(base), IPU_CM_SIZE, 0, &ioh);
  322         if (err)
  323                 goto fail_retarn_cm;
  324         sc->cm_ioh = ioh;
  325 
  326         /* map Display Multi FIFO Controller registers */
  327         err = bus_space_map(iot, IPU_DMFC_BASE(base), IPU_DMFC_SIZE, 0, &ioh);
  328         if (err)
  329                 goto fail_retarn_dmfc;
  330         sc->dmfc_ioh = ioh;
  331 
  332         /* map Display Interface 0 registers */
  333         err = bus_space_map(iot, IPU_DI0_BASE(base), IPU_DI0_SIZE, 0, &ioh);
  334         if (err)
  335                 goto fail_retarn_di0;
  336         sc->di0_ioh = ioh;
  337 
  338         /* map Display Interface 1 registers */
  339         err = bus_space_map(iot, IPU_DI1_BASE(base), IPU_DI0_SIZE, 0, &ioh);
  340         if (err)
  341                 goto fail_retarn_di1;
  342         sc->di1_ioh = ioh;
  343 
  344         /* map Display Processor registers */
  345         err = bus_space_map(iot, IPU_DP_BASE(base), IPU_DP_SIZE, 0, &ioh);
  346         if (err)
  347                 goto fail_retarn_dp;
  348         sc->dp_ioh = ioh;
  349 
  350         /* map Display Controller registers */
  351         err = bus_space_map(iot, IPU_DC_BASE(base), IPU_DC_SIZE, 0, &ioh);
  352         if (err)
  353                 goto fail_retarn_dc;
  354         sc->dc_ioh = ioh;
  355 
  356         /* map Image DMA Controller registers */
  357         err = bus_space_map(iot, IPU_IDMAC_BASE(base), IPU_IDMAC_SIZE, 0,
  358             &ioh);
  359         if (err)
  360                 goto fail_retarn_idmac;
  361         sc->idmac_ioh = ioh;
  362 
  363         /* map CPMEM registers */
  364         err = bus_space_map(iot, IPU_CPMEM_BASE(base), IPU_CPMEM_SIZE, 0,
  365             &ioh);
  366         if (err)
  367                 goto fail_retarn_cpmem;
  368         sc->cpmem_ioh = ioh;
  369 
  370         /* map DCTEMPL registers */
  371         err = bus_space_map(iot, IPU_DCTMPL_BASE(base), IPU_DCTMPL_SIZE, 0,
  372             &ioh);
  373         if (err)
  374                 goto fail_retarn_dctmpl;
  375         sc->dctmpl_ioh = ioh;
  376 
  377 #ifdef notyet
  378         sc->ih = imx51_ipuv3_intr_establish(IMX51_INT_IPUV3, IPL_BIO,
  379             ipuv3intr, sc);
  380         if (sc->ih == NULL) {
  381                 device_printf(sc->dev,
  382                     "unable to establish interrupt at irq %d\n",
  383                     IMX51_INT_IPUV3);
  384                 return (ENXIO);
  385         }
  386 #endif
  387 
  388         /*
  389          * We have to wait until interrupts are enabled. 
  390          * Mailbox relies on it to get data from VideoCore
  391          */
  392         ipu3_fb_init(sc);
  393 
  394         return (0);
  395 
  396 fail:
  397         return (ENXIO);
  398 fail_retarn_dctmpl:
  399         bus_space_unmap(sc->iot, sc->cpmem_ioh, IPU_CPMEM_SIZE);
  400 fail_retarn_cpmem:
  401         bus_space_unmap(sc->iot, sc->idmac_ioh, IPU_IDMAC_SIZE);
  402 fail_retarn_idmac:
  403         bus_space_unmap(sc->iot, sc->dc_ioh, IPU_DC_SIZE);
  404 fail_retarn_dp:
  405         bus_space_unmap(sc->iot, sc->dp_ioh, IPU_DP_SIZE);
  406 fail_retarn_dc:
  407         bus_space_unmap(sc->iot, sc->di1_ioh, IPU_DI1_SIZE);
  408 fail_retarn_di1:
  409         bus_space_unmap(sc->iot, sc->di0_ioh, IPU_DI0_SIZE);
  410 fail_retarn_di0:
  411         bus_space_unmap(sc->iot, sc->dmfc_ioh, IPU_DMFC_SIZE);
  412 fail_retarn_dmfc:
  413         bus_space_unmap(sc->iot, sc->dc_ioh, IPU_CM_SIZE);
  414 fail_retarn_cm:
  415         device_printf(sc->dev,
  416             "failed to map registers (errno=%d)\n", err);
  417         return (err);
  418 }
  419 
  420 static device_method_t ipu3_fb_methods[] = {
  421         /* Device interface */
  422         DEVMETHOD(device_probe,         ipu3_fb_probe),
  423         DEVMETHOD(device_attach,        ipu3_fb_attach),
  424         { 0, 0 }
  425 };
  426 
  427 static devclass_t ipu3_fb_devclass;
  428 
  429 static driver_t ipu3_fb_driver = {
  430         "fb",
  431         ipu3_fb_methods,
  432         sizeof(struct ipu3sc_softc),
  433 };
  434 
  435 DRIVER_MODULE(ipu3fb, simplebus, ipu3_fb_driver, ipu3_fb_devclass, 0, 0);
  436 
  437 /*
  438  * Video driver routines and glue.
  439  */
  440 static int                      ipu3fb_configure(int);
  441 static vi_probe_t               ipu3fb_probe;
  442 static vi_init_t                ipu3fb_init;
  443 static vi_get_info_t            ipu3fb_get_info;
  444 static vi_query_mode_t          ipu3fb_query_mode;
  445 static vi_set_mode_t            ipu3fb_set_mode;
  446 static vi_save_font_t           ipu3fb_save_font;
  447 static vi_load_font_t           ipu3fb_load_font;
  448 static vi_show_font_t           ipu3fb_show_font;
  449 static vi_save_palette_t        ipu3fb_save_palette;
  450 static vi_load_palette_t        ipu3fb_load_palette;
  451 static vi_set_border_t          ipu3fb_set_border;
  452 static vi_save_state_t          ipu3fb_save_state;
  453 static vi_load_state_t          ipu3fb_load_state;
  454 static vi_set_win_org_t         ipu3fb_set_win_org;
  455 static vi_read_hw_cursor_t      ipu3fb_read_hw_cursor;
  456 static vi_set_hw_cursor_t       ipu3fb_set_hw_cursor;
  457 static vi_set_hw_cursor_shape_t ipu3fb_set_hw_cursor_shape;
  458 static vi_blank_display_t       ipu3fb_blank_display;
  459 static vi_mmap_t                ipu3fb_mmap;
  460 static vi_ioctl_t               ipu3fb_ioctl;
  461 static vi_clear_t               ipu3fb_clear;
  462 static vi_fill_rect_t           ipu3fb_fill_rect;
  463 static vi_bitblt_t              ipu3fb_bitblt;
  464 static vi_diag_t                ipu3fb_diag;
  465 static vi_save_cursor_palette_t ipu3fb_save_cursor_palette;
  466 static vi_load_cursor_palette_t ipu3fb_load_cursor_palette;
  467 static vi_copy_t                ipu3fb_copy;
  468 static vi_putp_t                ipu3fb_putp;
  469 static vi_putc_t                ipu3fb_putc;
  470 static vi_puts_t                ipu3fb_puts;
  471 static vi_putm_t                ipu3fb_putm;
  472 
  473 static video_switch_t ipu3fbvidsw = {
  474         .probe                  = ipu3fb_probe,
  475         .init                   = ipu3fb_init,
  476         .get_info               = ipu3fb_get_info,
  477         .query_mode             = ipu3fb_query_mode,
  478         .set_mode               = ipu3fb_set_mode,
  479         .save_font              = ipu3fb_save_font,
  480         .load_font              = ipu3fb_load_font,
  481         .show_font              = ipu3fb_show_font,
  482         .save_palette           = ipu3fb_save_palette,
  483         .load_palette           = ipu3fb_load_palette,
  484         .set_border             = ipu3fb_set_border,
  485         .save_state             = ipu3fb_save_state,
  486         .load_state             = ipu3fb_load_state,
  487         .set_win_org            = ipu3fb_set_win_org,
  488         .read_hw_cursor         = ipu3fb_read_hw_cursor,
  489         .set_hw_cursor          = ipu3fb_set_hw_cursor,
  490         .set_hw_cursor_shape    = ipu3fb_set_hw_cursor_shape,
  491         .blank_display          = ipu3fb_blank_display,
  492         .mmap                   = ipu3fb_mmap,
  493         .ioctl                  = ipu3fb_ioctl,
  494         .clear                  = ipu3fb_clear,
  495         .fill_rect              = ipu3fb_fill_rect,
  496         .bitblt                 = ipu3fb_bitblt,
  497         .diag                   = ipu3fb_diag,
  498         .save_cursor_palette    = ipu3fb_save_cursor_palette,
  499         .load_cursor_palette    = ipu3fb_load_cursor_palette,
  500         .copy                   = ipu3fb_copy,
  501         .putp                   = ipu3fb_putp,
  502         .putc                   = ipu3fb_putc,
  503         .puts                   = ipu3fb_puts,
  504         .putm                   = ipu3fb_putm,
  505 };
  506 
  507 VIDEO_DRIVER(ipu3fb, ipu3fbvidsw, ipu3fb_configure);
  508 
  509 extern sc_rndr_sw_t txtrndrsw;
  510 RENDERER(ipu3fb, 0, txtrndrsw, gfb_set);
  511 RENDERER_MODULE(ipu3fb, gfb_set);
  512 
  513 static uint16_t ipu3fb_static_window[ROW*COL];
  514 extern u_char dflt_font_16[];
  515 
  516 static int
  517 ipu3fb_configure(int flags)
  518 {
  519         struct video_adapter_softc *sc;
  520 
  521         sc = &va_softc;
  522 
  523         if (sc->initialized)
  524                 return 0;
  525 
  526         sc->width = 640;
  527         sc->height = 480;
  528         sc->bpp = 2;
  529         sc->stride = sc->width * sc->bpp;
  530 
  531         ipu3fb_init(0, &sc->va, 0);
  532 
  533         sc->initialized = 1;
  534 
  535         return (0);
  536 }
  537 
  538 static int
  539 ipu3fb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
  540 {
  541 
  542         return (0);
  543 }
  544 
  545 static int
  546 ipu3fb_init(int unit, video_adapter_t *adp, int flags)
  547 {
  548         struct video_adapter_softc *sc;
  549         video_info_t *vi;
  550 
  551         sc = (struct video_adapter_softc *)adp;
  552         vi = &adp->va_info;
  553 
  554         vid_init_struct(adp, "ipu3fb", -1, unit);
  555 
  556         sc->font = dflt_font_16;
  557         vi->vi_cheight = IPU3FB_FONT_HEIGHT;
  558         vi->vi_cwidth = 8;
  559         vi->vi_width = sc->width/8;
  560         vi->vi_height = sc->height/vi->vi_cheight;
  561 
  562         /*
  563          * Clamp width/height to syscons maximums
  564          */
  565         if (vi->vi_width > COL)
  566                 vi->vi_width = COL;
  567         if (vi->vi_height > ROW)
  568                 vi->vi_height = ROW;
  569 
  570         sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
  571         sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
  572 
  573         adp->va_window = (vm_offset_t) ipu3fb_static_window;
  574         adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
  575         adp->va_line_width = sc->stride;
  576         adp->va_buffer_size = sc->fb_size;
  577 
  578         vid_register(&sc->va);
  579 
  580         return (0);
  581 }
  582 
  583 static int
  584 ipu3fb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
  585 {
  586 
  587         bcopy(&adp->va_info, info, sizeof(*info));
  588         return (0);
  589 }
  590 
  591 static int
  592 ipu3fb_query_mode(video_adapter_t *adp, video_info_t *info)
  593 {
  594 
  595         return (0);
  596 }
  597 
  598 static int
  599 ipu3fb_set_mode(video_adapter_t *adp, int mode)
  600 {
  601 
  602         return (0);
  603 }
  604 
  605 static int
  606 ipu3fb_save_font(video_adapter_t *adp, int page, int size, int width,
  607     u_char *data, int c, int count)
  608 {
  609 
  610         return (0);
  611 }
  612 
  613 static int
  614 ipu3fb_load_font(video_adapter_t *adp, int page, int size, int width,
  615     u_char *data, int c, int count)
  616 {
  617         struct video_adapter_softc *sc;
  618 
  619         sc = (struct video_adapter_softc *)adp;
  620         sc->font = data;
  621 
  622         return (0);
  623 }
  624 
  625 static int
  626 ipu3fb_show_font(video_adapter_t *adp, int page)
  627 {
  628 
  629         return (0);
  630 }
  631 
  632 static int
  633 ipu3fb_save_palette(video_adapter_t *adp, u_char *palette)
  634 {
  635 
  636         return (0);
  637 }
  638 
  639 static int
  640 ipu3fb_load_palette(video_adapter_t *adp, u_char *palette)
  641 {
  642 
  643         return (0);
  644 }
  645 
  646 static int
  647 ipu3fb_set_border(video_adapter_t *adp, int border)
  648 {
  649 
  650         return (ipu3fb_blank_display(adp, border));
  651 }
  652 
  653 static int
  654 ipu3fb_save_state(video_adapter_t *adp, void *p, size_t size)
  655 {
  656 
  657         return (0);
  658 }
  659 
  660 static int
  661 ipu3fb_load_state(video_adapter_t *adp, void *p)
  662 {
  663 
  664         return (0);
  665 }
  666 
  667 static int
  668 ipu3fb_set_win_org(video_adapter_t *adp, off_t offset)
  669 {
  670 
  671         return (0);
  672 }
  673 
  674 static int
  675 ipu3fb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
  676 {
  677 
  678         *col = *row = 0;
  679         return (0);
  680 }
  681 
  682 static int
  683 ipu3fb_set_hw_cursor(video_adapter_t *adp, int col, int row)
  684 {
  685 
  686         return (0);
  687 }
  688 
  689 static int
  690 ipu3fb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
  691     int celsize, int blink)
  692 {
  693 
  694         return (0);
  695 }
  696 
  697 static int
  698 ipu3fb_blank_display(video_adapter_t *adp, int mode)
  699 {
  700 
  701         return (0);
  702 }
  703 
  704 static int
  705 ipu3fb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
  706     int prot, vm_memattr_t *memattr)
  707 {
  708         struct video_adapter_softc *sc;
  709 
  710         sc = (struct video_adapter_softc *)adp;
  711 
  712         /*
  713          * This might be a legacy VGA mem request: if so, just point it at the
  714          * framebuffer, since it shouldn't be touched
  715          */
  716         if (offset < sc->stride * sc->height) {
  717                 *paddr = sc->fb_paddr + offset;
  718                 return (0);
  719         }
  720 
  721         return (EINVAL);
  722 }
  723 
  724 static int
  725 ipu3fb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
  726 {
  727         struct video_adapter_softc *sc;
  728         struct fbtype *fb;
  729 
  730         sc = (struct video_adapter_softc *)adp;
  731 
  732         switch (cmd) {
  733         case FBIOGTYPE:
  734                 fb = (struct fbtype *)data;
  735                 fb->fb_type = FBTYPE_PCIMISC;
  736                 fb->fb_height = sc->height;
  737                 fb->fb_width = sc->width;
  738                 fb->fb_depth = sc->depth;
  739                 if (sc->depth <= 1 || sc->depth > 8)
  740                         fb->fb_cmsize = 0;
  741                 else
  742                         fb->fb_cmsize = 1 << sc->depth;
  743                 fb->fb_size = sc->fb_size;
  744                 break;
  745         case FBIOSCURSOR:
  746                 return (ENODEV);
  747         default:
  748                 return (fb_commonioctl(adp, cmd, data));
  749         }
  750 
  751         return (0);
  752 }
  753 
  754 static int
  755 ipu3fb_clear(video_adapter_t *adp)
  756 {
  757 
  758         return (ipu3fb_blank_display(adp, 0));
  759 }
  760 
  761 static int
  762 ipu3fb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
  763 {
  764 
  765         return (0);
  766 }
  767 
  768 static int
  769 ipu3fb_bitblt(video_adapter_t *adp, ...)
  770 {
  771 
  772         return (0);
  773 }
  774 
  775 static int
  776 ipu3fb_diag(video_adapter_t *adp, int level)
  777 {
  778 
  779         return (0);
  780 }
  781 
  782 static int
  783 ipu3fb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
  784 {
  785 
  786         return (0);
  787 }
  788 
  789 static int
  790 ipu3fb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
  791 {
  792 
  793         return (0);
  794 }
  795 
  796 static int
  797 ipu3fb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
  798 {
  799 
  800         return (0);
  801 }
  802 
  803 static int
  804 ipu3fb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
  805     int size, int bpp, int bit_ltor, int byte_ltor)
  806 {
  807 
  808         return (0);
  809 }
  810 
  811 static int
  812 ipu3fb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
  813 {
  814         struct video_adapter_softc *sc;
  815         int col, row, bpp;
  816         int b, i, j, k;
  817         uint8_t *addr;
  818         u_char *p;
  819         uint32_t fg, bg, color;
  820 
  821         sc = (struct video_adapter_softc *)adp;
  822         bpp = sc->bpp;
  823 
  824         if (sc->fb_addr == 0)
  825                 return (0);
  826         row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
  827         col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
  828         p = sc->font + c * IPU3FB_FONT_HEIGHT;
  829         addr = (uint8_t *)sc->fb_addr
  830             + (row + sc->ymargin) * (sc->stride)
  831             + bpp * (col + sc->xmargin);
  832 
  833         if (bpp == 2) {
  834                 bg = colors[(a >> 4) & 0x0f];
  835                 fg = colors[a & 0x0f];
  836         } else if (bpp == 3) {
  837                 bg = colors_24[(a >> 4) & 0x0f];
  838                 fg = colors_24[a & 0x0f];
  839         } else {
  840                 return (ENXIO);
  841         }
  842 
  843         for (i = 0; i < IPU3FB_FONT_HEIGHT; i++) {
  844                 for (j = 0, k = 7; j < 8; j++, k--) {
  845                         if ((p[i] & (1 << k)) == 0)
  846                                 color = bg;
  847                         else
  848                                 color = fg;
  849                         /* FIXME: BPP maybe different */
  850                         for (b = 0; b < bpp; b ++)
  851                                 addr[bpp * j + b] =
  852                                     (color >> (b << 3)) & 0xff;
  853                 }
  854 
  855                 addr += (sc->stride);
  856         }
  857 
  858         return (0);
  859 }
  860 
  861 static int
  862 ipu3fb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
  863 {
  864         int i;
  865 
  866         for (i = 0; i < len; i++) 
  867                 ipu3fb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
  868 
  869         return (0);
  870 }
  871 
  872 static int
  873 ipu3fb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
  874     uint32_t pixel_mask, int size, int width)
  875 {
  876 
  877         return (0);
  878 }

Cache object: 9f1c5677d7c0ec43ff5f8d4d1d6c51f6


[ 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.