svn commit: r310308 - in head/sys/mips: conf ingenic
Jared McNeill
jmcneill at FreeBSD.org
Tue Dec 20 01:51:11 UTC 2016
Author: jmcneill
Date: Tue Dec 20 01:51:09 2016
New Revision: 310308
URL: https://svnweb.freebsd.org/changeset/base/310308
Log:
Add support for Ingenic JZ4780 LCD controller and enable framebuffer
console support.
Reviewed by: kan
Differential Revision: https://reviews.freebsd.org/D8827
Added:
head/sys/mips/ingenic/jz4780_lcd.c (contents, props changed)
head/sys/mips/ingenic/jz4780_lcd.h (contents, props changed)
Modified:
head/sys/mips/conf/JZ4780
head/sys/mips/ingenic/files.jz4780
Modified: head/sys/mips/conf/JZ4780
==============================================================================
--- head/sys/mips/conf/JZ4780 Tue Dec 20 01:37:00 2016 (r310307)
+++ head/sys/mips/conf/JZ4780 Tue Dec 20 01:51:09 2016 (r310308)
@@ -86,6 +86,16 @@ device mmcsd
device dme
+device iic
+device iicbus
+
+# Framebuffer console support
+device vt
+device kbdmux
+device hdmi
+device videomode
+device pty
+
# USB support
options USB_DEBUG # enable debug msgs
options USB_HOST_ALIGN=128 # L2 cache line size
@@ -95,6 +105,7 @@ device dwcotg # DesignWare HS OTG cont
device usb # USB Bus (required)
#device udbp # USB Double Bulk Pipe devices
device uhid # "Human Interface Devices"
+device ukbd # Allow keyboard like HIDs to control console
#device ulpt # Printer
device umass # Disks/Mass storage - Requires scbus and da
device ums # Mouse
Modified: head/sys/mips/ingenic/files.jz4780
==============================================================================
--- head/sys/mips/ingenic/files.jz4780 Tue Dec 20 01:37:00 2016 (r310307)
+++ head/sys/mips/ingenic/files.jz4780 Tue Dec 20 01:51:09 2016 (r310308)
@@ -6,6 +6,9 @@ mips/ingenic/jz4780_mmc.c optional mmc
mips/ingenic/jz4780_ohci.c optional ohci
mips/ingenic/jz4780_smb.c optional iicbus
mips/ingenic/jz4780_uart.c optional uart
+mips/ingenic/jz4780_lcd.c optional vt
+dev/hdmi/dwc_hdmi.c optional hdmi iicbus
+dev/hdmi/dwc_hdmi_fdt.c optional hdmi iicbus
mips/ingenic/jz4780_clock.c standard
mips/ingenic/jz4780_clk_gen.c standard
@@ -25,3 +28,6 @@ mips/ingenic/jz4780_mpboot.S optional sm
# Custom interface between pinctrl and gpio
mips/ingenic/jz4780_gpio_if.m standard
+
+# HDMI interface
+dev/hdmi/hdmi_if.m standard
Added: head/sys/mips/ingenic/jz4780_lcd.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/mips/ingenic/jz4780_lcd.c Tue Dec 20 01:51:09 2016 (r310308)
@@ -0,0 +1,572 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill at invisible.ca>
+ * All rights reserved.
+ *
+ * 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 THE AUTHOR ``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 THE AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Ingenic JZ4780 LCD Controller
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/condvar.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/fbio.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/videomode/videomode.h>
+#include <dev/videomode/edidvar.h>
+
+#include <dev/extres/clk/clk.h>
+
+#include <mips/ingenic/jz4780_lcd.h>
+
+#include "fb_if.h"
+#include "hdmi_if.h"
+
+#define FB_DEFAULT_W 800
+#define FB_DEFAULT_H 600
+#define FB_DEFAULT_REF 60
+#define FB_BPP 32
+#define FB_ALIGN (16 * 4)
+#define FB_MAX_BW (1920 * 1080 * 60)
+#define FB_MAX_W 2048
+#define FB_MAX_H 2048
+#define FB_DIVIDE(x, y) (((x) + ((y) / 2)) / (y))
+
+#define PCFG_MAGIC 0xc7ff2100
+
+#define DOT_CLOCK_TO_HZ(c) ((c) * 1000)
+
+#ifndef VM_MEMATTR_WRITE_COMBINING
+#define VM_MEMATTR_WRITE_COMBINING VM_MEMATTR_UNCACHEABLE
+#endif
+
+struct jzlcd_softc {
+ device_t dev;
+ device_t fbdev;
+ struct resource *res[1];
+
+ /* Clocks */
+ clk_t clk;
+ clk_t clk_pix;
+
+ /* Framebuffer */
+ struct fb_info info;
+ size_t fbsize;
+ bus_addr_t paddr;
+ vm_offset_t vaddr;
+
+ /* HDMI */
+ eventhandler_tag hdmi_evh;
+
+ /* Frame descriptor DMA */
+ bus_dma_tag_t fdesc_tag;
+ bus_dmamap_t fdesc_map;
+ bus_addr_t fdesc_paddr;
+ struct lcd_frame_descriptor *fdesc;
+};
+
+static struct resource_spec jzlcd_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+#define LCD_READ(sc, reg) bus_read_4((sc)->res[0], (reg))
+#define LCD_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
+
+static int
+jzlcd_allocfb(struct jzlcd_softc *sc)
+{
+ sc->vaddr = kmem_alloc_contig(kernel_arena, sc->fbsize,
+ M_NOWAIT | M_ZERO, 0, ~0, FB_ALIGN, 0, VM_MEMATTR_WRITE_COMBINING);
+ if (sc->vaddr == 0) {
+ device_printf(sc->dev, "failed to allocate FB memory\n");
+ return (ENOMEM);
+ }
+ sc->paddr = pmap_kextract(sc->vaddr);
+
+ return (0);
+}
+
+static void
+jzlcd_freefb(struct jzlcd_softc *sc)
+{
+ kmem_free(kernel_arena, sc->vaddr, sc->fbsize);
+}
+
+static void
+jzlcd_start(struct jzlcd_softc *sc)
+{
+ uint32_t ctrl;
+
+ /* Clear status registers */
+ LCD_WRITE(sc, LCDSTATE, 0);
+ LCD_WRITE(sc, LCDOSDS, 0);
+ /* Enable the controller */
+ ctrl = LCD_READ(sc, LCDCTRL);
+ ctrl |= LCDCTRL_ENA;
+ ctrl &= ~LCDCTRL_DIS;
+ LCD_WRITE(sc, LCDCTRL, ctrl);
+}
+
+static void
+jzlcd_stop(struct jzlcd_softc *sc)
+{
+ uint32_t ctrl;
+
+ ctrl = LCD_READ(sc, LCDCTRL);
+ if ((ctrl & LCDCTRL_ENA) != 0) {
+ /* Disable the controller and wait for it to stop */
+ ctrl |= LCDCTRL_DIS;
+ LCD_WRITE(sc, LCDCTRL, ctrl);
+ while ((LCD_READ(sc, LCDSTATE) & LCDSTATE_LDD) == 0)
+ DELAY(100);
+ }
+ /* Clear all status except for disable */
+ LCD_WRITE(sc, LCDSTATE, LCD_READ(sc, LCDSTATE) & ~LCDSTATE_LDD);
+}
+
+static void
+jzlcd_setup_descriptor(struct jzlcd_softc *sc, const struct videomode *mode,
+ u_int desno)
+{
+ struct lcd_frame_descriptor *fdesc;
+ int line_sz;
+
+ /* Frame size is specified in # words */
+ line_sz = (mode->hdisplay * FB_BPP) >> 3;
+ line_sz = ((line_sz + 3) & ~3) / 4;
+
+ fdesc = sc->fdesc + desno;
+
+ if (desno == 0)
+ fdesc->next = sc->fdesc_paddr +
+ sizeof(struct lcd_frame_descriptor);
+ else
+ fdesc->next = sc->fdesc_paddr;
+ fdesc->physaddr = sc->paddr;
+ fdesc->id = desno;
+ fdesc->cmd = LCDCMD_FRM_EN | (line_sz * mode->vdisplay);
+ fdesc->offs = 0;
+ fdesc->pw = 0;
+ fdesc->cnum_pos = LCDPOS_BPP01_18_24 |
+ LCDPOS_PREMULTI01 |
+ (desno == 0 ? LCDPOS_COEF_BLE01_1 : LCDPOS_COEF_SLE01);
+ fdesc->dessize = LCDDESSIZE_ALPHA |
+ ((mode->vdisplay - 1) << LCDDESSIZE_HEIGHT_SHIFT) |
+ ((mode->hdisplay - 1) << LCDDESSIZE_WIDTH_SHIFT);
+}
+
+static int
+jzlcd_set_videomode(struct jzlcd_softc *sc, const struct videomode *mode)
+{
+ u_int hbp, hfp, hsw, vbp, vfp, vsw;
+ u_int hds, hde, ht, vds, vde, vt;
+ uint32_t ctrl;
+ int error;
+
+ hbp = mode->htotal - mode->hsync_end;
+ hfp = mode->hsync_start - mode->hdisplay;
+ hsw = mode->hsync_end - mode->hsync_start;
+ vbp = mode->vtotal - mode->vsync_end;
+ vfp = mode->vsync_start - mode->vdisplay;
+ vsw = mode->vsync_end - mode->vsync_start;
+
+ hds = hsw + hbp;
+ hde = hds + mode->hdisplay;
+ ht = hde + hfp;
+
+ vds = vsw + vbp;
+ vde = vds + mode->vdisplay;
+ vt = vde + vfp;
+
+ /* Setup timings */
+ LCD_WRITE(sc, LCDVAT,
+ (ht << LCDVAT_HT_SHIFT) | (vt << LCDVAT_VT_SHIFT));
+ LCD_WRITE(sc, LCDDAH,
+ (hds << LCDDAH_HDS_SHIFT) | (hde << LCDDAH_HDE_SHIFT));
+ LCD_WRITE(sc, LCDDAV,
+ (vds << LCDDAV_VDS_SHIFT) | (vde << LCDDAV_VDE_SHIFT));
+ LCD_WRITE(sc, LCDHSYNC, hsw);
+ LCD_WRITE(sc, LCDVSYNC, vsw);
+
+ /* Set configuration */
+ LCD_WRITE(sc, LCDCFG, LCDCFG_NEWDES | LCDCFG_RECOVER | LCDCFG_24 |
+ LCDCFG_PSM | LCDCFG_CLSM | LCDCFG_SPLM | LCDCFG_REVM | LCDCFG_PCP);
+ ctrl = LCD_READ(sc, LCDCTRL);
+ ctrl &= ~LCDCTRL_BST;
+ ctrl |= LCDCTRL_BST_64 | LCDCTRL_OFUM;
+ LCD_WRITE(sc, LCDCTRL, ctrl);
+ LCD_WRITE(sc, LCDPCFG, PCFG_MAGIC);
+ LCD_WRITE(sc, LCDRGBC, LCDRGBC_RGBFMT);
+
+ /* Update registers */
+ LCD_WRITE(sc, LCDSTATE, 0);
+
+ /* Setup frame descriptors */
+ jzlcd_setup_descriptor(sc, mode, 0);
+ jzlcd_setup_descriptor(sc, mode, 1);
+ bus_dmamap_sync(sc->fdesc_tag, sc->fdesc_map, BUS_DMASYNC_PREWRITE);
+
+ /* Setup DMA channels */
+ LCD_WRITE(sc, LCDDA0, sc->fdesc_paddr
+ + sizeof(struct lcd_frame_descriptor));
+ LCD_WRITE(sc, LCDDA1, sc->fdesc_paddr);
+
+ /* Set display clock */
+ error = clk_set_freq(sc->clk_pix, DOT_CLOCK_TO_HZ(mode->dot_clock), 0);
+ if (error != 0) {
+ device_printf(sc->dev, "failed to set pixel clock to %u Hz\n",
+ DOT_CLOCK_TO_HZ(mode->dot_clock));
+ return (error);
+ }
+
+ return (0);
+}
+
+static int
+jzlcd_configure(struct jzlcd_softc *sc, const struct videomode *mode)
+{
+ size_t fbsize;
+ int error;
+
+ fbsize = round_page(mode->hdisplay * mode->vdisplay * (FB_BPP / NBBY));
+
+ /* Detach the old FB device */
+ if (sc->fbdev != NULL) {
+ device_delete_child(sc->dev, sc->fbdev);
+ sc->fbdev = NULL;
+ }
+
+ /* If the FB size has changed, free the old FB memory */
+ if (sc->fbsize > 0 && sc->fbsize != fbsize) {
+ jzlcd_freefb(sc);
+ sc->vaddr = 0;
+ }
+
+ /* Allocate the FB if necessary */
+ sc->fbsize = fbsize;
+ if (sc->vaddr == 0) {
+ error = jzlcd_allocfb(sc);
+ if (error != 0) {
+ device_printf(sc->dev, "failed to allocate FB memory\n");
+ return (ENXIO);
+ }
+ }
+
+ /* Setup video mode */
+ error = jzlcd_set_videomode(sc, mode);
+ if (error != 0)
+ return (error);
+
+ /* Attach framebuffer device */
+ sc->info.fb_name = device_get_nameunit(sc->dev);
+ sc->info.fb_vbase = (intptr_t)sc->vaddr;
+ sc->info.fb_pbase = sc->paddr;
+ sc->info.fb_size = sc->fbsize;
+ sc->info.fb_bpp = sc->info.fb_depth = FB_BPP;
+ sc->info.fb_stride = mode->hdisplay * (FB_BPP / NBBY);
+ sc->info.fb_width = mode->hdisplay;
+ sc->info.fb_height = mode->vdisplay;
+
+ sc->fbdev = device_add_child(sc->dev, "fbd", device_get_unit(sc->dev));
+ if (sc->fbdev == NULL) {
+ device_printf(sc->dev, "failed to add fbd child\n");
+ return (ENOENT);
+ }
+
+ error = device_probe_and_attach(sc->fbdev);
+ if (error != 0) {
+ device_printf(sc->dev, "failed to attach fbd device\n");
+ return (error);
+ }
+
+ return (0);
+}
+
+static int
+jzlcd_get_bandwidth(const struct videomode *mode)
+{
+ int refresh;
+
+ refresh = FB_DIVIDE(FB_DIVIDE(DOT_CLOCK_TO_HZ(mode->dot_clock),
+ mode->htotal), mode->vtotal);
+
+ return mode->hdisplay * mode->vdisplay * refresh;
+}
+
+static int
+jzlcd_mode_supported(const struct videomode *mode)
+{
+ /* Width and height must be less than 2048 */
+ if (mode->hdisplay > FB_MAX_W || mode->vdisplay > FB_MAX_H)
+ return (0);
+
+ /* Bandwidth check */
+ if (jzlcd_get_bandwidth(mode) > FB_MAX_BW)
+ return (0);
+
+ /* Interlace modes not yet supported by the driver */
+ if ((mode->flags & VID_INTERLACE) != 0)
+ return (0);
+
+ return (1);
+}
+
+static const struct videomode *
+jzlcd_find_mode(struct edid_info *ei)
+{
+ const struct videomode *best;
+ int n, bw, best_bw;
+
+ /* If the preferred mode is OK, just use it */
+ if (jzlcd_mode_supported(ei->edid_preferred_mode) != 0)
+ return ei->edid_preferred_mode;
+
+ /* Pick the mode with the highest bandwidth requirements */
+ best = NULL;
+ best_bw = 0;
+ for (n = 0; n < ei->edid_nmodes; n++) {
+ if (jzlcd_mode_supported(&ei->edid_modes[n]) == 0)
+ continue;
+ bw = jzlcd_get_bandwidth(&ei->edid_modes[n]);
+ if (bw > FB_MAX_BW)
+ continue;
+ if (best == NULL || bw > best_bw) {
+ best = &ei->edid_modes[n];
+ best_bw = bw;
+ }
+ }
+
+ return best;
+}
+
+static void
+jzlcd_hdmi_event(void *arg, device_t hdmi_dev)
+{
+ const struct videomode *mode;
+ struct videomode hdmi_mode;
+ struct jzlcd_softc *sc;
+ struct edid_info ei;
+ uint8_t *edid;
+ uint32_t edid_len;
+ int error;
+
+ sc = arg;
+ edid = NULL;
+ edid_len = 0;
+ mode = NULL;
+
+ error = HDMI_GET_EDID(hdmi_dev, &edid, &edid_len);
+ if (error != 0) {
+ device_printf(sc->dev, "failed to get EDID: %d\n", error);
+ } else {
+ error = edid_parse(edid, &ei);
+ if (error != 0) {
+ device_printf(sc->dev, "failed to parse EDID: %d\n",
+ error);
+ } else {
+ if (bootverbose)
+ edid_print(&ei);
+
+ mode = jzlcd_find_mode(&ei);
+ }
+ }
+
+ /* If a suitable mode could not be found, try the default */
+ if (mode == NULL)
+ mode = pick_mode_by_ref(FB_DEFAULT_W, FB_DEFAULT_H,
+ FB_DEFAULT_REF);
+
+ if (mode == NULL) {
+ device_printf(sc->dev, "failed to find usable video mode\n");
+ return;
+ }
+
+ if (bootverbose)
+ device_printf(sc->dev, "using %dx%d\n",
+ mode->hdisplay, mode->vdisplay);
+
+ /* Stop the controller */
+ jzlcd_stop(sc);
+
+ /* Configure LCD controller */
+ error = jzlcd_configure(sc, mode);
+ if (error != 0) {
+ device_printf(sc->dev, "failed to configure FB: %d\n", error);
+ return;
+ }
+
+ /* Enable HDMI TX */
+ hdmi_mode = *mode;
+ HDMI_SET_VIDEOMODE(hdmi_dev, &hdmi_mode);
+
+ /* Start the controller! */
+ jzlcd_start(sc);
+}
+
+static void
+jzlcd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ if (error != 0)
+ return;
+ *(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static int
+jzlcd_probe(device_t dev)
+{
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-lcd"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Ingenic JZ4780 LCD Controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+jzlcd_attach(device_t dev)
+{
+ struct jzlcd_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, jzlcd_spec, sc->res)) {
+ device_printf(dev, "cannot allocate resources for device\n");
+ goto failed;
+ }
+
+ if (clk_get_by_ofw_name(dev, 0, "lcd_clk", &sc->clk) != 0 ||
+ clk_get_by_ofw_name(dev, 0, "lcd_pixclk", &sc->clk_pix) != 0) {
+ device_printf(dev, "cannot get clocks\n");
+ goto failed;
+ }
+ if (clk_enable(sc->clk) != 0 || clk_enable(sc->clk_pix) != 0) {
+ device_printf(dev, "cannot enable clocks\n");
+ goto failed;
+ }
+
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev),
+ sizeof(struct lcd_frame_descriptor), 0,
+ BUS_SPACE_MAXADDR_32BIT,
+ BUS_SPACE_MAXADDR,
+ NULL, NULL,
+ sizeof(struct lcd_frame_descriptor) * 2, 1,
+ sizeof(struct lcd_frame_descriptor) * 2,
+ 0,
+ NULL, NULL,
+ &sc->fdesc_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create bus dma tag\n");
+ goto failed;
+ }
+
+ error = bus_dmamem_alloc(sc->fdesc_tag, (void **)&sc->fdesc,
+ BUS_DMA_NOCACHE | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->fdesc_map);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate dma descriptor\n");
+ goto dmaalloc_failed;
+ }
+
+ error = bus_dmamap_load(sc->fdesc_tag, sc->fdesc_map, sc->fdesc,
+ sizeof(struct lcd_frame_descriptor) * 2, jzlcd_dmamap_cb,
+ &sc->fdesc_paddr, 0);
+ if (error != 0) {
+ device_printf(dev, "cannot load dma map\n");
+ goto dmaload_failed;
+ }
+
+ sc->hdmi_evh = EVENTHANDLER_REGISTER(hdmi_event,
+ jzlcd_hdmi_event, sc, 0);
+
+ return (0);
+
+dmaload_failed:
+ bus_dmamem_free(sc->fdesc_tag, sc->fdesc, sc->fdesc_map);
+dmaalloc_failed:
+ bus_dma_tag_destroy(sc->fdesc_tag);
+failed:
+ if (sc->clk_pix != NULL)
+ clk_release(sc->clk);
+ if (sc->clk != NULL)
+ clk_release(sc->clk);
+ if (sc->res != NULL)
+ bus_release_resources(dev, jzlcd_spec, sc->res);
+
+ return (ENXIO);
+}
+
+static struct fb_info *
+jzlcd_fb_getinfo(device_t dev)
+{
+ struct jzlcd_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ return (&sc->info);
+}
+
+static device_method_t jzlcd_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, jzlcd_probe),
+ DEVMETHOD(device_attach, jzlcd_attach),
+
+ /* FB interface */
+ DEVMETHOD(fb_getinfo, jzlcd_fb_getinfo),
+
+ DEVMETHOD_END
+};
+
+static driver_t jzlcd_driver = {
+ "fb",
+ jzlcd_methods,
+ sizeof(struct jzlcd_softc),
+};
+
+static devclass_t jzlcd_devclass;
+
+DRIVER_MODULE(fb, simplebus, jzlcd_driver, jzlcd_devclass, 0, 0);
Added: head/sys/mips/ingenic/jz4780_lcd.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/mips/ingenic/jz4780_lcd.h Tue Dec 20 01:51:09 2016 (r310308)
@@ -0,0 +1,204 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill at invisible.ca>
+ * All rights reserved.
+ *
+ * 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 THE AUTHOR ``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 THE AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Ingenic JZ4780 LCD Controller
+ */
+
+#ifndef __JZ4780_LCD_H__
+#define __JZ4780_LCD_H__
+
+#define LCDCFG 0x0000
+#define LCDCFG_LCDPIN (1 << 31)
+#define LCDCFG_TVEPEH (1 << 30)
+#define LCDCFG_NEWDES (1 << 28)
+#define LCDCFG_PALBP (1 << 27)
+#define LCDCFG_TVEN (1 << 26)
+#define LCDCFG_RECOVER (1 << 25)
+#define LCDCFG_PSM (1 << 23)
+#define LCDCFG_CLSM (1 << 22)
+#define LCDCFG_SPLM (1 << 21)
+#define LCDCFG_REVM (1 << 20)
+#define LCDCFG_HSYNM (1 << 19)
+#define LCDCFG_VSYNM (1 << 18)
+#define LCDCFG_INVDAT (1 << 17)
+#define LCDCFG_SYNDIR (1 << 16)
+#define LCDCFG_PSP (1 << 15)
+#define LCDCFG_CLSP (1 << 14)
+#define LCDCFG_SPLP (1 << 13)
+#define LCDCFG_REVP (1 << 12)
+#define LCDCFG_HSP (1 << 11)
+#define LCDCFG_PCP (1 << 10)
+#define LCDCFG_DEP (1 << 9)
+#define LCDCFG_VSP (1 << 8)
+#define LCDCFG_18_16 (1 << 7)
+#define LCDCFG_24 (1 << 6)
+#define LCDCFG_MODE (0xf << 0)
+#define LCDCTRL 0x0030
+#define LCDCTRL_PINMD (1 << 31)
+#define LCDCTRL_BST (0x7 << 28)
+#define LCDCTRL_BST_4 (0 << 28)
+#define LCDCTRL_BST_8 (1 << 28)
+#define LCDCTRL_BST_16 (2 << 28)
+#define LCDCTRL_BST_32 (3 << 28)
+#define LCDCTRL_BST_64 (4 << 28)
+#define LCDCTRL_OUTRGB (1 << 27)
+#define LCDCTRL_OFUP (1 << 26)
+#define LCDCTRL_DACTE (1 << 14)
+#define LCDCTRL_EOFM (1 << 13)
+#define LCDCTRL_SOFM (1 << 12)
+#define LCDCTRL_OFUM (1 << 11)
+#define LCDCTRL_IFUM0 (1 << 10)
+#define LCDCTRL_IFUM1 (1 << 9)
+#define LCDCTRL_LDDM (1 << 8)
+#define LCDCTRL_QDM (1 << 7)
+#define LCDCTRL_BEDN (1 << 6)
+#define LCDCTRL_PEDN (1 << 5)
+#define LCDCTRL_DIS (1 << 4)
+#define LCDCTRL_ENA (1 << 3)
+#define LCDCTRL_BPP0 (0x7 << 0)
+#define LCDCTRL_BPP0_1 (0 << 0)
+#define LCDCTRL_BPP0_2 (1 << 0)
+#define LCDCTRL_BPP0_4 (2 << 0)
+#define LCDCTRL_BPP0_8 (3 << 0)
+#define LCDCTRL_BPP0_15_16 (4 << 0)
+#define LCDCTRL_BPP0_18_24 (5 << 0)
+#define LCDCTRL_BPP0_24_COMP (6 << 0)
+#define LCDCTRL_BPP0_30 (7 << 0)
+#define LCDCTR
+#define LCDSTATE 0x0034
+#define LCDSTATE_QD (1 << 7)
+#define LCDSTATE_EOF (1 << 5)
+#define LCDSTATE_SOF (1 << 4)
+#define LCDSTATE_OUT (1 << 3)
+#define LCDSTATE_IFU0 (1 << 2)
+#define LCDSTATE_IFU1 (1 << 1)
+#define LCDSTATE_LDD (1 << 0)
+#define LCDOSDC 0x0100
+#define LCDOSDCTRL 0x0104
+#define LCDOSDS 0x0108
+#define LCDBGC0 0x010c
+#define LCDBGC1 0x02c4
+#define LCDKEY0 0x0110
+#define LCDKEY1 0x0114
+#define LCDALPHA 0x0118
+#define LCDIPUR 0x011c
+#define LCDRGBC 0x0090
+#define LCDRGBC_RGBDM (1 << 15)
+#define LCDRGBC_DMM (1 << 14)
+#define LCDRGBC_422 (1 << 8)
+#define LCDRGBC_RGBFMT (1 << 7)
+#define LCDRGBC_ODDRGB (0x7 << 4)
+#define LCDRGBC_EVENRGB (0x7 << 0)
+#define LCDVAT 0x000c
+#define LCDVAT_HT_SHIFT 16
+#define LCDVAT_VT_SHIFT 0
+#define LCDDAH 0x0010
+#define LCDDAH_HDS_SHIFT 16
+#define LCDDAH_HDE_SHIFT 0
+#define LCDDAV 0x0014
+#define LCDDAV_VDS_SHIFT 16
+#define LCDDAV_VDE_SHIFT 0
+#define LCDXYP0 0x0120
+#define LCDXYP1 0x0124
+#define LCDSIZE0 0x0128
+#define LCDSIZE1 0x012c
+#define LCDVSYNC 0x0004
+#define LCDHSYNC 0x0008
+#define LCDPS 0x0018
+#define LCDCLS 0x001c
+#define LCDSPL 0x0020
+#define LCDREV 0x0024
+#define LCDIID 0x0038
+#define LCDDA0 0x0040
+#define LCDSA0 0x0044
+#define LCDFID0 0x0048
+#define LCDCMD0 0x004c
+#define LCDCMD_SOFINT (1 << 31)
+#define LCDCMD_EOFINT (1 << 30)
+#define LCDCMD_CMD (1 << 29)
+#define LCDCMD_COMPE (1 << 27)
+#define LCDCMD_FRM_EN (1 << 26)
+#define LCDCMD_FIELD_SEL (1 << 25)
+#define LCDCMD_16X16BLOCK (1 << 24)
+#define LCDCMD_LEN (0xffffff << 0)
+#define LCDOFFS0 0x0060
+#define LCDPW0 0x0064
+#define LCDCNUM0 0x0068
+#define LCDPOS0 LCDCNUM0
+#define LCDPOS_ALPHAMD1 (1 << 31)
+#define LCDPOS_RGB01 (1 << 30)
+#define LCDPOS_BPP01 (0x7 << 27)
+#define LCDPOS_BPP01_15_16 (4 << 27)
+#define LCDPOS_BPP01_18_24 (5 << 27)
+#define LCDPOS_BPP01_24_COMP (6 << 27)
+#define LCDPOS_BPP01_30 (7 << 27)
+#define LCDPOS_PREMULTI01 (1 << 26)
+#define LCDPOS_COEF_SLE01 (0x3 << 24)
+#define LCDPOS_COEF_BLE01_1 (1 << 24)
+#define LCDPOS_YPOS01 (0xfff << 12)
+#define LCDPOS_XPOS01 (0xfff << 0)
+#define LCDDESSIZE0 0x006c
+#define LCDDESSIZE_ALPHA (0xff << 24)
+#define LCDDESSIZE_HEIGHT (0xfff << 12)
+#define LCDDESSIZE_HEIGHT_SHIFT 12
+#define LCDDESSIZE_WIDTH (0xfff << 0)
+#define LCDDESSIZE_WIDTH_SHIFT 0
+#define LCDDA1 0x0050
+#define LCDSA1 0x0054
+#define LCDFID1 0x0058
+#define LCDCMD1 0x005c
+#define LCDOFFS1 0x0070
+#define LCDPW1 0x0074
+#define LCDCNUM1 0x0078
+#define LCDPOS1 LCDCNUM1
+#define LCDDESSIZE1 0x007c
+#define LCDPCFG 0x02c0
+#define LCDDUALCTRL 0x02c8
+#define LCDENH_CFG 0x0400
+#define LCDENH_CSCCFG 0x0404
+#define LCDENH_LUMACFG 0x0408
+#define LCDENH_CHROCFG0 0x040c
+#define LCDENH_CHROCFG1 0x0410
+#define LCDENH_DITHERCFG 0x0414
+#define LCDENH_STATUS 0x0418
+#define LCDENH_GAMMA 0x0800 /* base */
+#define LCDENH_VEE 0x1000 /* base */
+
+struct lcd_frame_descriptor {
+ uint32_t next;
+ uint32_t physaddr;
+ uint32_t id;
+ uint32_t cmd;
+ uint32_t offs;
+ uint32_t pw;
+ uint32_t cnum_pos;
+ uint32_t dessize;
+} __packed;
+
+#endif /* !__JZ4780_LCD_H__ */
More information about the svn-src-all
mailing list