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 driver_t ipu3_fb_driver = {
  428         "fb",
  429         ipu3_fb_methods,
  430         sizeof(struct ipu3sc_softc),
  431 };
  432 
  433 DRIVER_MODULE(ipu3fb, simplebus, ipu3_fb_driver, 0, 0);
  434 
  435 /*
  436  * Video driver routines and glue.
  437  */
  438 static int                      ipu3fb_configure(int);
  439 static vi_probe_t               ipu3fb_probe;
  440 static vi_init_t                ipu3fb_init;
  441 static vi_get_info_t            ipu3fb_get_info;
  442 static vi_query_mode_t          ipu3fb_query_mode;
  443 static vi_set_mode_t            ipu3fb_set_mode;
  444 static vi_save_font_t           ipu3fb_save_font;
  445 static vi_load_font_t           ipu3fb_load_font;
  446 static vi_show_font_t           ipu3fb_show_font;
  447 static vi_save_palette_t        ipu3fb_save_palette;
  448 static vi_load_palette_t        ipu3fb_load_palette;
  449 static vi_set_border_t          ipu3fb_set_border;
  450 static vi_save_state_t          ipu3fb_save_state;
  451 static vi_load_state_t          ipu3fb_load_state;
  452 static vi_set_win_org_t         ipu3fb_set_win_org;
  453 static vi_read_hw_cursor_t      ipu3fb_read_hw_cursor;
  454 static vi_set_hw_cursor_t       ipu3fb_set_hw_cursor;
  455 static vi_set_hw_cursor_shape_t ipu3fb_set_hw_cursor_shape;
  456 static vi_blank_display_t       ipu3fb_blank_display;
  457 static vi_mmap_t                ipu3fb_mmap;
  458 static vi_ioctl_t               ipu3fb_ioctl;
  459 static vi_clear_t               ipu3fb_clear;
  460 static vi_fill_rect_t           ipu3fb_fill_rect;
  461 static vi_bitblt_t              ipu3fb_bitblt;
  462 static vi_diag_t                ipu3fb_diag;
  463 static vi_save_cursor_palette_t ipu3fb_save_cursor_palette;
  464 static vi_load_cursor_palette_t ipu3fb_load_cursor_palette;
  465 static vi_copy_t                ipu3fb_copy;
  466 static vi_putp_t                ipu3fb_putp;
  467 static vi_putc_t                ipu3fb_putc;
  468 static vi_puts_t                ipu3fb_puts;
  469 static vi_putm_t                ipu3fb_putm;
  470 
  471 static video_switch_t ipu3fbvidsw = {
  472         .probe                  = ipu3fb_probe,
  473         .init                   = ipu3fb_init,
  474         .get_info               = ipu3fb_get_info,
  475         .query_mode             = ipu3fb_query_mode,
  476         .set_mode               = ipu3fb_set_mode,
  477         .save_font              = ipu3fb_save_font,
  478         .load_font              = ipu3fb_load_font,
  479         .show_font              = ipu3fb_show_font,
  480         .save_palette           = ipu3fb_save_palette,
  481         .load_palette           = ipu3fb_load_palette,
  482         .set_border             = ipu3fb_set_border,
  483         .save_state             = ipu3fb_save_state,
  484         .load_state             = ipu3fb_load_state,
  485         .set_win_org            = ipu3fb_set_win_org,
  486         .read_hw_cursor         = ipu3fb_read_hw_cursor,
  487         .set_hw_cursor          = ipu3fb_set_hw_cursor,
  488         .set_hw_cursor_shape    = ipu3fb_set_hw_cursor_shape,
  489         .blank_display          = ipu3fb_blank_display,
  490         .mmap                   = ipu3fb_mmap,
  491         .ioctl                  = ipu3fb_ioctl,
  492         .clear                  = ipu3fb_clear,
  493         .fill_rect              = ipu3fb_fill_rect,
  494         .bitblt                 = ipu3fb_bitblt,
  495         .diag                   = ipu3fb_diag,
  496         .save_cursor_palette    = ipu3fb_save_cursor_palette,
  497         .load_cursor_palette    = ipu3fb_load_cursor_palette,
  498         .copy                   = ipu3fb_copy,
  499         .putp                   = ipu3fb_putp,
  500         .putc                   = ipu3fb_putc,
  501         .puts                   = ipu3fb_puts,
  502         .putm                   = ipu3fb_putm,
  503 };
  504 
  505 VIDEO_DRIVER(ipu3fb, ipu3fbvidsw, ipu3fb_configure);
  506 
  507 extern sc_rndr_sw_t txtrndrsw;
  508 RENDERER(ipu3fb, 0, txtrndrsw, gfb_set);
  509 RENDERER_MODULE(ipu3fb, gfb_set);
  510 
  511 static uint16_t ipu3fb_static_window[ROW*COL];
  512 extern u_char dflt_font_16[];
  513 
  514 static int
  515 ipu3fb_configure(int flags)
  516 {
  517         struct video_adapter_softc *sc;
  518 
  519         sc = &va_softc;
  520 
  521         if (sc->initialized)
  522                 return 0;
  523 
  524         sc->width = 640;
  525         sc->height = 480;
  526         sc->bpp = 2;
  527         sc->stride = sc->width * sc->bpp;
  528 
  529         ipu3fb_init(0, &sc->va, 0);
  530 
  531         sc->initialized = 1;
  532 
  533         return (0);
  534 }
  535 
  536 static int
  537 ipu3fb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
  538 {
  539 
  540         return (0);
  541 }
  542 
  543 static int
  544 ipu3fb_init(int unit, video_adapter_t *adp, int flags)
  545 {
  546         struct video_adapter_softc *sc;
  547         video_info_t *vi;
  548 
  549         sc = (struct video_adapter_softc *)adp;
  550         vi = &adp->va_info;
  551 
  552         vid_init_struct(adp, "ipu3fb", -1, unit);
  553 
  554         sc->font = dflt_font_16;
  555         vi->vi_cheight = IPU3FB_FONT_HEIGHT;
  556         vi->vi_cwidth = 8;
  557         vi->vi_width = sc->width/8;
  558         vi->vi_height = sc->height/vi->vi_cheight;
  559 
  560         /*
  561          * Clamp width/height to syscons maximums
  562          */
  563         if (vi->vi_width > COL)
  564                 vi->vi_width = COL;
  565         if (vi->vi_height > ROW)
  566                 vi->vi_height = ROW;
  567 
  568         sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
  569         sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
  570 
  571         adp->va_window = (vm_offset_t) ipu3fb_static_window;
  572         adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
  573         adp->va_line_width = sc->stride;
  574         adp->va_buffer_size = sc->fb_size;
  575 
  576         vid_register(&sc->va);
  577 
  578         return (0);
  579 }
  580 
  581 static int
  582 ipu3fb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
  583 {
  584 
  585         bcopy(&adp->va_info, info, sizeof(*info));
  586         return (0);
  587 }
  588 
  589 static int
  590 ipu3fb_query_mode(video_adapter_t *adp, video_info_t *info)
  591 {
  592 
  593         return (0);
  594 }
  595 
  596 static int
  597 ipu3fb_set_mode(video_adapter_t *adp, int mode)
  598 {
  599 
  600         return (0);
  601 }
  602 
  603 static int
  604 ipu3fb_save_font(video_adapter_t *adp, int page, int size, int width,
  605     u_char *data, int c, int count)
  606 {
  607 
  608         return (0);
  609 }
  610 
  611 static int
  612 ipu3fb_load_font(video_adapter_t *adp, int page, int size, int width,
  613     u_char *data, int c, int count)
  614 {
  615         struct video_adapter_softc *sc;
  616 
  617         sc = (struct video_adapter_softc *)adp;
  618         sc->font = data;
  619 
  620         return (0);
  621 }
  622 
  623 static int
  624 ipu3fb_show_font(video_adapter_t *adp, int page)
  625 {
  626 
  627         return (0);
  628 }
  629 
  630 static int
  631 ipu3fb_save_palette(video_adapter_t *adp, u_char *palette)
  632 {
  633 
  634         return (0);
  635 }
  636 
  637 static int
  638 ipu3fb_load_palette(video_adapter_t *adp, u_char *palette)
  639 {
  640 
  641         return (0);
  642 }
  643 
  644 static int
  645 ipu3fb_set_border(video_adapter_t *adp, int border)
  646 {
  647 
  648         return (ipu3fb_blank_display(adp, border));
  649 }
  650 
  651 static int
  652 ipu3fb_save_state(video_adapter_t *adp, void *p, size_t size)
  653 {
  654 
  655         return (0);
  656 }
  657 
  658 static int
  659 ipu3fb_load_state(video_adapter_t *adp, void *p)
  660 {
  661 
  662         return (0);
  663 }
  664 
  665 static int
  666 ipu3fb_set_win_org(video_adapter_t *adp, off_t offset)
  667 {
  668 
  669         return (0);
  670 }
  671 
  672 static int
  673 ipu3fb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
  674 {
  675 
  676         *col = *row = 0;
  677         return (0);
  678 }
  679 
  680 static int
  681 ipu3fb_set_hw_cursor(video_adapter_t *adp, int col, int row)
  682 {
  683 
  684         return (0);
  685 }
  686 
  687 static int
  688 ipu3fb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
  689     int celsize, int blink)
  690 {
  691 
  692         return (0);
  693 }
  694 
  695 static int
  696 ipu3fb_blank_display(video_adapter_t *adp, int mode)
  697 {
  698 
  699         return (0);
  700 }
  701 
  702 static int
  703 ipu3fb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
  704     int prot, vm_memattr_t *memattr)
  705 {
  706         struct video_adapter_softc *sc;
  707 
  708         sc = (struct video_adapter_softc *)adp;
  709 
  710         /*
  711          * This might be a legacy VGA mem request: if so, just point it at the
  712          * framebuffer, since it shouldn't be touched
  713          */
  714         if (offset < sc->stride * sc->height) {
  715                 *paddr = sc->fb_paddr + offset;
  716                 return (0);
  717         }
  718 
  719         return (EINVAL);
  720 }
  721 
  722 static int
  723 ipu3fb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
  724 {
  725         struct video_adapter_softc *sc;
  726         struct fbtype *fb;
  727 
  728         sc = (struct video_adapter_softc *)adp;
  729 
  730         switch (cmd) {
  731         case FBIOGTYPE:
  732                 fb = (struct fbtype *)data;
  733                 fb->fb_type = FBTYPE_PCIMISC;
  734                 fb->fb_height = sc->height;
  735                 fb->fb_width = sc->width;
  736                 fb->fb_depth = sc->depth;
  737                 if (sc->depth <= 1 || sc->depth > 8)
  738                         fb->fb_cmsize = 0;
  739                 else
  740                         fb->fb_cmsize = 1 << sc->depth;
  741                 fb->fb_size = sc->fb_size;
  742                 break;
  743         default:
  744                 return (fb_commonioctl(adp, cmd, data));
  745         }
  746 
  747         return (0);
  748 }
  749 
  750 static int
  751 ipu3fb_clear(video_adapter_t *adp)
  752 {
  753 
  754         return (ipu3fb_blank_display(adp, 0));
  755 }
  756 
  757 static int
  758 ipu3fb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
  759 {
  760 
  761         return (0);
  762 }
  763 
  764 static int
  765 ipu3fb_bitblt(video_adapter_t *adp, ...)
  766 {
  767 
  768         return (0);
  769 }
  770 
  771 static int
  772 ipu3fb_diag(video_adapter_t *adp, int level)
  773 {
  774 
  775         return (0);
  776 }
  777 
  778 static int
  779 ipu3fb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
  780 {
  781 
  782         return (0);
  783 }
  784 
  785 static int
  786 ipu3fb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
  787 {
  788 
  789         return (0);
  790 }
  791 
  792 static int
  793 ipu3fb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
  794 {
  795 
  796         return (0);
  797 }
  798 
  799 static int
  800 ipu3fb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
  801     int size, int bpp, int bit_ltor, int byte_ltor)
  802 {
  803 
  804         return (0);
  805 }
  806 
  807 static int
  808 ipu3fb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
  809 {
  810         struct video_adapter_softc *sc;
  811         int col, row, bpp;
  812         int b, i, j, k;
  813         uint8_t *addr;
  814         u_char *p;
  815         uint32_t fg, bg, color;
  816 
  817         sc = (struct video_adapter_softc *)adp;
  818         bpp = sc->bpp;
  819 
  820         if (sc->fb_addr == 0)
  821                 return (0);
  822         row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
  823         col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
  824         p = sc->font + c * IPU3FB_FONT_HEIGHT;
  825         addr = (uint8_t *)sc->fb_addr
  826             + (row + sc->ymargin) * (sc->stride)
  827             + bpp * (col + sc->xmargin);
  828 
  829         if (bpp == 2) {
  830                 bg = colors[(a >> 4) & 0x0f];
  831                 fg = colors[a & 0x0f];
  832         } else if (bpp == 3) {
  833                 bg = colors_24[(a >> 4) & 0x0f];
  834                 fg = colors_24[a & 0x0f];
  835         } else {
  836                 return (ENXIO);
  837         }
  838 
  839         for (i = 0; i < IPU3FB_FONT_HEIGHT; i++) {
  840                 for (j = 0, k = 7; j < 8; j++, k--) {
  841                         if ((p[i] & (1 << k)) == 0)
  842                                 color = bg;
  843                         else
  844                                 color = fg;
  845                         /* FIXME: BPP maybe different */
  846                         for (b = 0; b < bpp; b ++)
  847                                 addr[bpp * j + b] =
  848                                     (color >> (b << 3)) & 0xff;
  849                 }
  850 
  851                 addr += (sc->stride);
  852         }
  853 
  854         return (0);
  855 }
  856 
  857 static int
  858 ipu3fb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
  859 {
  860         int i;
  861 
  862         for (i = 0; i < len; i++) 
  863                 ipu3fb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
  864 
  865         return (0);
  866 }
  867 
  868 static int
  869 ipu3fb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
  870     uint32_t pixel_mask, int size, int width)
  871 {
  872 
  873         return (0);
  874 }

Cache object: 0be934bee872b23df68ef947e2770e84


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