Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Support i.MX51's LCD framebuffer on Netwalker.



details:   https://anonhg.NetBSD.org/src/rev/9c221acdc28a
branches:  trunk
changeset: 778861:9c221acdc28a
user:      bsh <bsh%NetBSD.org@localhost>
date:      Tue Apr 17 10:19:57 2012 +0000

description:
Support i.MX51's LCD framebuffer on Netwalker.
from Kenichi Hashimoto.

diffstat:

 sys/arch/arm/imx/files.imx51              |    11 +-
 sys/arch/arm/imx/imx51_ipuv3.c            |  1288 +++++++++++++++++++++++++++++
 sys/arch/arm/imx/imx51_ipuv3reg.h         |   841 ++++++++++++++++++
 sys/arch/arm/imx/imx51_ipuv3var.h         |   137 +++
 sys/arch/evbarm/conf/NETWALKER            |    23 +-
 sys/arch/evbarm/conf/files.netwalker      |     9 +-
 sys/arch/evbarm/netwalker/netwalker_lcd.c |   268 ++++++
 sys/dev/wscons/wsconsio.h                 |     3 +-
 8 files changed, 2571 insertions(+), 9 deletions(-)

diffs (truncated from 2654 to 300 lines):

diff -r 104f264d24e8 -r 9c221acdc28a sys/arch/arm/imx/files.imx51
--- a/sys/arch/arm/imx/files.imx51      Tue Apr 17 10:16:57 2012 +0000
+++ b/sys/arch/arm/imx/files.imx51      Tue Apr 17 10:19:57 2012 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.imx51,v 1.3 2011/03/11 03:16:13 bsh Exp $
+#      $NetBSD: files.imx51,v 1.4 2012/04/17 10:19:57 bsh Exp $
 #
 # Configuration info for the Freescale i.MX51
 #
@@ -56,10 +56,11 @@
 attach imxiomux at axi
 file   arch/arm/imx/imx51_iomux.c              imxiomux
 
-# LCD controller
-# device       lcd : bus_dma_generic, wsemuldisplaydev, rasops16, rasops8, rasops4, rasops_rotation
-# file arch/arm/imx/imx31_lcd.c                lcd             needs-flag
-# defflag      opt_imx31_lcd.h                         IMXLCDCONSOLE
+# IPU v3 controller
+device ipu : bus_dma_generic, wsemuldisplaydev, rasops16, rasops8, rasops4, rasops_rotation, vcons
+file   arch/arm/imx/imx51_ipuv3.c      ipu      needs-flag
+defflag        opt_imx51_ipuv3.h               IMXIPUCONSOLE
+defparam opt_imx51_ipuv3.h             IPUV3_DEBUG
 
 # iMX M3IF - Multi Master Memory Interface
 # iMX ESDCTL/MDDRC - Enhanced SDRAM/LPDDR memory controller
diff -r 104f264d24e8 -r 9c221acdc28a sys/arch/arm/imx/imx51_ipuv3.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/imx/imx51_ipuv3.c    Tue Apr 17 10:19:57 2012 +0000
@@ -0,0 +1,1288 @@
+/*     $NetBSD: imx51_ipuv3.c,v 1.1 2012/04/17 10:19:57 bsh Exp $      */
+
+/*
+ * Copyright (c) 2011, 2012  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.c,v 1.1 2012/04/17 10:19:57 bsh Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>                        /* for cold */
+
+#include <uvm/uvm_extern.h>
+
+#include <dev/cons.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wscons_callbacks.h>
+#include <dev/rasops/rasops.h>
+#include <dev/wsfont/wsfont.h>
+#include <dev/wscons/wsdisplay_vconsvar.h>
+
+#include <sys/bus.h>
+#include <machine/cpu.h>
+#include <arm/cpufunc.h>
+
+#include <arm/imx/imx51var.h>
+#include <arm/imx/imx51reg.h>
+#include <arm/imx/imx51_ipuv3var.h>
+#include <arm/imx/imx51_ipuv3reg.h>
+#include <arm/imx/imx51_ccmvar.h>
+#include <arm/imx/imx51_ccmreg.h>
+
+#include "imxccm.h"    /* if CCM driver is configured into the kernel */
+#include "wsdisplay.h"
+#include "opt_imx51_ipuv3.h"
+
+/*
+ * Console variables. These are necessary since console is setup very early,
+ * before devices get attached.
+ */
+struct {
+       int                             is_console;
+} imx51_ipuv3_console;
+
+#define        IPUV3_READ(ipuv3, module, reg)                                        \
+       bus_space_read_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg))
+#define        IPUV3_WRITE(ipuv3, module, reg, val)                                  \
+       bus_space_write_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg), (val))
+
+#ifdef IPUV3_DEBUG
+int ipuv3_debug = IPUV3_DEBUG;
+#define        DPRINTFN(n,x)   if (ipuv3_debug>(n)) printf x; else
+#else
+#define        DPRINTFN(n,x)
+#endif
+
+int ipuv3intr(void *);
+
+static void imx51_ipuv3_initialize(struct imx51_ipuv3_softc *,
+    const struct lcd_panel_geometry *);
+#if NWSDISPLAY > 0
+static void imx51_ipuv3_setup_rasops(struct imx51_ipuv3_softc *,
+    struct rasops_info *, struct imx51_wsscreen_descr *,
+    const struct lcd_panel_geometry *);
+#endif
+static void imx51_ipuv3_set_idma_param(uint32_t *, uint32_t, uint32_t);
+
+#if NWSDISPLAY > 0
+/*
+ * wsdisplay glue
+ */
+static struct imx51_wsscreen_descr imx51_ipuv3_stdscreen = {
+       .c = {
+               .name         = "std",
+               .ncols        = 0,
+               .nrows        = 0,
+               .textops      = NULL,
+               .fontwidth    = 8,
+               .fontheight   = 16,
+               .capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
+               .modecookie   = NULL
+       },
+       .depth = 16,            /* bits per pixel */
+       .flags = RI_CENTER | RI_FULLCLEAR
+};
+
+static const struct wsscreen_descr *imx51_ipuv3_scr_descr[] = {
+       &imx51_ipuv3_stdscreen.c,
+};
+
+const struct wsscreen_list imx51_ipuv3_screen_list = {
+       sizeof imx51_ipuv3_scr_descr / sizeof imx51_ipuv3_scr_descr[0],
+       imx51_ipuv3_scr_descr
+};
+
+struct wsdisplay_accessops imx51_ipuv3_accessops = {
+       .ioctl        = imx51_ipuv3_ioctl,
+       .mmap         = imx51_ipuv3_mmap,
+       .alloc_screen = NULL,
+       .free_screen  = NULL,
+       .show_screen  = NULL,
+       .load_font    = NULL,
+       .pollc        = NULL,
+       .scroll       = NULL
+};
+#endif
+
+#ifdef IPUV3_DEBUG
+static void
+imx51_ipuv3_dump(struct imx51_ipuv3_softc *sc)
+{
+       int i;
+
+       DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
+
+#define        __DUMP(grp, reg)                                                \
+       DPRINTFN(4, ("%-16s = 0x%08X\n", #reg, IPUV3_READ(sc, grp, IPU_##reg)))
+
+       __DUMP(cm, CM_CONF);
+       __DUMP(cm, CM_DISP_GEN);
+       __DUMP(idmac, IDMAC_CONF);
+       __DUMP(idmac, IDMAC_CH_EN_1);
+       __DUMP(idmac, IDMAC_CH_EN_2);
+       __DUMP(idmac, IDMAC_CH_PRI_1);
+       __DUMP(idmac, IDMAC_CH_PRI_2);
+       __DUMP(idmac, IDMAC_BNDM_EN_1);
+       __DUMP(idmac, IDMAC_BNDM_EN_2);
+       __DUMP(cm, CM_CH_DB_MODE_SEL_0);
+       __DUMP(cm, CM_CH_DB_MODE_SEL_1);
+       __DUMP(dmfc, DMFC_WR_CHAN);
+       __DUMP(dmfc, DMFC_WR_CHAN_DEF);
+       __DUMP(dmfc, DMFC_DP_CHAN);
+       __DUMP(dmfc, DMFC_DP_CHAN_DEF);
+       __DUMP(dmfc, DMFC_IC_CTRL);
+       __DUMP(cm, CM_FS_PROC_FLOW1);
+       __DUMP(cm, CM_FS_PROC_FLOW2);
+       __DUMP(cm, CM_FS_PROC_FLOW3);
+       __DUMP(cm, CM_FS_DISP_FLOW1);
+       __DUMP(dc, DC_DISP_CONF1_0);
+       __DUMP(dc, DC_DISP_CONF2_0);
+       __DUMP(dc, DC_WR_CH_CONF_5);
+
+       printf("*** IPU ***\n");
+       for (i = 0; i <= 0x17c; i += 4)
+               DPRINTFN(6, ("0x%08X = 0x%08X\n", i, IPUV3_READ(sc, cm, i)));
+       printf("*** IDMAC ***\n");
+       for (i = 0; i <= 0x104; i += 4)
+               DPRINTFN(6, ("0x%08X = 0x%08X\n", i, IPUV3_READ(sc, idmac, i)));
+       printf("*** CPMEM ***\n");
+       for (i = 0x5c0; i <= 0x600; i += 4)
+               DPRINTFN(6, ("0x%08X = 0x%08X\n", i, IPUV3_READ(sc, cpmem, i)));
+
+#undef __DUMP
+
+}
+#endif
+
+static void
+imx51_ipuv3_enable_display(struct imx51_ipuv3_softc *sc)
+{
+       uint32_t reg = 0;
+
+       DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
+
+       /* enable sub modules */
+       reg = IPUV3_READ(sc, cm, IPU_CM_CONF);
+       reg |= CM_CONF_DP_EN |
+           CM_CONF_DC_EN |
+           CM_CONF_DMFC_EN |
+           CM_CONF_DI0_EN;
+       IPUV3_WRITE(sc, cm, IPU_CM_CONF, reg);
+}
+
+static void
+imx51_ipuv3_dmfc_init(struct imx51_ipuv3_softc *sc)
+{
+       DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
+
+       /* IC channel is disabled */
+       IPUV3_WRITE(sc, dmfc, IPU_DMFC_IC_CTRL,
+           IC_IN_PORT_DISABLE);
+
+       IPUV3_WRITE(sc, dmfc, IPU_DMFC_WR_CHAN, 0x00000000);
+       IPUV3_WRITE(sc, dmfc, IPU_DMFC_WR_CHAN_DEF, 0x20202020);
+       IPUV3_WRITE(sc, dmfc, IPU_DMFC_DP_CHAN, 0x00000094);
+       IPUV3_WRITE(sc, dmfc, IPU_DMFC_DP_CHAN_DEF, 0x202020F6);
+
+       IPUV3_WRITE(sc, dmfc, IPU_DMFC_GENERAL1,
+           DCDP_SYNC_PR_ROUNDROBIN);
+
+#ifdef IPUV3_DEBUG
+       int i;
+       printf("*** DMFC ***\n");
+       for (i = 0; i <= 0x34; i += 4)
+               printf("0x%08X = 0x%08X\n", i, IPUV3_READ(sc, dmfc, i));
+
+       printf("%s: DMFC_IC_CTRL         0x%08X\n", __func__,
+           IPUV3_READ(sc, dmfc, IPU_DMFC_IC_CTRL));
+       printf("%s: IPU_DMFC_WR_CHAN     0x%08X\n", __func__,
+           IPUV3_READ(sc, dmfc, IPU_DMFC_WR_CHAN));
+       printf("%s: IPU_DMFC_WR_CHAN_DEF 0x%08X\n", __func__,
+           IPUV3_READ(sc, dmfc, IPU_DMFC_WR_CHAN_DEF));
+       printf("%s: IPU_DMFC_GENERAL1    0x%08X\n", __func__,
+           IPUV3_READ(sc, dmfc, IPU_DMFC_GENERAL1));
+#endif
+}
+
+static void
+imx51_ipuv3_dc_map_clear(struct imx51_ipuv3_softc *sc, int map)
+{
+       DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
+
+       uint32_t reg;
+       uint32_t addr;
+
+       addr = IPU_DC_MAP_CONF_PNTR(map / 2);
+       reg = IPUV3_READ(sc, dc, addr);
+       reg &= ~(0xFFFF << (16 * (map & 0x1)));
+       IPUV3_WRITE(sc, dc, addr, reg);
+}
+
+static void
+imx51_ipuv3_dc_map_conf(struct imx51_ipuv3_softc *sc,
+    int map, int byte, int offset, uint8_t mask)
+{
+       DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
+
+       uint32_t reg;
+       uint32_t addr;
+
+       addr = IPU_DC_MAP_CONF_MASK((map * 3 + byte) / 2);
+       reg = IPUV3_READ(sc, dc, addr);
+       reg &= ~(0xFFFF << (16 * ((map * 3 + byte) & 0x1)));
+       reg |= ((offset << 8) | mask) << (16 * ((map * 3 + byte) & 0x1));
+       IPUV3_WRITE(sc, dc, addr, reg);
+#ifdef IPUV3_DEBUG
+       printf("%s: addr 0x%08X reg 0x%08X\n", __func__, addr, reg);
+#endif
+
+       addr = IPU_DC_MAP_CONF_PNTR(map / 2);
+       reg = IPUV3_READ(sc, dc, addr);
+       reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte)));
+       reg |= ((map * 3) + byte) << ((16 * (map & 0x1)) + (5 * byte));
+       IPUV3_WRITE(sc, dc, addr, reg);



Home | Main Index | Thread Index | Old Index